@juxtui/ui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/nuxt.js CHANGED
@@ -10,6 +10,7 @@ var components = [
10
10
  "JBadge",
11
11
  "JBanner",
12
12
  "JBreadcrumb",
13
+ "JBurger",
13
14
  "JButton",
14
15
  "JCard",
15
16
  "JCheckbox",
@@ -22,8 +23,12 @@ var components = [
22
23
  "JDropdownMenuSeparator",
23
24
  "JDropdownMenuSub",
24
25
  "JEmptyState",
26
+ "JFooter",
27
+ "JFooterColumn",
25
28
  "JInput",
26
29
  "JKbd",
30
+ "JNavbar",
31
+ "JNavbarLink",
27
32
  "JPagination",
28
33
  "JPopover",
29
34
  "JProgress",
@@ -33,6 +38,9 @@ var components = [
33
38
  "JSelect",
34
39
  "JSeparator",
35
40
  "JSheet",
41
+ "JSidebar",
42
+ "JSidebarGroup",
43
+ "JSidebarItem",
36
44
  "JSkeleton",
37
45
  "JSlider",
38
46
  "JSpinner",
package/dist/nuxt.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nuxt.js","names":[],"sources":["../src/nuxt.ts"],"sourcesContent":["import type { NuxtModule } from '@nuxt/schema'\r\nimport { addComponent, addImports, defineNuxtModule } from '@nuxt/kit'\r\n\r\nexport interface ModuleOptions {\r\n /** Inject Juxt's stylesheet (tokens + component styles). Defaults to true. */\r\n css?: boolean\r\n}\r\n\r\nconst components = [\r\n 'JAccordion',\r\n 'JAccordionItem',\r\n 'JAlert',\r\n 'JAspectRatio',\r\n 'JAvatar',\r\n 'JAvatarGroup',\r\n 'JBadge',\r\n 'JBanner',\r\n 'JBreadcrumb',\r\n 'JButton',\r\n 'JCard',\r\n 'JCheckbox',\r\n 'JCollapsible',\r\n 'JCommandPalette',\r\n 'JDialog',\r\n 'JDropdownMenu',\r\n 'JDropdownMenuItem',\r\n 'JDropdownMenuLabel',\r\n 'JDropdownMenuSeparator',\r\n 'JDropdownMenuSub',\r\n 'JEmptyState',\r\n 'JInput',\r\n 'JKbd',\r\n 'JPagination',\r\n 'JPopover',\r\n 'JProgress',\r\n 'JRadio',\r\n 'JRadioGroup',\r\n 'JRating',\r\n 'JSelect',\r\n 'JSeparator',\r\n 'JSheet',\r\n 'JSkeleton',\r\n 'JSlider',\r\n 'JSpinner',\r\n 'JStat',\r\n 'JSwitch',\r\n 'JTabs',\r\n 'JTag',\r\n 'JTextarea',\r\n 'JTimeline',\r\n 'JTimelineItem',\r\n 'JToaster',\r\n 'JToggleGroup',\r\n 'JToggleGroupItem',\r\n 'JTooltip',\r\n 'JVisuallyHidden',\r\n] as const\r\n\r\nconst composables = ['toast', 'useToast', 'useRecentCommands', 'useHotkey', 'formatHotkey'] as const\r\n\r\n/**\r\n * Nuxt module: auto-imports every Juxt component and composable, and adds the\r\n * stylesheet.\r\n *\r\n * export default defineNuxtConfig({ modules: ['@juxtui/ui/nuxt'] })\r\n */\r\nconst juxtModule: NuxtModule<ModuleOptions> = defineNuxtModule<ModuleOptions>({\r\n meta: {\r\n name: '@juxtui/ui',\r\n configKey: 'juxt',\r\n compatibility: { nuxt: '>=3.15.0' },\r\n },\r\n defaults: {\r\n css: true,\r\n },\r\n setup(options, nuxt) {\r\n for (const name of components) addComponent({ name, export: name, filePath: '@juxtui/ui' })\r\n addImports(composables.map(name => ({ name, from: '@juxtui/ui' })))\r\n if (options.css) nuxt.options.css.unshift('@juxtui/ui/style.css')\r\n nuxt.options.build.transpile.push('@juxtui/ui')\r\n },\r\n})\r\n\r\nexport default juxtModule\r\n"],"mappings":";;AAQA,IAAM,aAAa;CACjB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,cAAc;CAAC;CAAS;CAAY;CAAqB;CAAa;AAAc;;;;;;;AAQ1F,IAAM,aAAwC,iBAAgC;CAC5E,MAAM;EACJ,MAAM;EACN,WAAW;EACX,eAAe,EAAE,MAAM,WAAW;CACpC;CACA,UAAU,EACR,KAAK,KACP;CACA,MAAM,SAAS,MAAM;EACnB,KAAK,MAAM,QAAQ,YAAY,aAAa;GAAE;GAAM,QAAQ;GAAM,UAAU;EAAa,CAAC;EAC1F,WAAW,YAAY,KAAI,UAAS;GAAE;GAAM,MAAM;EAAa,EAAE,CAAC;EAClE,IAAI,QAAQ,KAAK,KAAK,QAAQ,IAAI,QAAQ,sBAAsB;EAChE,KAAK,QAAQ,MAAM,UAAU,KAAK,YAAY;CAChD;AACF,CAAC"}
1
+ {"version":3,"file":"nuxt.js","names":[],"sources":["../src/nuxt.ts"],"sourcesContent":["import type { NuxtModule } from '@nuxt/schema'\nimport { addComponent, addImports, defineNuxtModule } from '@nuxt/kit'\n\nexport interface ModuleOptions {\n /** Inject Juxt's stylesheet (tokens + component styles). Defaults to true. */\n css?: boolean\n}\n\nconst components = [\n 'JAccordion',\n 'JAccordionItem',\n 'JAlert',\n 'JAspectRatio',\n 'JAvatar',\n 'JAvatarGroup',\n 'JBadge',\n 'JBanner',\n 'JBreadcrumb',\n 'JBurger',\n 'JButton',\n 'JCard',\n 'JCheckbox',\n 'JCollapsible',\n 'JCommandPalette',\n 'JDialog',\n 'JDropdownMenu',\n 'JDropdownMenuItem',\n 'JDropdownMenuLabel',\n 'JDropdownMenuSeparator',\n 'JDropdownMenuSub',\n 'JEmptyState',\n 'JFooter',\n 'JFooterColumn',\n 'JInput',\n 'JKbd',\n 'JNavbar',\n 'JNavbarLink',\n 'JPagination',\n 'JPopover',\n 'JProgress',\n 'JRadio',\n 'JRadioGroup',\n 'JRating',\n 'JSelect',\n 'JSeparator',\n 'JSheet',\n 'JSidebar',\n 'JSidebarGroup',\n 'JSidebarItem',\n 'JSkeleton',\n 'JSlider',\n 'JSpinner',\n 'JStat',\n 'JSwitch',\n 'JTabs',\n 'JTag',\n 'JTextarea',\n 'JTimeline',\n 'JTimelineItem',\n 'JToaster',\n 'JToggleGroup',\n 'JToggleGroupItem',\n 'JTooltip',\n 'JVisuallyHidden',\n] as const\n\nconst composables = ['toast', 'useToast', 'useRecentCommands', 'useHotkey', 'formatHotkey'] as const\n\n/**\n * Nuxt module: auto-imports every Juxt component and composable, and adds the\n * stylesheet.\n *\n * export default defineNuxtConfig({ modules: ['@juxtui/ui/nuxt'] })\n */\nconst juxtModule: NuxtModule<ModuleOptions> = defineNuxtModule<ModuleOptions>({\n meta: {\n name: '@juxtui/ui',\n configKey: 'juxt',\n compatibility: { nuxt: '>=3.15.0' },\n },\n defaults: {\n css: true,\n },\n setup(options, nuxt) {\n for (const name of components) addComponent({ name, export: name, filePath: '@juxtui/ui' })\n addImports(composables.map(name => ({ name, from: '@juxtui/ui' })))\n if (options.css) nuxt.options.css.unshift('@juxtui/ui/style.css')\n nuxt.options.build.transpile.push('@juxtui/ui')\n },\n})\n\nexport default juxtModule\n"],"mappings":";;AAQA,IAAM,aAAa;CACjB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,cAAc;CAAC;CAAS;CAAY;CAAqB;CAAa;AAAc;;;;;;;AAQ1F,IAAM,aAAwC,iBAAgC;CAC5E,MAAM;EACJ,MAAM;EACN,WAAW;EACX,eAAe,EAAE,MAAM,WAAW;CACpC;CACA,UAAU,EACR,KAAK,KACP;CACA,MAAM,SAAS,MAAM;EACnB,KAAK,MAAM,QAAQ,YAAY,aAAa;GAAE;GAAM,QAAQ;GAAM,UAAU;EAAa,CAAC;EAC1F,WAAW,YAAY,KAAI,UAAS;GAAE;GAAM,MAAM;EAAa,EAAE,CAAC;EAClE,IAAI,QAAQ,KAAK,KAAK,QAAQ,IAAI,QAAQ,sBAAsB;EAChE,KAAK,QAAQ,MAAM,UAAU,KAAK,YAAY;CAChD;AACF,CAAC"}
package/dist/style.css CHANGED
@@ -1097,6 +1097,79 @@
1097
1097
  }
1098
1098
  }
1099
1099
 
1100
+ @layer theme, base, juxt, components, utilities;
1101
+ @layer juxt {
1102
+ .j-burger {
1103
+ --j-burger-size: var(--juxt-control-md);
1104
+ --j-burger-width: 1rem;
1105
+ --j-burger-gap: 0.3125rem;
1106
+
1107
+ display: inline-grid;
1108
+ place-items: center;
1109
+ width: var(--j-burger-size);
1110
+ height: var(--j-burger-size);
1111
+ padding: 0;
1112
+ border: 0;
1113
+ border-radius: var(--juxt-radius-sm);
1114
+ background: transparent;
1115
+ color: var(--juxt-fg);
1116
+ cursor: pointer;
1117
+ -webkit-tap-highlight-color: transparent;
1118
+ transition-property: background-color, outline-color, outline-offset;
1119
+ }
1120
+ .j-burger--sm {
1121
+ --j-burger-size: var(--juxt-control-sm);
1122
+ --j-burger-width: 0.875rem;
1123
+ --j-burger-gap: 0.25rem;
1124
+ }
1125
+ .j-burger:hover {
1126
+ background: var(--juxt-surface-hover);
1127
+ }
1128
+ .j-burger__lines {
1129
+ position: relative;
1130
+ display: block;
1131
+ width: var(--j-burger-width);
1132
+ height: calc(var(--j-burger-gap) * 2 + 1.5px);
1133
+ }
1134
+ .j-burger__line {
1135
+ position: absolute;
1136
+ left: 0;
1137
+ width: 100%;
1138
+ height: 1.5px;
1139
+ border-radius: 1px;
1140
+ background: currentColor;
1141
+ transition:
1142
+ transform var(--juxt-duration-normal) var(--juxt-ease-out),
1143
+ opacity var(--juxt-duration-fast) var(--juxt-ease-standard);
1144
+ }
1145
+ .j-burger__line:nth-child(1) {
1146
+ top: 0;
1147
+ }
1148
+ .j-burger__line:nth-child(2) {
1149
+ top: var(--j-burger-gap);
1150
+ }
1151
+ .j-burger__line:nth-child(3) {
1152
+ top: calc(var(--j-burger-gap) * 2);
1153
+ }
1154
+
1155
+ /* Outer lines meet in the middle and cross; the middle one fades. */
1156
+ .j-burger[data-state='open'] .j-burger__line:nth-child(1) {
1157
+ transform: translateY(var(--j-burger-gap)) rotate(45deg);
1158
+ }
1159
+ .j-burger[data-state='open'] .j-burger__line:nth-child(2) {
1160
+ opacity: 0;
1161
+ transform: scaleX(0.4);
1162
+ }
1163
+ .j-burger[data-state='open'] .j-burger__line:nth-child(3) {
1164
+ transform: translateY(calc(var(--j-burger-gap) * -1)) rotate(-45deg);
1165
+ }
1166
+ @media (prefers-reduced-motion: reduce) {
1167
+ .j-burger__line {
1168
+ transition-duration: 0ms;
1169
+ }
1170
+ }
1171
+ }
1172
+
1100
1173
  @layer theme, base, juxt, components, utilities;
1101
1174
  @layer juxt {
1102
1175
  .j-button {
@@ -2251,6 +2324,119 @@ to {
2251
2324
  }
2252
2325
  }
2253
2326
 
2327
+ @layer theme, base, juxt, components, utilities;
2328
+ @layer juxt {
2329
+ .j-footer {
2330
+ background: var(--juxt-bg);
2331
+ color: var(--juxt-fg-secondary);
2332
+ font-family: var(--juxt-font-sans);
2333
+ font-size: var(--juxt-text-sm);
2334
+ }
2335
+ .j-footer.is-bordered {
2336
+ border-top: 1px solid var(--juxt-border-subtle);
2337
+ }
2338
+ .dark .j-footer.is-bordered,
2339
+ [data-theme='dark'] .j-footer.is-bordered {
2340
+ border-top-color: var(--juxt-border);
2341
+ }
2342
+ .j-footer__inner {
2343
+ max-width: var(--j-footer-max);
2344
+ margin: 0 auto;
2345
+ padding: var(--juxt-space-12) var(--juxt-space-4) var(--juxt-space-8);
2346
+ }
2347
+ .j-footer__top {
2348
+ display: grid;
2349
+ grid-template-columns: minmax(0, 1fr);
2350
+ gap: var(--juxt-space-10);
2351
+ }
2352
+ .j-footer__brand {
2353
+ display: flex;
2354
+ flex-direction: column;
2355
+ gap: var(--juxt-space-3);
2356
+ max-width: 18rem;
2357
+ color: var(--juxt-fg-muted);
2358
+ line-height: var(--juxt-leading-normal);
2359
+ }
2360
+ .j-footer__columns {
2361
+ display: grid;
2362
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2363
+ gap: var(--juxt-space-8) var(--juxt-space-6);
2364
+ }
2365
+ @media (min-width: 768px) {
2366
+ .j-footer__top {
2367
+ grid-template-columns: minmax(12rem, 1fr) minmax(0, 2fr);
2368
+ }
2369
+ .j-footer__columns {
2370
+ grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
2371
+ }
2372
+ }
2373
+ .j-footer__bottom {
2374
+ display: flex;
2375
+ flex-wrap: wrap;
2376
+ align-items: center;
2377
+ justify-content: space-between;
2378
+ gap: var(--juxt-space-3) var(--juxt-space-6);
2379
+ margin-top: var(--juxt-space-12);
2380
+ padding-top: var(--juxt-space-6);
2381
+ border-top: 1px solid var(--juxt-border-subtle);
2382
+ color: var(--juxt-fg-muted);
2383
+ font-size: var(--juxt-text-xs);
2384
+ }
2385
+ .dark .j-footer__bottom,
2386
+ [data-theme='dark'] .j-footer__bottom {
2387
+ border-top-color: var(--juxt-border);
2388
+ }
2389
+ .j-footer__bottom a {
2390
+ color: inherit;
2391
+ text-decoration: none;
2392
+ transition: color var(--juxt-duration-fast) var(--juxt-ease-standard);
2393
+ }
2394
+ .j-footer__bottom a:hover {
2395
+ color: var(--juxt-fg);
2396
+ }
2397
+ }
2398
+
2399
+ @layer theme, base, juxt, components, utilities;
2400
+ @layer juxt {
2401
+ .j-footer-column {
2402
+ display: flex;
2403
+ flex-direction: column;
2404
+ gap: var(--juxt-space-3);
2405
+ min-width: 0;
2406
+ }
2407
+ .j-footer-column__title {
2408
+ margin: 0;
2409
+ color: var(--juxt-fg);
2410
+ font-size: var(--juxt-text-sm);
2411
+ font-weight: var(--juxt-weight-medium);
2412
+ letter-spacing: var(--juxt-tracking-tight);
2413
+ }
2414
+ .j-footer-column__links {
2415
+ display: flex;
2416
+ flex-direction: column;
2417
+ align-items: flex-start;
2418
+ gap: var(--juxt-space-2);
2419
+ }
2420
+ .j-footer-column__links a {
2421
+ border-radius: var(--juxt-radius-xs);
2422
+ color: var(--juxt-fg-muted);
2423
+ text-decoration: none;
2424
+ outline: 2px solid transparent;
2425
+ outline-offset: 0;
2426
+ transition:
2427
+ color var(--juxt-duration-fast) var(--juxt-ease-standard),
2428
+ outline-color var(--juxt-duration-fast) var(--juxt-ease-out),
2429
+ outline-offset var(--juxt-duration-fast) var(--juxt-ease-out);
2430
+ }
2431
+ .j-footer-column__links a:hover {
2432
+ color: var(--juxt-fg);
2433
+ }
2434
+ .j-footer-column__links a:focus-visible {
2435
+ outline-color: var(--juxt-ring);
2436
+ outline-offset: 2px;
2437
+ }
2438
+ }
2439
+
2254
2440
  @layer theme, base, juxt, components, utilities;
2255
2441
  @layer juxt {
2256
2442
  .j-field {
@@ -2352,6 +2538,193 @@ to {
2352
2538
  }
2353
2539
  }
2354
2540
 
2541
+ @layer theme, base, juxt, components, utilities;
2542
+ @layer juxt {
2543
+ .j-navbar {
2544
+ --j-navbar-height: 3.5rem;
2545
+
2546
+ position: relative;
2547
+ z-index: var(--juxt-z-sticky);
2548
+ background: var(--juxt-bg);
2549
+ color: var(--juxt-fg);
2550
+ font-family: var(--juxt-font-sans);
2551
+ }
2552
+ .j-navbar.is-sticky {
2553
+ position: sticky;
2554
+ top: 0;
2555
+ }
2556
+ .j-navbar.is-bordered {
2557
+ box-shadow: inset 0 -1px 0 var(--juxt-border-subtle);
2558
+ }
2559
+ .dark .j-navbar.is-bordered,
2560
+ [data-theme='dark'] .j-navbar.is-bordered {
2561
+ box-shadow: inset 0 -1px 0 var(--juxt-border);
2562
+ }
2563
+ .j-navbar__bar {
2564
+ display: flex;
2565
+ align-items: center;
2566
+ gap: var(--juxt-space-6);
2567
+ max-width: var(--j-navbar-max);
2568
+ height: var(--j-navbar-height);
2569
+ margin: 0 auto;
2570
+ padding: 0 var(--juxt-space-4);
2571
+ }
2572
+ .j-navbar__brand {
2573
+ display: flex;
2574
+ flex: none;
2575
+ align-items: center;
2576
+ }
2577
+ .j-navbar__links {
2578
+ display: flex;
2579
+ align-items: center;
2580
+ gap: var(--juxt-space-1);
2581
+ min-width: 0;
2582
+ }
2583
+ .j-navbar__end {
2584
+ display: flex;
2585
+ align-items: center;
2586
+ gap: var(--juxt-space-2);
2587
+ margin-left: auto;
2588
+ }
2589
+ .j-navbar__actions {
2590
+ display: flex;
2591
+ align-items: center;
2592
+ gap: var(--juxt-space-2);
2593
+ }
2594
+ .j-navbar__burger {
2595
+ display: none;
2596
+ margin-right: calc(var(--juxt-space-2) * -1);
2597
+ }
2598
+
2599
+ /* Mobile menu: a panel that drops from the bar, links stacked with big targets. */
2600
+ .j-navbar__menu {
2601
+ position: absolute;
2602
+ top: 100%;
2603
+ right: 0;
2604
+ left: 0;
2605
+ display: flex;
2606
+ flex-direction: column;
2607
+ gap: var(--juxt-space-4);
2608
+ max-height: calc(100dvh - var(--j-navbar-height));
2609
+ padding: var(--juxt-space-3) var(--juxt-space-4) var(--juxt-space-5);
2610
+ overflow-y: auto;
2611
+ border-bottom: 1px solid var(--juxt-border);
2612
+ background: var(--juxt-bg);
2613
+ box-shadow: var(--juxt-shadow-md);
2614
+ }
2615
+ .j-navbar__menu-links {
2616
+ display: flex;
2617
+ flex-direction: column;
2618
+ gap: var(--juxt-space-0-5);
2619
+ }
2620
+ .j-navbar__menu-links .j-navbar-link {
2621
+ justify-content: flex-start;
2622
+ height: 2.75rem;
2623
+ padding: 0 var(--juxt-space-3);
2624
+ font-size: var(--juxt-text-lg);
2625
+ }
2626
+ .j-navbar__menu-footer {
2627
+ display: flex;
2628
+ flex-direction: column;
2629
+ gap: var(--juxt-space-2);
2630
+ padding-top: var(--juxt-space-4);
2631
+ border-top: 1px solid var(--juxt-border-subtle);
2632
+ }
2633
+ .j-navbar__menu-footer > * {
2634
+ width: 100%;
2635
+ }
2636
+ .j-navbar-menu-enter-active {
2637
+ transition:
2638
+ opacity var(--juxt-duration-fast) var(--juxt-ease-out),
2639
+ transform var(--juxt-duration-normal) var(--juxt-ease-out);
2640
+ }
2641
+ .j-navbar-menu-leave-active {
2642
+ transition:
2643
+ opacity var(--juxt-duration-instant) var(--juxt-ease-in),
2644
+ transform var(--juxt-duration-instant) var(--juxt-ease-in);
2645
+ }
2646
+ .j-navbar-menu-enter-from,
2647
+ .j-navbar-menu-leave-to {
2648
+ opacity: 0;
2649
+ transform: translateY(calc(var(--juxt-motion-shift) * -1));
2650
+ }
2651
+
2652
+ /* Collapse points. Above them the menu never shows, below them the links hide. */
2653
+ .j-navbar--collapse-never .j-navbar__menu {
2654
+ display: none !important;
2655
+ }
2656
+ @media (max-width: 639.98px) {
2657
+ .j-navbar--collapse-sm .j-navbar__links { display: none;
2658
+ }
2659
+ .j-navbar--collapse-sm .j-navbar__burger { display: inline-grid;
2660
+ }
2661
+ }
2662
+ @media (min-width: 640px) {
2663
+ .j-navbar--collapse-sm .j-navbar__menu { display: none !important;
2664
+ }
2665
+ }
2666
+ @media (max-width: 767.98px) {
2667
+ .j-navbar--collapse-md .j-navbar__links { display: none;
2668
+ }
2669
+ .j-navbar--collapse-md .j-navbar__burger { display: inline-grid;
2670
+ }
2671
+ }
2672
+ @media (min-width: 768px) {
2673
+ .j-navbar--collapse-md .j-navbar__menu { display: none !important;
2674
+ }
2675
+ }
2676
+ @media (max-width: 1023.98px) {
2677
+ .j-navbar--collapse-lg .j-navbar__links { display: none;
2678
+ }
2679
+ .j-navbar--collapse-lg .j-navbar__burger { display: inline-grid;
2680
+ }
2681
+ }
2682
+ @media (min-width: 1024px) {
2683
+ .j-navbar--collapse-lg .j-navbar__menu { display: none !important;
2684
+ }
2685
+ }
2686
+ }
2687
+
2688
+ @layer theme, base, juxt, components, utilities;
2689
+ @layer juxt {
2690
+ .j-navbar-link {
2691
+ display: inline-flex;
2692
+ align-items: center;
2693
+ gap: var(--juxt-space-1-5);
2694
+ height: var(--juxt-control-sm);
2695
+ padding: 0 var(--juxt-space-2-5);
2696
+ border-radius: var(--juxt-radius-sm);
2697
+ color: var(--juxt-fg-muted);
2698
+ font-size: var(--juxt-text-sm);
2699
+ font-weight: var(--juxt-weight-medium);
2700
+ letter-spacing: var(--juxt-tracking-tight);
2701
+ text-decoration: none;
2702
+ white-space: nowrap;
2703
+ cursor: pointer;
2704
+ -webkit-tap-highlight-color: transparent;
2705
+ transition-property: color, background-color, outline-color, outline-offset;
2706
+ }
2707
+ .j-navbar-link:hover {
2708
+ color: var(--juxt-fg);
2709
+ }
2710
+ .j-navbar-link.is-active {
2711
+ color: var(--juxt-fg);
2712
+ }
2713
+
2714
+ /* In the mobile menu the current page gets a quiet fill, like a selected row. */
2715
+ .j-navbar__menu .j-navbar-link.is-active {
2716
+ background: var(--juxt-surface-hover);
2717
+ }
2718
+ .j-navbar-link__icon {
2719
+ display: inline-flex;
2720
+ color: var(--juxt-fg-muted);
2721
+ }
2722
+ .j-navbar-link__icon > svg {
2723
+ width: 1rem;
2724
+ height: 1rem;
2725
+ }
2726
+ }
2727
+
2355
2728
  @layer theme, base, juxt, components, utilities;
2356
2729
  @layer juxt {
2357
2730
  .j-pagination {
@@ -3108,6 +3481,196 @@ to {
3108
3481
  }
3109
3482
  }
3110
3483
 
3484
+ @layer theme, base, juxt, components, utilities;
3485
+ @layer juxt {
3486
+ .j-sidebar {
3487
+ display: flex;
3488
+ flex-direction: column;
3489
+ width: 100%;
3490
+ height: 100%;
3491
+ min-height: 0;
3492
+ color: var(--juxt-fg);
3493
+ font-family: var(--juxt-font-sans);
3494
+ }
3495
+ .j-sidebar__header {
3496
+ display: flex;
3497
+ align-items: center;
3498
+ gap: var(--juxt-space-2);
3499
+ padding: var(--juxt-space-3) var(--juxt-space-3) var(--juxt-space-2);
3500
+ }
3501
+ .j-sidebar__nav {
3502
+ display: flex;
3503
+ flex: 1;
3504
+ flex-direction: column;
3505
+ gap: var(--juxt-space-4);
3506
+ min-height: 0;
3507
+ padding: var(--juxt-space-2);
3508
+ overflow-y: auto;
3509
+ overscroll-behavior: contain;
3510
+ }
3511
+ .j-sidebar__footer {
3512
+ display: flex;
3513
+ flex-direction: column;
3514
+ gap: var(--juxt-space-0-5);
3515
+ padding: var(--juxt-space-2);
3516
+ border-top: 1px solid var(--juxt-border-subtle);
3517
+ }
3518
+ .dark .j-sidebar__footer,
3519
+ [data-theme='dark'] .j-sidebar__footer {
3520
+ border-top-color: var(--juxt-border);
3521
+ }
3522
+ }
3523
+
3524
+ @layer theme, base, juxt, components, utilities;
3525
+ @layer juxt {
3526
+ .j-sidebar-group {
3527
+ display: flex;
3528
+ flex-direction: column;
3529
+ gap: var(--juxt-space-0-5);
3530
+ }
3531
+ .j-sidebar-group__title {
3532
+ display: flex;
3533
+ align-items: center;
3534
+ justify-content: space-between;
3535
+ gap: var(--juxt-space-2);
3536
+ margin: 0;
3537
+ padding: var(--juxt-space-1) var(--juxt-space-2);
3538
+ color: var(--juxt-fg-muted);
3539
+ font-size: var(--juxt-text-xs);
3540
+ font-weight: var(--juxt-weight-medium);
3541
+ line-height: var(--juxt-leading-snug);
3542
+ }
3543
+ .j-sidebar-group__toggle {
3544
+ width: 100%;
3545
+ border: 0;
3546
+ border-radius: var(--juxt-radius-xs);
3547
+ background: transparent;
3548
+ font-family: inherit;
3549
+ text-align: left;
3550
+ cursor: pointer;
3551
+ transition-property: color, outline-color, outline-offset;
3552
+ }
3553
+ .j-sidebar-group__toggle:hover {
3554
+ color: var(--juxt-fg-secondary);
3555
+ }
3556
+ .j-sidebar-group__chevron {
3557
+ flex: none;
3558
+ width: 0.75rem;
3559
+ height: 0.75rem;
3560
+ opacity: 0;
3561
+ transform: rotate(-90deg);
3562
+ transition:
3563
+ transform var(--juxt-duration-normal) var(--juxt-ease-out),
3564
+ opacity var(--juxt-duration-fast) var(--juxt-ease-standard);
3565
+ }
3566
+
3567
+ /* The chevron only appears on hover or focus, or while the group is folded. */
3568
+ .j-sidebar-group__toggle:hover .j-sidebar-group__chevron,
3569
+ .j-sidebar-group__toggle:focus-visible .j-sidebar-group__chevron,
3570
+ .j-sidebar-group[data-state='closed'] .j-sidebar-group__chevron {
3571
+ opacity: 1;
3572
+ }
3573
+ .j-sidebar-group[data-state='open'] .j-sidebar-group__chevron {
3574
+ transform: none;
3575
+ }
3576
+ .j-sidebar-group__panel {
3577
+ display: grid;
3578
+ grid-template-rows: 1fr;
3579
+ transition: grid-template-rows var(--juxt-duration-normal) var(--juxt-ease-out);
3580
+ }
3581
+ .j-sidebar-group[data-state='closed'] .j-sidebar-group__panel {
3582
+ grid-template-rows: 0fr;
3583
+ }
3584
+ .j-sidebar-group__panel-inner {
3585
+ min-height: 0;
3586
+ overflow: hidden;
3587
+ }
3588
+ .j-sidebar-group__items {
3589
+ display: flex;
3590
+ flex-direction: column;
3591
+ gap: var(--juxt-space-0-5);
3592
+ }
3593
+ @media (prefers-reduced-motion: reduce) {
3594
+ .j-sidebar-group__panel,
3595
+ .j-sidebar-group__chevron {
3596
+ transition: none;
3597
+ }
3598
+ }
3599
+ }
3600
+
3601
+ @layer theme, base, juxt, components, utilities;
3602
+ @layer juxt {
3603
+ .j-sidebar-item {
3604
+ position: relative;
3605
+ display: flex;
3606
+ align-items: center;
3607
+ gap: var(--juxt-space-2);
3608
+ min-height: var(--juxt-control-sm);
3609
+ padding: 0 var(--juxt-space-2);
3610
+ border-radius: var(--juxt-radius-sm);
3611
+ color: var(--juxt-fg-secondary);
3612
+ font-size: var(--juxt-text-sm);
3613
+ letter-spacing: var(--juxt-tracking-tight);
3614
+ text-decoration: none;
3615
+ cursor: pointer;
3616
+ -webkit-tap-highlight-color: transparent;
3617
+ transition-property: color, background-color, outline-color, outline-offset;
3618
+ }
3619
+ .j-sidebar-item:hover:not(.is-disabled) {
3620
+ background: var(--juxt-surface-hover);
3621
+ color: var(--juxt-fg);
3622
+ }
3623
+ .j-sidebar-item.is-active {
3624
+ background: var(--juxt-surface-hover);
3625
+ color: var(--juxt-fg);
3626
+ font-weight: var(--juxt-weight-medium);
3627
+ }
3628
+
3629
+ /* Same marker as the command palette: a short accent line where you are. */
3630
+ .j-sidebar-item.is-active::before {
3631
+ content: '';
3632
+ position: absolute;
3633
+ top: 0.4375rem;
3634
+ bottom: 0.4375rem;
3635
+ left: 0;
3636
+ width: 2px;
3637
+ border-radius: 0 2px 2px 0;
3638
+ background: var(--juxt-accent);
3639
+ }
3640
+ .j-sidebar-item.is-disabled {
3641
+ color: var(--juxt-fg-disabled);
3642
+ cursor: not-allowed;
3643
+ }
3644
+ .j-sidebar-item__icon {
3645
+ display: inline-flex;
3646
+ flex: none;
3647
+ color: var(--juxt-fg-muted);
3648
+ }
3649
+ .j-sidebar-item.is-active .j-sidebar-item__icon,
3650
+ .j-sidebar-item:hover:not(.is-disabled) .j-sidebar-item__icon {
3651
+ color: var(--juxt-fg);
3652
+ }
3653
+ .j-sidebar-item__icon > svg {
3654
+ width: 1rem;
3655
+ height: 1rem;
3656
+ }
3657
+ .j-sidebar-item__label {
3658
+ flex: 1;
3659
+ min-width: 0;
3660
+ overflow: hidden;
3661
+ text-overflow: ellipsis;
3662
+ white-space: nowrap;
3663
+ }
3664
+ .j-sidebar-item__trailing {
3665
+ display: inline-flex;
3666
+ flex: none;
3667
+ align-items: center;
3668
+ color: var(--juxt-fg-muted);
3669
+ font-size: var(--juxt-text-xs);
3670
+ font-variant-numeric: tabular-nums;
3671
+ }
3672
+ }
3673
+
3111
3674
  @layer theme, base, juxt, components, utilities;
3112
3675
  @layer juxt {
3113
3676
  .j-skeleton {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juxtui/ui",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Thoughtfully crafted components for Nuxt & Vue.",
5
5
  "license": "MIT",
6
6
  "author": "Julius K.",