@adea-ai/ui 0.99.2 → 0.99.4

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 (75) hide show
  1. package/dist/components/composites/workspace-mark/workspace-mark.d.ts.map +1 -1
  2. package/dist/components/composites/workspace-mark/workspace-mark.js +2 -2
  3. package/dist/components/composites/workspace-mark/workspace-mark.js.map +1 -1
  4. package/dist/components/conversation/message-row.d.ts.map +1 -1
  5. package/dist/components/conversation/message-row.js +2 -2
  6. package/dist/components/conversation/message-row.js.map +1 -1
  7. package/dist/components/conversation/thread-panel.d.ts.map +1 -1
  8. package/dist/components/conversation/thread-panel.js +1 -1
  9. package/dist/components/conversation/thread-panel.js.map +1 -1
  10. package/dist/components/ui/badge/badge.d.ts +1 -1
  11. package/dist/components/ui/badge/badge.d.ts.map +1 -1
  12. package/dist/components/ui/badge/badge.js +8 -1
  13. package/dist/components/ui/badge/badge.js.map +1 -1
  14. package/dist/components/ui/context-menu/context-menu.d.ts +8 -0
  15. package/dist/components/ui/context-menu/context-menu.d.ts.map +1 -1
  16. package/dist/components/ui/context-menu/context-menu.js +8 -0
  17. package/dist/components/ui/context-menu/context-menu.js.map +1 -1
  18. package/dist/components/ui/drawer/drawer.d.ts +8 -1
  19. package/dist/components/ui/drawer/drawer.d.ts.map +1 -1
  20. package/dist/components/ui/drawer/drawer.js.map +1 -1
  21. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +8 -0
  22. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  23. package/dist/components/ui/dropdown-menu/dropdown-menu.js +8 -0
  24. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  25. package/dist/components/ui/menubar/menubar.d.ts +8 -0
  26. package/dist/components/ui/menubar/menubar.d.ts.map +1 -1
  27. package/dist/components/ui/menubar/menubar.js +8 -0
  28. package/dist/components/ui/menubar/menubar.js.map +1 -1
  29. package/dist/components/ui/navigation-menu/navigation-menu.d.ts +14 -2
  30. package/dist/components/ui/navigation-menu/navigation-menu.d.ts.map +1 -1
  31. package/dist/components/ui/navigation-menu/navigation-menu.js +28 -23
  32. package/dist/components/ui/navigation-menu/navigation-menu.js.map +1 -1
  33. package/dist/components/ui/tabs/tabs.d.ts +6 -0
  34. package/dist/components/ui/tabs/tabs.d.ts.map +1 -1
  35. package/dist/components/ui/tabs/tabs.js +7 -1
  36. package/dist/components/ui/tabs/tabs.js.map +1 -1
  37. package/dist/components/ui/toast/toast.d.ts.map +1 -1
  38. package/dist/components/ui/toast/toast.js +19 -6
  39. package/dist/components/ui/toast/toast.js.map +1 -1
  40. package/dist/components/ui/tooltip/tooltip.d.ts.map +1 -1
  41. package/dist/components/ui/tooltip/tooltip.js +1 -0
  42. package/dist/components/ui/tooltip/tooltip.js.map +1 -1
  43. package/dist/lib/version-notes.d.ts +6 -0
  44. package/dist/lib/version-notes.d.ts.map +1 -1
  45. package/dist/lib/version-notes.js +9 -1
  46. package/dist/lib/version-notes.js.map +1 -1
  47. package/dist/r/src/components/composites/workspace-mark/workspace-mark.tsx +13 -2
  48. package/dist/r/src/components/conversation/message-row.tsx +6 -1
  49. package/dist/r/src/components/conversation/thread-panel.tsx +4 -1
  50. package/dist/r/src/components/ui/badge/badge.tsx +7 -0
  51. package/dist/r/src/components/ui/context-menu/context-menu.tsx +8 -0
  52. package/dist/r/src/components/ui/drawer/drawer.tsx +8 -1
  53. package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +8 -0
  54. package/dist/r/src/components/ui/menubar/menubar.tsx +8 -0
  55. package/dist/r/src/components/ui/navigation-menu/navigation-menu.tsx +42 -28
  56. package/dist/r/src/components/ui/tabs/tabs.tsx +7 -1
  57. package/dist/r/src/components/ui/toast/toast.tsx +21 -6
  58. package/dist/r/src/components/ui/tooltip/tooltip.tsx +3 -0
  59. package/dist/r/src/lib/version-notes.ts +8 -0
  60. package/dist/r/src/styles/base.css +13 -0
  61. package/package.json +1 -1
  62. package/src/components/composites/workspace-mark/workspace-mark.tsx +13 -2
  63. package/src/components/conversation/message-row.tsx +6 -1
  64. package/src/components/conversation/thread-panel.tsx +4 -1
  65. package/src/components/ui/badge/badge.tsx +7 -0
  66. package/src/components/ui/context-menu/context-menu.tsx +8 -0
  67. package/src/components/ui/drawer/drawer.tsx +8 -1
  68. package/src/components/ui/dropdown-menu/dropdown-menu.tsx +8 -0
  69. package/src/components/ui/menubar/menubar.tsx +8 -0
  70. package/src/components/ui/navigation-menu/navigation-menu.tsx +42 -28
  71. package/src/components/ui/tabs/tabs.tsx +7 -1
  72. package/src/components/ui/toast/toast.tsx +21 -6
  73. package/src/components/ui/tooltip/tooltip.tsx +3 -0
  74. package/src/lib/version-notes.ts +8 -0
  75. package/src/styles/base.css +13 -0
