@adea-ai/ui 0.110.1 → 0.111.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.
Files changed (88) hide show
  1. package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts +17 -2
  2. package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts.map +1 -1
  3. package/dist/components/composites/appearance-editor/accent-swatch-groups.js +47 -122
  4. package/dist/components/composites/appearance-editor/accent-swatch-groups.js.map +1 -1
  5. package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -1
  6. package/dist/components/composites/appearance-editor/appearance-choices.js +0 -4
  7. package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -1
  8. package/dist/components/composites/appearance-editor/appearance-editor.js +1 -1
  9. package/dist/components/composites/appearance-editor/font-settings-group.d.ts.map +1 -1
  10. package/dist/components/composites/appearance-editor/font-settings-group.js +60 -68
  11. package/dist/components/composites/appearance-editor/font-settings-group.js.map +1 -1
  12. package/dist/components/composites/appearance-editor/index.js +1 -1
  13. package/dist/components/theme/appearance-panel.d.ts.map +1 -1
  14. package/dist/components/theme/appearance-panel.js +0 -3
  15. package/dist/components/theme/appearance-panel.js.map +1 -1
  16. package/dist/components/ui/alert-dialog/alert-dialog.js +2 -2
  17. package/dist/components/ui/alert-dialog/alert-dialog.js.map +1 -1
  18. package/dist/components/ui/combobox/combobox.d.ts.map +1 -1
  19. package/dist/components/ui/combobox/combobox.js +1 -1
  20. package/dist/components/ui/combobox/combobox.js.map +1 -1
  21. package/dist/components/ui/context-menu/context-menu.d.ts.map +1 -1
  22. package/dist/components/ui/context-menu/context-menu.js +2 -2
  23. package/dist/components/ui/context-menu/context-menu.js.map +1 -1
  24. package/dist/components/ui/dialog/dialog.js +2 -2
  25. package/dist/components/ui/dialog/dialog.js.map +1 -1
  26. package/dist/components/ui/drawer/drawer.js +1 -1
  27. package/dist/components/ui/drawer/drawer.js.map +1 -1
  28. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +22 -2
  29. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  30. package/dist/components/ui/dropdown-menu/dropdown-menu.js +79 -30
  31. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  32. package/dist/components/ui/dropdown-menu/index.d.ts +1 -0
  33. package/dist/components/ui/dropdown-menu/index.d.ts.map +1 -1
  34. package/dist/components/ui/menubar/menubar.d.ts.map +1 -1
  35. package/dist/components/ui/menubar/menubar.js +2 -2
  36. package/dist/components/ui/menubar/menubar.js.map +1 -1
  37. package/dist/components/ui/select/index.d.ts +1 -0
  38. package/dist/components/ui/select/index.d.ts.map +1 -1
  39. package/dist/components/ui/select/select.d.ts +7 -1
  40. package/dist/components/ui/select/select.d.ts.map +1 -1
  41. package/dist/components/ui/select/select.js +34 -20
  42. package/dist/components/ui/select/select.js.map +1 -1
  43. package/dist/components/ui/sheet/sheet.js +1 -1
  44. package/dist/components/ui/sheet/sheet.js.map +1 -1
  45. package/dist/components/ui/tooltip/tooltip.d.ts +16 -6
  46. package/dist/components/ui/tooltip/tooltip.d.ts.map +1 -1
  47. package/dist/components/ui/tooltip/tooltip.js +15 -4
  48. package/dist/components/ui/tooltip/tooltip.js.map +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/lib/overlay.d.ts +30 -1
  51. package/dist/lib/overlay.d.ts.map +1 -1
  52. package/dist/lib/overlay.js +37 -2
  53. package/dist/lib/overlay.js.map +1 -1
  54. package/dist/r/src/components/composites/appearance-editor/accent-swatch-groups.tsx +33 -86
  55. package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +0 -3
  56. package/dist/r/src/components/composites/appearance-editor/font-settings-group.tsx +20 -7
  57. package/dist/r/src/components/theme/appearance-panel.tsx +0 -1
  58. package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +2 -2
  59. package/dist/r/src/components/ui/combobox/combobox.tsx +3 -1
  60. package/dist/r/src/components/ui/context-menu/context-menu.tsx +6 -2
  61. package/dist/r/src/components/ui/dialog/dialog.tsx +2 -2
  62. package/dist/r/src/components/ui/drawer/drawer.tsx +1 -1
  63. package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +44 -6
  64. package/dist/r/src/components/ui/dropdown-menu/index.ts +1 -0
  65. package/dist/r/src/components/ui/menubar/menubar.tsx +6 -2
  66. package/dist/r/src/components/ui/select/index.ts +1 -0
  67. package/dist/r/src/components/ui/select/select.tsx +31 -6
  68. package/dist/r/src/components/ui/sheet/sheet.tsx +1 -1
  69. package/dist/r/src/components/ui/tooltip/tooltip.tsx +28 -2
  70. package/dist/r/src/lib/overlay.ts +45 -1
  71. package/package.json +1 -1
  72. package/src/components/composites/appearance-editor/accent-swatch-groups.tsx +33 -86
  73. package/src/components/composites/appearance-editor/appearance-choices.tsx +0 -3
  74. package/src/components/composites/appearance-editor/font-settings-group.tsx +20 -7
  75. package/src/components/theme/appearance-panel.tsx +0 -1
  76. package/src/components/ui/alert-dialog/alert-dialog.tsx +2 -2
  77. package/src/components/ui/combobox/combobox.tsx +3 -1
  78. package/src/components/ui/context-menu/context-menu.tsx +6 -2
  79. package/src/components/ui/dialog/dialog.tsx +2 -2
  80. package/src/components/ui/drawer/drawer.tsx +1 -1
  81. package/src/components/ui/dropdown-menu/dropdown-menu.tsx +44 -6
  82. package/src/components/ui/dropdown-menu/index.ts +1 -0
  83. package/src/components/ui/menubar/menubar.tsx +6 -2
  84. package/src/components/ui/select/index.ts +1 -0
  85. package/src/components/ui/select/select.tsx +31 -6
  86. package/src/components/ui/sheet/sheet.tsx +1 -1
  87. package/src/components/ui/tooltip/tooltip.tsx +28 -2
  88. package/src/lib/overlay.ts +45 -1
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.js","names":[],"sources":["../../src/lib/overlay.ts"],"sourcesContent":["/**\n * Shared strings for the overlay layer: dialogs, sheets, menus, popovers,\n * tooltips and the command palette.\n *\n * These live here rather than in each component because the overlay family is\n * where consistency is most visible and least likely to survive duplication.\n * A dialog, a sheet and a dropdown that disagree about their border, radius,\n * motion or shadow read as three different apps — and an app that adopts this\n * library would inherit all three. Declaring the surface once is what makes\n * \"an overlay looks like this\" a fact rather than a convention.\n */\n\n/** The panel itself: fill, hairline edge, radius, elevation. */\nexport const overlaySurface =\n 'bg-popover text-popover-foreground rounded-xl border border-border shadow-lg'\n\n/**\n * Overlay titles have one fixed typography role. Keep this small recipe shared\n * without loading the configurable Heading component into every dialog.\n */\nexport const overlayTitle = 'font-semibold text-base tracking-tight leading-none'\n\n/** The span of the portal wrapper that centres a dialog-like overlay. */\nexport const overlayPositioner = 'fixed inset-0 z-(--z-dialog) grid place-items-center p-4'\n\n/** The dimming layer behind a modal overlay. */\nexport const overlayScrim =\n 'fixed inset-0 z-(--z-dialog) bg-scrim/50 supports-[backdrop-filter]:backdrop-blur-xs'\n\n/**\n * The tip: the card-toned bubble an explanation shows in. The side rail draws\n * it flush to a collapsed row and every floating tooltip composes the same\n * fill, edge, and type, so a control never explains itself in two visual\n * languages.\n */\nexport const tooltipTip =\n 'bg-card text-card-foreground rounded-md border border-border text-sm font-medium shadow-lg'\n\n/**\n * Entrance and exit motion, expressed as data-state classes.\n *\n * `data-expanded` / `data-closed` are Kobalte's; `data-side-*` come from its\n * popper positioning and let a menu slide in from the edge it is anchored to,\n * which is what makes a dropdown feel attached to its trigger rather than\n * dropped on the screen. Exit motion is shorter than entry, because a\n * dismissal should feel immediate while an arrival benefits from being seen.\n */\nexport const overlayMotion = [\n 'data-expanded:animate-in data-expanded:fade-in-0 data-expanded:zoom-in-95',\n 'data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n 'data-expanded:duration-200 data-closed:duration-150',\n].join(' ')\n\n/** Popover-style motion: no zoom, so a panel anchored to a control does not\n * appear to breathe away from it. */\nexport const popoverMotion = [\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n 'data-expanded:duration-150 data-closed:duration-100',\n].join(' ')\n\n/** The popper arrow. Sized in the component; coloured here. */\nexport const popoverArrow = 'fill-popover stroke-border'\n\n/**\n * A menu row: the shared height, radius, hover fill and focus treatment for\n * every item inside a menu, listbox or command list.\n */\nexport const menuItem = [\n 'relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none',\n 'transition-colors ease-out',\n 'data-[highlighted]:bg-surface-hover data-[highlighted]:text-foreground',\n 'data-[disabled]:pointer-events-none data-[disabled]:text-muted-foreground',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4',\n '[&_svg:not([class*=text-])]:text-muted-foreground',\n].join(' ')\n\n/** A destructive action keeps readable text and marks its row with a status edge. */\nexport const destructiveMenuItem =\n 'border-s-2 border-destructive ps-1.5 text-foreground data-[highlighted]:bg-destructive-subtle'\n\n/** The label above a group of menu rows. */\nexport const menuLabel =\n 'px-2 py-1.5 text-2xs font-medium tracking-wide text-muted-foreground uppercase'\n\n/** The rule between menu groups. */\nexport const menuSeparator = 'bg-border -mx-1 my-1 h-px'\n\n/** Padding shared by every menu-list surface. */\nexport const menuContentPadding = 'p-1'\n\n/**\n * Marks a floating layer — a menu, a listbox, a popover — as part of the top\n * layer.\n *\n * A modal dialog hides everything outside itself from assistive technology\n * (`aria-hidden` on its siblings) and keeps watching `<body>` for new nodes.\n * A menu or select opened from inside the dialog portals to `<body>`, so the\n * dialog hid it too: the list was on screen, focused, and invisible to a\n * screen reader, and an outside-click check could treat a click on it as a\n * click away from the dialog. Kobalte exempts nodes carrying this attribute\n * from both, so every floating layer carries it.\n */\nexport const topLayerProps = { 'data-kb-top-layer': '' } as const\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,iBACX;;;;;AAMF,IAAa,eAAe;;AAG5B,IAAa,oBAAoB;;AAGjC,IAAa,eACX;;;;;;;AAQF,IAAa,aACX;;;;;;;;;;AAWF,IAAa,gBAAgB;CAC3B;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;;AAIV,IAAa,gBAAgB,CAC3B,mGACA,qDACF,CAAC,CAAC,KAAK,GAAG;;AAGV,IAAa,eAAe;;;;;AAM5B,IAAa,WAAW;CACtB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;AAGV,IAAa,sBACX;;AAGF,IAAa,YACX;;AAGF,IAAa,gBAAgB;;;;;;;;;;;;;AAiB7B,IAAa,gBAAgB,EAAE,qBAAqB,GAAG"}
1
+ {"version":3,"file":"overlay.js","names":[],"sources":["../../src/lib/overlay.ts"],"sourcesContent":["/**\n * Shared strings for the overlay layer: dialogs, sheets, menus, popovers,\n * tooltips and the command palette.\n *\n * These live here rather than in each component because the overlay family is\n * where consistency is most visible and least likely to survive duplication.\n * A dialog, a sheet and a dropdown that disagree about their border, radius,\n * motion or shadow read as three different apps — and an app that adopts this\n * library would inherit all three. Declaring the surface once is what makes\n * \"an overlay looks like this\" a fact rather than a convention.\n */\n\nimport { cva, type VariantProps } from '#lib/variants'\n\n/** The panel itself: fill, hairline edge, radius, elevation. Menus, popovers\n * and the command palette float on the elevated overlay rung (`--popover`). */\nexport const overlaySurface =\n 'bg-popover text-popover-foreground rounded-xl border border-border shadow-lg'\n\n/**\n * The modal panel: the same hairline edge, radius and elevation, painted on the\n * *neutral* theme surface instead of the elevated overlay rung.\n *\n * `--popover` is the catalogue's `surfaceElevated`, whose derivation amplifies\n * the canvas hue's chroma on the elevated step. On the dark default's violet\n * canvas that makes the dialog the most chromatic surface in the ladder —\n * `oklch(0.2406 0.0088 300.91)`, red above green in sRGB — and on a full dialog\n * panel that cast reads as a warm tint the canvas never has. shadcn's own\n * convention already splits the two: a Dialog paints `bg-background`, menus and\n * popovers paint `bg-popover`. The veil, the hairline and the elevation shadow\n * carry the separation the lighter fill no longer provides.\n */\nexport const dialogSurface =\n 'bg-background text-foreground rounded-xl border border-border shadow-lg'\n\n/**\n * Overlay titles have one fixed typography role. Keep this small recipe shared\n * without loading the configurable Heading component into every dialog.\n */\nexport const overlayTitle = 'font-semibold text-base tracking-tight leading-none'\n\n/** The span of the portal wrapper that centres a dialog-like overlay. */\nexport const overlayPositioner = 'fixed inset-0 z-(--z-dialog) grid place-items-center p-4'\n\n/** The dimming layer behind a modal overlay. */\nexport const overlayScrim =\n 'fixed inset-0 z-(--z-dialog) bg-scrim/50 supports-[backdrop-filter]:backdrop-blur-xs'\n\n/**\n * The tip: the card-toned bubble an explanation shows in. The side rail draws\n * it flush to a collapsed row and every floating tooltip composes the same\n * fill, edge, and type, so a control never explains itself in two visual\n * languages.\n */\nexport const tooltipTip =\n 'bg-card text-card-foreground rounded-md border border-border text-sm font-medium shadow-lg'\n\n/**\n * Entrance and exit motion, expressed as data-state classes.\n *\n * `data-expanded` / `data-closed` are Kobalte's; `data-side-*` come from its\n * popper positioning and let a menu slide in from the edge it is anchored to,\n * which is what makes a dropdown feel attached to its trigger rather than\n * dropped on the screen. Exit motion is shorter than entry, because a\n * dismissal should feel immediate while an arrival benefits from being seen.\n */\nexport const overlayMotion = [\n 'data-expanded:animate-in data-expanded:fade-in-0 data-expanded:zoom-in-95',\n 'data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n 'data-expanded:duration-200 data-closed:duration-150',\n].join(' ')\n\n/** Popover-style motion: no zoom, so a panel anchored to a control does not\n * appear to breathe away from it. */\nexport const popoverMotion = [\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n 'data-expanded:duration-150 data-closed:duration-100',\n].join(' ')\n\n/** The popper arrow. Sized in the component; coloured here. */\nexport const popoverArrow = 'fill-popover stroke-border'\n\n/**\n * A menu row: the shared height, radius, hover fill and focus treatment for\n * every item inside a menu, listbox or command list.\n */\nexport const menuItem = [\n 'relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none',\n 'transition-colors ease-out',\n 'data-[highlighted]:bg-surface-hover data-[highlighted]:text-foreground',\n 'data-[disabled]:pointer-events-none data-[disabled]:text-muted-foreground',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4',\n '[&_svg:not([class*=text-])]:text-muted-foreground',\n].join(' ')\n\n/** A destructive action keeps readable text and marks its row with a status edge. */\nexport const destructiveMenuItem =\n 'border-s-2 border-destructive ps-1.5 text-foreground data-[highlighted]:bg-destructive-subtle'\n\n/** The label above a group of menu rows. */\nexport const menuLabel =\n 'px-2 py-1.5 text-2xs font-medium tracking-wide text-muted-foreground uppercase'\n\n/** The rule between menu groups. */\nexport const menuSeparator = 'bg-border -mx-1 my-1 h-px'\n\n/**\n * A leading colour swatch on a menu or select row: the sanctioned way to carry\n * a card-tone colour into a list of options. The tones are the system's accent\n * and status roles — the vocabulary a Badge already speaks — so the colour an\n * option shows in a menu is the colour its badge carries on a card, and a\n * caller never passes a raw colour into a list. The dot is `aria-hidden`; the\n * label carries the meaning, so a tone is never the only signal.\n */\nexport const menuSwatchTone = cva('size-2 shrink-0 rounded-full', {\n variants: {\n tone: {\n neutral: 'bg-muted-foreground',\n primary: 'bg-primary',\n success: 'bg-success',\n warning: 'bg-warning',\n destructive: 'bg-destructive',\n info: 'bg-info',\n },\n },\n defaultVariants: { tone: 'neutral' },\n})\n\n/** The tones a menu row's swatch can take. */\nexport type MenuSwatchTone = NonNullable<VariantProps<typeof menuSwatchTone>['tone']>\n\n/** Padding shared by every menu-list surface. */\nexport const menuContentPadding = 'p-1'\n\n/**\n * Marks a floating layer — a menu, a listbox, a popover — as part of the top\n * layer.\n *\n * A modal dialog hides everything outside itself from assistive technology\n * (`aria-hidden` on its siblings) and keeps watching `<body>` for new nodes.\n * A menu or select opened from inside the dialog portals to `<body>`, so the\n * dialog hid it too: the list was on screen, focused, and invisible to a\n * screen reader, and an outside-click check could treat a click on it as a\n * click away from the dialog. Kobalte exempts nodes carrying this attribute\n * from both, so every floating layer carries it.\n */\nexport const topLayerProps = { 'data-kb-top-layer': '' } as const\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,IAAa,iBACX;;;;;;;;;;;;;;AAeF,IAAa,gBACX;;;;;AAMF,IAAa,eAAe;;AAG5B,IAAa,oBAAoB;;AAGjC,IAAa,eACX;;;;;;;AAQF,IAAa,aACX;;;;;;;;;;AAWF,IAAa,gBAAgB;CAC3B;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;;AAIV,IAAa,gBAAgB,CAC3B,mGACA,qDACF,CAAC,CAAC,KAAK,GAAG;;AAGV,IAAa,eAAe;;;;;AAM5B,IAAa,WAAW;CACtB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;AAGV,IAAa,sBACX;;AAGF,IAAa,YACX;;AAGF,IAAa,gBAAgB;;;;;;;;;AAU7B,IAAa,iBAAiB,IAAI,gCAAgC;CAChE,UAAU,EACR,MAAM;EACJ,SAAS;EACT,SAAS;EACT,SAAS;EACT,SAAS;EACT,aAAa;EACb,MAAM;CACR,EACF;CACA,iBAAiB,EAAE,MAAM,UAAU;AACrC,CAAC;;;;;;;;;;;;;AAoBD,IAAa,gBAAgB,EAAE,qBAAqB,GAAG"}
@@ -22,11 +22,7 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
  import { RadioGroup as Radio } from '@kobalte/core/radio-group'
25
- import { For, Show } from 'solid-js'
26
- import { cn } from '../../../lib/utils'
27
-
28
- export const PRIMARY_ACCENT_IDS = ['blue', 'green', 'amber', 'cyan', 'pink'] as const
29
- const primaryAccentIds: ReadonlySet<string> = new Set(PRIMARY_ACCENT_IDS)
25
+ import { For } from 'solid-js'
30
26
 
31
27
  type AccentOption = Readonly<{
32
28
  id: string
@@ -37,104 +33,55 @@ type AccentOption = Readonly<{
37
33
 
38
34
  type AccentSwatchGroupsProps = {
39
35
  accentOptions: readonly AccentOption[]
40
- themeAccentOptions: readonly AccentOption[]
36
+ /**
37
+ * Accepted for host compatibility and no longer rendered. The picker offers
38
+ * one theme-scoped group — the theme's own primary followed by the presets —
39
+ * instead of splitting additional presets and the theme pair's accent slots
40
+ * into labelled groups of their own. A stored theme-accent id still resolves
41
+ * (`resolveAccentPreset`) and is still described by the row; it is just no
42
+ * longer offered as a swatch, and a host can stop feeding this list.
43
+ */
44
+ themeAccentOptions?: readonly AccentOption[]
41
45
  resolvedAppearance: 'light' | 'dark'
42
46
  themeDefaultColor: string
43
47
  }
44
48
 
49
+ /**
50
+ * The accent choices, as ONE group: the theme's own primary first, then every
51
+ * preset the host feeds, each painted with its value for the resolved
52
+ * appearance — which is what makes the group theme-scoped rather than a
53
+ * catalogue table. The custom-color entry is the host's (`AccentChoices`
54
+ * renders it beside this grid), because whether a free-form colour is accepted
55
+ * is the host's validation to own.
56
+ */
45
57
  export function AccentSwatchGroups(props: AccentSwatchGroupsProps) {
46
- const primaryAccents = () =>
47
- PRIMARY_ACCENT_IDS.flatMap((id) => {
48
- const option = props.accentOptions.find((candidate) => candidate.id === id)
49
- return option ? [option] : []
50
- })
51
- const additionalAccents = () =>
52
- props.accentOptions.filter(
53
- (option) => option.id !== 'theme' && !primaryAccentIds.has(option.id)
54
- )
58
+ const presets = () => props.accentOptions.filter((option) => option.id !== 'theme')
55
59
 
56
60
  return (
57
- <>
58
- <div class="grid grid-cols-3 gap-2" data-primary-accent-grid>
59
- <AccentSwatch
60
- id="theme"
61
- label="Theme default"
62
- color={props.themeDefaultColor}
63
- group="primary"
64
- />
65
- <For each={primaryAccents()}>
66
- {(option) => (
67
- <AccentSwatch
68
- id={option.id}
69
- label={option.label}
70
- color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
71
- group="primary"
72
- />
73
- )}
74
- </For>
75
- </div>
76
- <Show when={additionalAccents().length > 0}>
77
- <div class="flex flex-col gap-1">
78
- <span class="text-xs font-medium text-muted-foreground">Additional colors</span>
79
- <div class="flex flex-wrap gap-2">
80
- <For each={additionalAccents()}>
81
- {(option) => (
82
- <AccentSwatch
83
- id={option.id}
84
- label={option.label}
85
- color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
86
- group="additional"
87
- />
88
- )}
89
- </For>
90
- </div>
91
- </div>
92
- </Show>
93
- <Show when={props.themeAccentOptions.length > 0}>
94
- <div class="flex flex-col gap-1">
95
- <span class="text-xs font-medium text-muted-foreground">Theme accents</span>
96
- <div class="grid grid-cols-3 gap-2">
97
- <For each={props.themeAccentOptions}>
98
- {(option) => (
99
- <AccentSwatch
100
- id={option.id}
101
- label={'Theme ' + option.label.toLowerCase()}
102
- color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
103
- group="theme"
104
- dashed
105
- />
106
- )}
107
- </For>
108
- </div>
109
- </div>
110
- </Show>
111
- </>
61
+ <div class="grid grid-cols-4 gap-2" data-accent-grid>
62
+ <AccentSwatch id="theme" label="Theme default" color={props.themeDefaultColor} />
63
+ <For each={presets()}>
64
+ {(option) => (
65
+ <AccentSwatch
66
+ id={option.id}
67
+ label={option.label}
68
+ color={(props.resolvedAppearance === 'light' ? option.light : option.dark) ?? ''}
69
+ />
70
+ )}
71
+ </For>
72
+ </div>
112
73
  )
113
74
  }
114
75
 
115
- function AccentSwatch(props: {
116
- id: string
117
- label: string
118
- color: string
119
- group: 'primary' | 'additional' | 'theme'
120
- dashed?: boolean
121
- }) {
76
+ function AccentSwatch(props: { id: string; label: string; color: string }) {
122
77
  return (
123
78
  <Radio.Item
124
79
  value={props.id}
125
80
  data-accent-option={props.id}
126
- data-primary-accent={props.group === 'primary' ? props.id : undefined}
127
- data-additional-accent={props.group === 'additional' ? props.id : undefined}
128
- data-theme-accent={props.group === 'theme' ? props.id : undefined}
129
81
  class="rounded-full focus-within:ring-3 focus-within:ring-ring/50"
130
82
  >
131
83
  <Radio.ItemInput />
132
- <Radio.ItemLabel
133
- class={cn(
134
- 'block size-7 cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary',
135
- { 'border-dashed data-[checked]:border-solid': props.dashed }
136
- )}
137
- >
84
+ <Radio.ItemLabel class="block size-7 cursor-pointer rounded-full border p-0.5 data-[checked]:border-primary data-[checked]:ring-1 data-[checked]:ring-primary">
138
85
  <span
139
86
  class="block size-full rounded-full"
140
87
  aria-hidden="true"
@@ -104,8 +104,6 @@ export function AccentChoices(props: AppearanceEditorProps) {
104
104
  // user will see it.
105
105
  const resolvedAppearance = () =>
106
106
  props.draft.mode === 'system' ? props.resolvedAppearance : props.draft.mode
107
- // The accents the previewed theme pair carries, offered after the presets.
108
- const themeAccents = () => props.themeAccentOptions ?? []
109
107
  const accentSelection = () => (isCustomAccent(props) ? 'custom' : props.draft.accent)
110
108
  return (
111
109
  <Radio
@@ -122,7 +120,6 @@ export function AccentChoices(props: AppearanceEditorProps) {
122
120
  >
123
121
  <AccentSwatchGroups
124
122
  accentOptions={props.accentOptions}
125
- themeAccentOptions={themeAccents()}
126
123
  resolvedAppearance={resolvedAppearance()}
127
124
  themeDefaultColor={
128
125
  resolvedAppearance() === 'light'
@@ -11,7 +11,6 @@ import {
11
11
  DropdownMenuTrigger,
12
12
  } from '../../ui/dropdown-menu/dropdown-menu'
13
13
  import { InputControl } from '../../ui/input/input-control'
14
- import { SettingsRow } from './appearance-rows'
15
14
  import {
16
15
  APPEARANCE_EDITOR_FONT_SIZE_MAX,
17
16
  APPEARANCE_EDITOR_FONT_SIZE_MIN,
@@ -142,7 +141,7 @@ function FontFamilyMenu(props: {
142
141
  size="sm"
143
142
  aria-label={`${props.label} font family`}
144
143
  disabled={props.disabled}
145
- class="w-40 max-w-full justify-between"
144
+ class="w-32 max-w-full justify-between"
146
145
  >
147
146
  <span class="truncate">{selectedLabel()}</span>
148
147
  <ChevronDown aria-hidden="true" class="ms-2 size-4 shrink-0 text-muted-foreground" />
@@ -298,8 +297,22 @@ export function AppearanceFontSettingsGroup(props: AppearanceFontSettingsGroupPr
298
297
  )
299
298
  }
300
299
  return (
301
- <SettingsRow title={row.label} icon={<Icon />} description={row.description}>
302
- <div class="flex min-w-0 max-w-full flex-wrap items-center gap-2">
300
+ <section class="flex items-center gap-3 px-4 py-4" data-font-settings-row={row.axis}>
301
+ <span
302
+ class="flex size-9 shrink-0 items-center justify-center rounded-lg border bg-foreground/5 text-muted-foreground [&_svg]:size-4"
303
+ aria-hidden="true"
304
+ >
305
+ <Icon />
306
+ </span>
307
+ {/* One line, always: the copy truncates rather than wrapping the
308
+ controls to a second line, so the family menu, the size field
309
+ and the title/subtitle stay aligned. The compact widths keep
310
+ that true at the appearance sheet's own width. */}
311
+ <div class="min-w-0 flex-1">
312
+ <h3 class="text-sm font-medium">{row.label}</h3>
313
+ <div class="mt-0.5 truncate text-xs text-muted-foreground">{row.description}</div>
314
+ </div>
315
+ <div class="flex shrink-0 items-center gap-2">
303
316
  <FontFamilyMenu
304
317
  label={row.label}
305
318
  family={value().family}
@@ -307,7 +320,7 @@ export function AppearanceFontSettingsGroup(props: AppearanceFontSettingsGroupPr
307
320
  disabled={props.disabled}
308
321
  onSelect={(family) => updateAxis(row.axis, { family })}
309
322
  />
310
- <div class="flex shrink-0 items-center gap-1">
323
+ <div class="flex items-center gap-1">
311
324
  <InputControl
312
325
  type="number"
313
326
  min={APPEARANCE_EDITOR_FONT_SIZE_MIN}
@@ -318,7 +331,7 @@ export function AppearanceFontSettingsGroup(props: AppearanceFontSettingsGroupPr
318
331
  aria-label={`${row.label} font size in pixels`}
319
332
  aria-describedby={sizeHintId}
320
333
  aria-invalid={sizeIsInvalid()}
321
- class="w-16"
334
+ class="w-12"
322
335
  onInput={(event) =>
323
336
  setSizeDrafts((current) => ({
324
337
  ...current,
@@ -341,7 +354,7 @@ export function AppearanceFontSettingsGroup(props: AppearanceFontSettingsGroupPr
341
354
  {APPEARANCE_EDITOR_FONT_SIZE_MAX} pixels.
342
355
  </span>
343
356
  </div>
344
- </SettingsRow>
357
+ </section>
345
358
  )
346
359
  }}
347
360
  </For>
@@ -118,7 +118,6 @@ export function AppearancePanel(props: AppearancePanelProps) {
118
118
  >
119
119
  <AccentSwatchGroups
120
120
  accentOptions={accentPresets}
121
- themeAccentOptions={themeAccents()}
122
121
  resolvedAppearance={resolvedAppearance()}
123
122
  themeDefaultColor="var(--primary)"
124
123
  />
@@ -6,10 +6,10 @@ import {
6
6
  import type { ComponentProps } from 'solid-js'
7
7
  import { createEffect, createSignal, splitProps } from 'solid-js'
8
8
  import {
9
+ dialogSurface,
9
10
  overlayMotion,
10
11
  overlayPositioner,
11
12
  overlayScrim,
12
- overlaySurface,
13
13
  overlayTitle,
14
14
  } from '../../../lib/overlay'
15
15
  import { cn } from '../../../lib/utils'
@@ -89,7 +89,7 @@ export function AlertDialogContent(props: ComponentProps<typeof KobalteAlertDial
89
89
  <div class={overlayPositioner}>
90
90
  <KobalteAlertDialogContent
91
91
  {...blockDismissal}
92
- class={cn(overlaySurface, overlayMotion, 'grid w-full max-w-md gap-4 p-5', local.class)}
92
+ class={cn(dialogSurface, overlayMotion, 'grid w-full max-w-md gap-4 p-5', local.class)}
93
93
  {...rest}
94
94
  />
95
95
  </div>
@@ -133,7 +133,9 @@ export function ComboboxItem(props: ComponentProps<typeof KobalteCombobox.Item>)
133
133
  return (
134
134
  <KobalteCombobox.Item class={cn(menuItem, 'pe-8', local.class)} {...rest}>
135
135
  <KobalteCombobox.ItemLabel>{local.children}</KobalteCombobox.ItemLabel>
136
- <KobalteCombobox.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
136
+ {/* The indicator reads in the accent, like every other selected state in
137
+ the system. */}
138
+ <KobalteCombobox.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
137
139
  <Check class="size-4" />
138
140
  </KobalteCombobox.ItemIndicator>
139
141
  </KobalteCombobox.Item>
@@ -109,7 +109,9 @@ export function ContextMenuCheckboxItem(
109
109
  return (
110
110
  <KobalteContextMenu.CheckboxItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
111
111
  {local.children}
112
- <KobalteContextMenu.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
112
+ {/* The indicator reads in the accent, like every other selected state in
113
+ the system. */}
114
+ <KobalteContextMenu.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
113
115
  <Check class="size-4" />
114
116
  </KobalteContextMenu.ItemIndicator>
115
117
  </KobalteContextMenu.CheckboxItem>
@@ -126,7 +128,9 @@ export function ContextMenuRadioItem(props: ComponentProps<typeof KobalteContext
126
128
  return (
127
129
  <KobalteContextMenu.RadioItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
128
130
  {local.children}
129
- <KobalteContextMenu.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
131
+ {/* The indicator reads in the accent, like every other selected state in
132
+ the system. */}
133
+ <KobalteContextMenu.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
130
134
  <Circle class="size-2 fill-current" />
131
135
  </KobalteContextMenu.ItemIndicator>
132
136
  </KobalteContextMenu.RadioItem>
@@ -8,10 +8,10 @@ import { X } from 'lucide-solid'
8
8
  import type { Accessor, ComponentProps, JSX } from 'solid-js'
9
9
  import { createRenderEffect, onCleanup, Show, splitProps } from 'solid-js'
10
10
  import {
11
+ dialogSurface,
11
12
  overlayMotion,
12
13
  overlayPositioner,
13
14
  overlayScrim,
14
- overlaySurface,
15
15
  overlayTitle,
16
16
  } from '../../../lib/overlay'
17
17
  import { cn } from '../../../lib/utils'
@@ -282,7 +282,7 @@ export function DialogContent(props: DialogContentProps) {
282
282
  <div class={cn(overlayPositioner, local.positioner === 'inset' && 'inset-4 grid-rows-1 p-0')}>
283
283
  <KobalteDialogContent
284
284
  class={cn(
285
- overlaySurface,
285
+ dialogSurface,
286
286
  overlayMotion,
287
287
  'relative grid w-full max-w-lg gap-4 p-5',
288
288
  local.class
@@ -69,7 +69,7 @@ export function DrawerContent(props: DrawerContentProps) {
69
69
  <DrawerOverlay />
70
70
  <DrawerPrimitive.Content
71
71
  class={cn(
72
- 'group/drawer bg-popover text-popover-foreground fixed z-(--z-drawer) flex flex-col border-border shadow-lg',
72
+ 'group/drawer bg-background text-foreground fixed z-(--z-drawer) flex flex-col border-border shadow-lg',
73
73
  'data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:max-h-[85vh] data-[side=bottom]:rounded-t-xl data-[side=bottom]:border-t',
74
74
  'data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:max-h-[85vh] data-[side=top]:rounded-b-xl data-[side=top]:border-b',
75
75
  'data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:w-80 data-[side=left]:rounded-e-xl data-[side=left]:border-e',
@@ -1,12 +1,14 @@
1
1
  import { DropdownMenu as KobalteDropdownMenu } from '@kobalte/core/dropdown-menu'
2
2
  import { Check, ChevronRight, Circle } from 'lucide-solid'
3
3
  import type { Accessor, ComponentProps } from 'solid-js'
4
- import { createContext, splitProps, useContext } from 'solid-js'
4
+ import { createContext, Show, splitProps, useContext } from 'solid-js'
5
5
  import {
6
6
  menuContentPadding,
7
7
  destructiveMenuItem,
8
8
  menuItem,
9
9
  menuLabel,
10
+ menuSwatchTone,
11
+ type MenuSwatchTone,
10
12
  menuSeparator,
11
13
  overlayMotion,
12
14
  overlaySurface,
@@ -192,6 +194,13 @@ export function DropdownMenuPortal(props: ComponentProps<typeof KobalteDropdownM
192
194
  }
193
195
 
194
196
  export type DropdownMenuContentProps = ComponentProps<typeof KobalteDropdownMenu.Content> & {
197
+ /**
198
+ * Kept for callers that hid the arrow explicitly; the arrow is now hidden by
199
+ * default. Pass `false` to draw one. The default flipped because Kobalte
200
+ * reserves half of the arrow's 30px box as popper gutter — a menu anchored to
201
+ * its trigger floated 15px off it, which read as a gap rather than as a
202
+ * pointer, and every anchored caller already passed `hideArrow`.
203
+ */
195
204
  hideArrow?: boolean
196
205
  /** Mount under an owner element such as a modal, keeping the menu in its accessible subtree. */
197
206
  portalMount?: HTMLElement
@@ -213,7 +222,12 @@ export function DropdownMenuContent(props: DropdownMenuContentProps) {
213
222
  )}
214
223
  {...rest}
215
224
  >
216
- {!local.hideArrow && <KobalteDropdownMenu.Arrow aria-hidden="true" class={popoverArrow} />}
225
+ {local.hideArrow === false && (
226
+ /* Rendered only when a caller asks for it back: the popper folds half
227
+ the arrow's box into the content's gutter, so an arrow and a flush
228
+ menu have never been true at once. */
229
+ <KobalteDropdownMenu.Arrow aria-hidden="true" class={popoverArrow} />
230
+ )}
217
231
  {local.children}
218
232
  </KobalteDropdownMenu.Content>
219
233
  </KobalteDropdownMenu.Portal>
@@ -233,6 +247,10 @@ export function DropdownMenuItem(
233
247
  * whenever `shortcut` is drawn.
234
248
  */
235
249
  keyshortcuts?: string
250
+ /** Draw a leading colour dot from the shared tone ladder — the accent or
251
+ * status role the option's card badge carries. `aria-hidden`; the label
252
+ * carries the meaning. */
253
+ swatch?: MenuSwatchTone
236
254
  }
237
255
  ) {
238
256
  const [local, rest] = splitProps(props, [
@@ -240,6 +258,7 @@ export function DropdownMenuItem(
240
258
  'variant',
241
259
  'shortcut',
242
260
  'keyshortcuts',
261
+ 'swatch',
243
262
  'children',
244
263
  ])
245
264
 
@@ -255,6 +274,9 @@ export function DropdownMenuItem(
255
274
  aria-keyshortcuts={local.keyshortcuts}
256
275
  {...rest}
257
276
  >
277
+ <Show when={local.swatch}>
278
+ <span aria-hidden="true" class={menuSwatchTone({ tone: local.swatch })} />
279
+ </Show>
258
280
  {local.children}
259
281
  {local.shortcut ? (
260
282
  <span
@@ -292,12 +314,19 @@ export function DropdownMenuShortcut(props: ComponentProps<'span'>) {
292
314
  }
293
315
 
294
316
  export function DropdownMenuCheckboxItem(
295
- props: ComponentProps<typeof KobalteDropdownMenu.CheckboxItem>
317
+ props: ComponentProps<typeof KobalteDropdownMenu.CheckboxItem> & {
318
+ /** Draw a leading colour dot from the shared tone ladder. `aria-hidden`;
319
+ * the label carries the meaning. */
320
+ swatch?: MenuSwatchTone
321
+ }
296
322
  ) {
297
- const [local, rest] = splitProps(props, ['class', 'children'])
323
+ const [local, rest] = splitProps(props, ['class', 'swatch', 'children'])
298
324
 
299
325
  return (
300
326
  <KobalteDropdownMenu.CheckboxItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
327
+ <Show when={local.swatch}>
328
+ <span aria-hidden="true" class={menuSwatchTone({ tone: local.swatch })} />
329
+ </Show>
301
330
  {local.children}
302
331
  <KobalteDropdownMenu.ItemIndicator
303
332
  data-slot="dropdown-menu-indicator"
@@ -315,11 +344,20 @@ export function DropdownMenuRadioGroup(
315
344
  return <KobalteDropdownMenu.RadioGroup {...props} />
316
345
  }
317
346
 
318
- export function DropdownMenuRadioItem(props: ComponentProps<typeof KobalteDropdownMenu.RadioItem>) {
319
- const [local, rest] = splitProps(props, ['class', 'children'])
347
+ export function DropdownMenuRadioItem(
348
+ props: ComponentProps<typeof KobalteDropdownMenu.RadioItem> & {
349
+ /** Draw a leading colour dot from the shared tone ladder. `aria-hidden`;
350
+ * the label carries the meaning. */
351
+ swatch?: MenuSwatchTone
352
+ }
353
+ ) {
354
+ const [local, rest] = splitProps(props, ['class', 'swatch', 'children'])
320
355
 
321
356
  return (
322
357
  <KobalteDropdownMenu.RadioItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
358
+ <Show when={local.swatch}>
359
+ <span aria-hidden="true" class={menuSwatchTone({ tone: local.swatch })} />
360
+ </Show>
323
361
  {local.children}
324
362
  {/* The indicator reads in the accent, like every other selected state in
325
363
  the system — a canvas-colored dot on a checked row reads as decoration. */}
@@ -16,3 +16,4 @@ export {
16
16
  DropdownMenuTrigger,
17
17
  type DropdownMenuContentProps,
18
18
  } from './dropdown-menu'
19
+ export type { MenuSwatchTone } from '../../../lib/overlay'
@@ -139,7 +139,9 @@ export function MenubarCheckboxItem(props: ComponentProps<typeof KobalteMenubar.
139
139
  return (
140
140
  <KobalteMenubar.CheckboxItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
141
141
  {local.children}
142
- <KobalteMenubar.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
142
+ {/* The indicator reads in the accent, like every other selected state in
143
+ the system. */}
144
+ <KobalteMenubar.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
143
145
  <Check class="size-4" />
144
146
  </KobalteMenubar.ItemIndicator>
145
147
  </KobalteMenubar.CheckboxItem>
@@ -155,7 +157,9 @@ export function MenubarRadioItem(props: ComponentProps<typeof KobalteMenubar.Rad
155
157
  return (
156
158
  <KobalteMenubar.RadioItem class={cn(menuItem, 'pe-8', local.class)} {...rest}>
157
159
  {local.children}
158
- <KobalteMenubar.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
160
+ {/* The indicator reads in the accent, like every other selected state in
161
+ the system. */}
162
+ <KobalteMenubar.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
159
163
  <Circle class="size-2 fill-current" />
160
164
  </KobalteMenubar.ItemIndicator>
161
165
  </KobalteMenubar.RadioItem>
@@ -9,3 +9,4 @@ export {
9
9
  SelectValue,
10
10
  type SelectTriggerProps,
11
11
  } from './select'
12
+ export type { MenuSwatchTone } from '../../../lib/overlay'
@@ -2,7 +2,13 @@ import { Select as KobalteSelect } from '@kobalte/core/select'
2
2
  import { Check, ChevronDown, ChevronsUpDown } from 'lucide-solid'
3
3
  import type { ComponentProps } from 'solid-js'
4
4
  import { Show, splitProps } from 'solid-js'
5
- import { menuContentPadding, menuItem, popoverArrow, topLayerProps } from '../../../lib/overlay'
5
+ import {
6
+ menuContentPadding,
7
+ menuItem,
8
+ menuSwatchTone,
9
+ type MenuSwatchTone,
10
+ topLayerProps,
11
+ } from '../../../lib/overlay'
6
12
  import { cn } from '../../../lib/utils'
7
13
 
8
14
  /**
@@ -21,7 +27,12 @@ import { cn } from '../../../lib/utils'
21
27
  export function Select<Option, OptGroup = never>(
22
28
  props: ComponentProps<typeof KobalteSelect<Option, OptGroup>>
23
29
  ) {
24
- return <KobalteSelect {...props} />
30
+ // Kobalte's own default gutter is 8px; without the arrow (removed below) the
31
+ // popper no longer folds half an arrow box into that offset, and 8px read as
32
+ // a detached list. Four pixels is shadcn's `sideOffset` — attached, with
33
+ // room for the trigger's own border.
34
+ const [local, rest] = splitProps(props, ['gutter'])
35
+ return <KobalteSelect gutter={local.gutter ?? 4} {...rest} />
25
36
  }
26
37
 
27
38
  export type SelectTriggerProps = ComponentProps<typeof KobalteSelect.Trigger> & {
@@ -153,20 +164,34 @@ export function SelectContent(props: SelectContentProps) {
153
164
  {...rest}
154
165
  >
155
166
  {local.children}
167
+ {/* No arrow: the list is the trigger's own value opened up, and Kobalte
168
+ reserves half the arrow's 30px box as popper gutter, which is where
169
+ the reported gap between a form trigger and its options came from. */}
156
170
  <KobalteSelect.Listbox class="flex flex-col" />
157
- <KobalteSelect.Arrow aria-hidden="true" class={popoverArrow} />
158
171
  </KobalteSelect.Content>
159
172
  </KobalteSelect.Portal>
160
173
  )
161
174
  }
162
175
 
163
- export function SelectItem(props: ComponentProps<typeof KobalteSelect.Item>) {
164
- const [local, rest] = splitProps(props, ['class', 'children'])
176
+ export function SelectItem(
177
+ props: ComponentProps<typeof KobalteSelect.Item> & {
178
+ /** Draw a leading colour dot from the shared tone ladder — the accent or
179
+ * status role the option's card badge carries. `aria-hidden`; the label
180
+ * carries the meaning. */
181
+ swatch?: MenuSwatchTone
182
+ }
183
+ ) {
184
+ const [local, rest] = splitProps(props, ['class', 'children', 'swatch'])
165
185
 
166
186
  return (
167
187
  <KobalteSelect.Item class={cn(menuItem, 'pe-8', local.class)} {...rest}>
188
+ <Show when={local.swatch}>
189
+ <span aria-hidden="true" class={menuSwatchTone({ tone: local.swatch })} />
190
+ </Show>
168
191
  <KobalteSelect.ItemLabel>{local.children}</KobalteSelect.ItemLabel>
169
- <KobalteSelect.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center">
192
+ {/* The indicator reads in the accent, like every other selected state in
193
+ the system — the row's own foreground reads as decoration. */}
194
+ <KobalteSelect.ItemIndicator class="absolute end-2 flex size-4 items-center justify-center text-primary">
170
195
  <Check class="size-4" />
171
196
  </KobalteSelect.ItemIndicator>
172
197
  </KobalteSelect.Item>
@@ -46,7 +46,7 @@ import { createDialogFocusRestoration, DialogOverlay } from '../dialog/dialog'
46
46
  // scrolled programmatically (focus, scrollIntoView, scrollTop), which slid the
47
47
  // pinned footer out of view. Only SheetBody scrolls.
48
48
  const sheetVariants = cva(
49
- 'bg-popover text-popover-foreground fixed z-(--z-dialog) flex flex-col overflow-clip border-border shadow-lg',
49
+ 'bg-background text-foreground fixed z-(--z-dialog) flex flex-col overflow-clip border-border shadow-lg',
50
50
  {
51
51
  variants: {
52
52
  side: {