@@ -86,8 +86,11 @@ export function ThreadPanel(props: ThreadPanelProps) {
86
86
  <div class="bg-muted/40 shrink-0 border-b border-border px-3 py-2">{local.root}</div>
87
87
  </Show>
88
88
 
89
+ {/* The replies carry their own inline padding: a row brings only `px-1`, so
90
+ a bubble at its widest otherwise meets the panel's edge. `px-2` plus the
91
+ row's `px-1` lands on the `px-3` line the header and root use. */}
89
92
  <div
90
- class="min-h-0 flex-1 overflow-y-auto overscroll-contain"
93
+ class="min-h-0 flex-1 overflow-y-auto overscroll-contain px-2 py-2"
91
94
  role="region"
92
95
  aria-label="Thread replies"
93
96
  tabindex="0"
@@ -25,6 +25,13 @@ export const badgeVariants = cva(
25
25
  destructive: 'bg-destructive-subtle text-foreground',
26
26
  info: 'bg-info-subtle text-foreground',
27
27
  subtle: 'bg-primary-subtle text-primary',
28
+ /**
29
+ * A count that asks for attention, pinned to a corner of another control
30
+ * (a workspace mark, a rail icon). At `sm` it is a 2xs label on whatever
31
+ * surface sits behind the corner, where the destructive tint all but
32
+ * disappears — so it takes the solid, contrast-measured action fill.
33
+ */
34
+ notification: 'bg-destructive-action text-destructive-action-foreground',
28
35
  },
29
36
  size: {
30
37
  sm: 'h-4 px-1.5 text-2xs',
@@ -131,6 +131,14 @@ export function ContextMenuRadioItem(props: ComponentProps<typeof KobalteContext
131
131
  )
132
132
  }
133
133
 
134
+ /**
135
+ * The caption of a `ContextMenuGroup`, and that group's accessible name. It must be a
136
+ * child of the group it names: Kobalte reads the group from context, so a label
137
+ * placed directly in the content throws `useMenuGroupContext must be used within
138
+ * a Menu.Group` the moment the menu opens. For an ungrouped caption, wrap the
139
+ * label and its items in a group anyway — the grouping is what a screen reader
140
+ * announces.
141
+ */
134
142
  export function ContextMenuLabel(props: ComponentProps<typeof KobalteContextMenu.GroupLabel>) {
135
143
  const [local, rest] = splitProps(props, ['class'])
136
144
  return <KobalteContextMenu.GroupLabel class={cn(menuLabel, local.class)} {...rest} />
@@ -41,7 +41,14 @@ export function DrawerOverlay(props: ComponentProps<typeof DrawerPrimitive.Overl
41
41
  )
42
42
  }
43
43
 
44
- export type DrawerContentProps = ComponentProps<typeof DrawerPrimitive.Content> & {
44
+ export type DrawerContentProps = Omit<ComponentProps<typeof DrawerPrimitive.Content>, 'side'> & {
45
+ /**
46
+ * Not accepted here. corvu reads the side from the root `Drawer`, which uses it
47
+ * for the drag axis and publishes it as `data-side`; a `side` on the content
48
+ * would type-check through the polymorphic props and be silently ignored,
49
+ * leaving the drawer on the bottom edge. Set `<Drawer side="right">` instead.
50
+ */
51
+ side?: never
45
52
  /**
46
53
  * Draw the grabber at the leading edge of the sheet.
47
54
  *
@@ -187,6 +187,14 @@ export function DropdownMenuRadioItem(props: ComponentProps<typeof KobalteDropdo
187
187
  )
188
188
  }
189
189
 
190
+ /**
191
+ * The caption of a `DropdownMenuGroup`, and that group's accessible name. It must be a
192
+ * child of the group it names: Kobalte reads the group from context, so a label
193
+ * placed directly in the content throws `useMenuGroupContext must be used within
194
+ * a Menu.Group` the moment the menu opens. For an ungrouped caption, wrap the
195
+ * label and its items in a group anyway — the grouping is what a screen reader
196
+ * announces.
197
+ */
190
198
  export function DropdownMenuLabel(props: ComponentProps<typeof KobalteDropdownMenu.GroupLabel>) {
191
199
  const [local, rest] = splitProps(props, ['class'])
192
200
  return <KobalteDropdownMenu.GroupLabel class={cn(menuLabel, local.class)} {...rest} />
@@ -160,6 +160,14 @@ export function MenubarRadioItem(props: ComponentProps<typeof KobalteMenubar.Rad
160
160
  )
161
161
  }
162
162
 
163
+ /**
164
+ * The caption of a `MenubarGroup`, and that group's accessible name. It must be a
165
+ * child of the group it names: Kobalte reads the group from context, so a label
166
+ * placed directly in the content throws `useMenuGroupContext must be used within
167
+ * a Menu.Group` the moment the menu opens. For an ungrouped caption, wrap the
168
+ * label and its items in a group anyway — the grouping is what a screen reader
169
+ * announces.
170
+ */
163
171
  export function MenubarLabel(props: ComponentProps<typeof KobalteMenubar.GroupLabel>) {
164
172
  const [local, rest] = splitProps(props, ['class'])
165
173
  return <KobalteMenubar.GroupLabel class={cn(menuLabel, local.class)} {...rest} />
@@ -41,9 +41,15 @@ import { menuContentPadding, menuItem, overlayMotion, overlaySurface } from '#li
41
41
  * - `Content` must be a direct child of `Menu`, and the `Viewport` is a **sibling
42
42
  * of the menus** — not inside them. All the panels share one viewport, which is
43
43
  * what lets the bar animate between them instead of each panel popping in place.
44
+ * - The viewport is an empty surface. Each `Content` reaches it through Kobalte's
45
+ * `Portal`, which mounts the panel inside the viewport while keeping it in its
46
+ * own `Menu`'s context. A `Content` rendered anywhere else — the viewport's own
47
+ * children included — has no `Menu` above it, and Kobalte throws
48
+ * `useMenuRootContext must be used within a MenuRoot` the moment a panel opens.
44
49
  *
45
- * The wrapper enforces the last of those by rendering the `Viewport` itself, so a
46
- * caller cannot forget it and get a menu whose panels never appear.
50
+ * The wrapper enforces the last two by rendering the `Viewport` itself and by
51
+ * portalling every `NavigationMenuContent`, so a caller cannot forget either and
52
+ * get a menu whose panels never appear.
47
53
  */
48
54
 
49
55
  export type NavigationMenuProps = ComponentProps<typeof KobalteNavigationMenu.Root> & {
@@ -112,25 +118,41 @@ export function NavigationMenuContent(props: ComponentProps<typeof KobalteNaviga
112
118
  const [local, rest] = splitProps(props, ['class', 'children'])
113
119
 
114
120
  return (
115
- <KobalteNavigationMenu.Content
116
- class={cn(
117
- 'grid w-max gap-1 p-2',
118
- // A two-column panel is the shape most menu bars want, and it is opt-in
119
- // through this hook rather than a prop because the column count is a
120
- // layout decision the caller's content makes.
121
- 'data-[wide]:grid-cols-2',
122
- local.class
123
- )}
124
- {...rest}
125
- >
126
- {local.children}
127
- </KobalteNavigationMenu.Content>
121
+ <KobalteNavigationMenu.Portal>
122
+ <KobalteNavigationMenu.Content
123
+ class={cn(
124
+ // Absolute so the viewport sizes to the active panel's measured box and
125
+ // animates between panels, rather than stacking them.
126
+ 'absolute top-0 left-0 grid w-max gap-1 p-2 outline-none',
127
+ // The motion is the panel's, not the viewport's. Kobalte keeps an
128
+ // outgoing panel mounted until the viewport's own animation ends; a
129
+ // viewport that carries an entrance animation never fires that again
130
+ // after it opens, so the previous panel would stay painted under the
131
+ // next one.
132
+ overlayMotion,
133
+ // A two-column panel is the shape most menu bars want, and it is opt-in
134
+ // through this hook rather than a prop because the column count is a
135
+ // layout decision the caller's content makes.
136
+ 'data-[wide]:grid-cols-2',
137
+ local.class
138
+ )}
139
+ {...rest}
140
+ >
141
+ {local.children}
142
+ </KobalteNavigationMenu.Content>
143
+ </KobalteNavigationMenu.Portal>
128
144
  )
129
145
  }
130
146
 
131
147
  /**
132
148
  * The shared panel surface. One per menu bar, and the wrapper supplies it — but
133
149
  * exported so a caller with an unusual layout can place it themselves.
150
+ *
151
+ * It renders no children: the panels arrive through each `NavigationMenuContent`'s
152
+ * portal. Kobalte positions it under the bar and publishes the active panel's size
153
+ * as `--kb-navigation-menu-viewport-*`, which the surface animates between.
154
+ * `box-content` keeps the border outside that measured size so a panel is never
155
+ * clipped by its own frame.
134
156
  */
135
157
  export function NavigationMenuViewport(
136
158
  props: ComponentProps<typeof KobalteNavigationMenu.Viewport>
@@ -139,24 +161,16 @@ export function NavigationMenuViewport(
139
161
 
140
162
  return (
141
163
  <KobalteNavigationMenu.Viewport
164
+ data-slot="navigation-menu-viewport"
142
165
  class={cn(
143
- 'absolute top-full left-0 isolate z-(--z-menu) mt-1.5 flex justify-center overflow-hidden',
166
+ overlaySurface,
167
+ 'isolate z-(--z-menu) mt-1.5 box-content list-none overflow-hidden',
144
168
  'h-(--kb-navigation-menu-viewport-height) w-(--kb-navigation-menu-viewport-width)',
145
- 'origin-top transition-[width,height] duration-200 ease-out',
169
+ 'origin-(--kb-menu-content-transform-origin) transition-[width,height] duration-200 ease-out',
146
170
  local.class
147
171
  )}
148
172
  {...rest}
149
- >
150
- <div
151
- class={cn(
152
- overlaySurface,
153
- overlayMotion,
154
- 'w-full rounded-lg border border-border bg-popover p-1 shadow-lg'
155
- )}
156
- >
157
- <KobalteNavigationMenu.Content />
158
- </div>
159
- </KobalteNavigationMenu.Viewport>
173
+ />
160
174
  )
161
175
  }
162
176
 
@@ -75,6 +75,12 @@ export type TabsListProps = ComponentProps<typeof KobalteTabs.List> & {
75
75
  appearance?: 'underline' | 'segmented'
76
76
  }
77
77
 
78
+ /**
79
+ * The underline appearance's rule is the baseline a horizontal row of tabs sits
80
+ * on. A vertical list has no baseline — its triggers stack — so the rule is
81
+ * dropped there; otherwise it draws as a stray line under the last trigger,
82
+ * spanning only the list's width (the SettingsLayout rail showed exactly that).
83
+ */
78
84
  export function TabsList(props: TabsListProps) {
79
85
  const [local, rest] = splitProps(props, ['class', 'appearance'])
80
86
 
@@ -84,7 +90,7 @@ export function TabsList(props: TabsListProps) {
84
90
  'inline-flex w-fit shrink-0 items-center justify-center',
85
91
  local.appearance === 'segmented'
86
92
  ? 'gap-0.5 rounded-lg bg-surface-hover p-0.5'
87
- : 'gap-1 rounded-none border-b border-border',
93
+ : 'gap-1 rounded-none border-b border-border data-[orientation=vertical]:border-b-0',
88
94
  'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',
89
95
  local.class
90
96
  )}
@@ -179,11 +179,23 @@ export type ToasterProps = ComponentProps<typeof KobalteToast.Region> & {
179
179
  region?: string
180
180
  }
181
181
 
182
+ /**
183
+ * The corner is set on the region, not the list. The region is the `fixed`
184
+ * element: an inset on the list inside it positions nothing, and the region falls
185
+ * back to wherever it happens to sit in the document flow.
186
+ */
182
187
  const toasterPosition = {
183
- 'top-left': 'top-0 left-0 items-start',
184
- 'top-right': 'top-0 right-0 items-end',
185
- 'bottom-left': 'bottom-0 left-0 items-start',
186
- 'bottom-right': 'bottom-0 right-0 items-end',
188
+ 'top-left': 'top-0 left-0',
189
+ 'top-right': 'top-0 right-0',
190
+ 'bottom-left': 'bottom-0 left-0',
191
+ 'bottom-right': 'bottom-0 right-0',
192
+ }
193
+
194
+ const toasterAlignment = {
195
+ 'top-left': 'items-start',
196
+ 'top-right': 'items-end',
197
+ 'bottom-left': 'items-start',
198
+ 'bottom-right': 'items-end',
187
199
  }
188
200
 
189
201
  /** Mount once, near the root. Renders the stack and owns its timing defaults. */
@@ -203,13 +215,16 @@ export function Toaster(props: ToasterProps) {
203
215
  * in-flight notification, and clicking a toast must not dismiss the
204
216
  * dialog behind it.
205
217
  */
206
- class="pointer-events-none fixed z-(--z-toast) flex max-h-screen w-full flex-col gap-2 p-4 sm:max-w-sm"
218
+ class={cn(
219
+ 'pointer-events-none fixed z-(--z-toast) flex max-h-screen w-full flex-col gap-2 p-4 sm:max-w-sm',
220
+ toasterPosition[local.position ?? 'bottom-right']
221
+ )}
207
222
  {...rest}
208
223
  >
209
224
  <KobalteToast.List
210
225
  class={cn(
211
226
  'flex flex-col gap-2',
212
- toasterPosition[local.position ?? 'bottom-right'],
227
+ toasterAlignment[local.position ?? 'bottom-right'],
213
228
  local.class
214
229
  )}
215
230
  />
@@ -367,6 +367,9 @@ export function TooltipContent(props: TooltipContentProps) {
367
367
  return (
368
368
  <KobalteTooltip.Portal>
369
369
  <KobalteTooltip.Content
370
+ /* The slot is what base.css's pointer-transparency rule keys on; every
371
+ tip carries it, so no consumer has to remember to pass it. */
372
+ data-slot="tooltip-content"
370
373
  class={cn(
371
374
  tooltipTip,
372
375
  // The max width is a token, not a fixed measure: it has to fall
@@ -34,15 +34,23 @@ export function plainTextFromMarkdown(markdown: string): string {
34
34
  * A release date, formatted for a reader. Returns the input when it cannot be
35
35
  * parsed — a date a build tool wrote in an unusual format is still better shown
36
36
  * verbatim than dropped.
37
+ *
38
+ * A date-only value (`2026-09-24`) is a calendar day, not an instant. `new Date`
39
+ * reads it as UTC midnight, and formatting that instant in the reader's zone
40
+ * moves it to the previous day anywhere west of UTC — so a date-only value is
41
+ * formatted in UTC, where its midnight still falls on the day it names. A full
42
+ * timestamp is a real instant and keeps the reader's zone.
37
43
  */
38
44
  export function formatReleaseDate(value: string | null): string | null {
39
45
  if (!value) return null
40
46
  const date = new Date(value)
41
47
  if (Number.isNaN(date.getTime())) return value
48
+ const dateOnly = /^\d{4}-\d{2}-\d{2}$/.test(value.trim())
42
49
  return new Intl.DateTimeFormat(undefined, {
43
50
  day: 'numeric',
44
51
  month: 'short',
45
52
  year: 'numeric',
53
+ ...(dateOnly ? { timeZone: 'UTC' } : {}),
46
54
  }).format(date)
47
55
  }
48
56
 
@@ -592,6 +592,19 @@
592
592
  color var(--duration-normal) var(--ease-out);
593
593
  }
594
594
 
595
+ /* A tooltip is informational: neither its popper positioner nor its content
596
+ may intercept the pointer and block the control the tooltip describes —
597
+ or a control beside it. The layer stack writes `pointer-events: auto`
598
+ inline on the active layer, so the content needs `!important` to stay out
599
+ of the pointer path. */
600
+ [data-popper-positioner]:has(> [data-slot='tooltip-content']) {
601
+ pointer-events: none;
602
+ }
603
+
604
+ [data-slot='tooltip-content'] {
605
+ pointer-events: none !important;
606
+ }
607
+
595
608
  /* Keyboard focus only. `:focus-visible` rather than `:focus` so a pointer
596
609
  click never paints a ring. */
597
610
  :focus-visible {