@adea-ai/ui 0.109.0 → 0.109.1

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 (48) hide show
  1. package/dist/components/composites/update-dialog/update-dialog.js +1 -1
  2. package/dist/components/layout/contextual-sidebar/contextual-sidebar.d.ts.map +1 -1
  3. package/dist/components/layout/contextual-sidebar/contextual-sidebar.js +45 -35
  4. package/dist/components/layout/contextual-sidebar/contextual-sidebar.js.map +1 -1
  5. package/dist/components/layout/contextual-sidebar/mobile-contextual-sidebar.d.ts +12 -0
  6. package/dist/components/layout/contextual-sidebar/mobile-contextual-sidebar.d.ts.map +1 -0
  7. package/dist/components/layout/contextual-sidebar/mobile-contextual-sidebar.js +36 -0
  8. package/dist/components/layout/contextual-sidebar/mobile-contextual-sidebar.js.map +1 -0
  9. package/dist/components/ui/alert-dialog/alert-dialog.d.ts.map +1 -1
  10. package/dist/components/ui/alert-dialog/alert-dialog.js +2 -6
  11. package/dist/components/ui/alert-dialog/alert-dialog.js.map +1 -1
  12. package/dist/components/ui/board/board.js +1 -1
  13. package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
  14. package/dist/components/ui/dialog/dialog.js +2 -6
  15. package/dist/components/ui/dialog/dialog.js.map +1 -1
  16. package/dist/components/ui/item/item.d.ts +1 -1
  17. package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
  18. package/dist/components/ui/sheet/sheet.js +2 -5
  19. package/dist/components/ui/sheet/sheet.js.map +1 -1
  20. package/dist/components/ui/typography/typography.d.ts.map +1 -1
  21. package/dist/components/ui/typography/typography.js +2 -2
  22. package/dist/components/ui/typography/typography.js.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/lib/overlay.d.ts +5 -0
  25. package/dist/lib/overlay.d.ts.map +1 -1
  26. package/dist/lib/overlay.js +6 -1
  27. package/dist/lib/overlay.js.map +1 -1
  28. package/dist/r/alert-dialog.json +0 -1
  29. package/dist/r/contextual-sidebar.json +5 -0
  30. package/dist/r/dialog.json +0 -1
  31. package/dist/r/registry.json +5 -3
  32. package/dist/r/sheet.json +0 -1
  33. package/dist/r/src/components/layout/contextual-sidebar/contextual-sidebar.tsx +41 -16
  34. package/dist/r/src/components/layout/contextual-sidebar/mobile-contextual-sidebar.tsx +28 -0
  35. package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +8 -8
  36. package/dist/r/src/components/ui/dialog/dialog.tsx +8 -8
  37. package/dist/r/src/components/ui/sheet/sheet.tsx +2 -7
  38. package/dist/r/src/components/ui/typography/typography.tsx +3 -2
  39. package/dist/r/src/lib/overlay.ts +6 -0
  40. package/package.json +1 -1
  41. package/registry.json +5 -3
  42. package/src/components/layout/contextual-sidebar/contextual-sidebar.tsx +41 -16
  43. package/src/components/layout/contextual-sidebar/mobile-contextual-sidebar.tsx +28 -0
  44. package/src/components/ui/alert-dialog/alert-dialog.tsx +8 -8
  45. package/src/components/ui/dialog/dialog.tsx +8 -8
  46. package/src/components/ui/sheet/sheet.tsx +2 -7
  47. package/src/components/ui/typography/typography.tsx +3 -2
  48. package/src/lib/overlay.ts +6 -0
@@ -1,7 +1,6 @@
1
1
  import type { Accessor, JSX } from 'solid-js'
2
2
  import { Show, createSignal, createUniqueId, onCleanup, onMount } from 'solid-js'
3
3
  import { cn } from '#lib/utils'
4
- import { Sheet, SheetContent, SheetTitle } from '../../ui/sheet'
5
4
  import {
6
5
  SidebarNav,
7
6
  SidebarNavContent,
@@ -11,6 +10,9 @@ import {
11
10
  } from '../sidebar-nav/sidebar-nav'
12
11
  import { PixelResizeHandle } from '../pixel-resize-handle/pixel-resize-handle'
13
12
 
13
+ type MobileModule = typeof import('./mobile-contextual-sidebar')
14
+ type MobileLoad = MobileModule | { error: unknown }
15
+
14
16
  export type ContextualSidebarRenderContext = {
15
17
  /** Whether the slot is being rendered inside the modal mobile sheet. */
16
18
  mobile: boolean
@@ -67,6 +69,22 @@ export type ContextualSidebarProps = {
67
69
  */
68
70
  export function ContextualSidebar(props: ContextualSidebarProps) {
69
71
  const [isNarrowViewport, setIsNarrowViewport] = createSignal(false)
72
+ const [mobileLoad, setMobileLoad] = createSignal<MobileLoad>()
73
+ let mobileRequested = false
74
+ // Keep the resolved component mounted across viewport changes for Sheet cleanup.
75
+ const loadMobile = () => {
76
+ if (mobileRequested) return
77
+ mobileRequested = true
78
+ // Native module caching shares successful loads without keeping a rejected promise.
79
+ void import('./mobile-contextual-sidebar').then(
80
+ (module) => {
81
+ if (mobileRequested) setMobileLoad(module)
82
+ },
83
+ (error: unknown) => {
84
+ if (mobileRequested) setMobileLoad({ error })
85
+ }
86
+ )
87
+ }
70
88
  const [mobileMount, setMobileMount] = createSignal<
71
89
  { element: HTMLElement; connected: boolean } | undefined
72
90
  >()
@@ -81,6 +99,7 @@ export function ContextualSidebar(props: ContextualSidebarProps) {
81
99
  const media = window.matchMedia('(max-width: 48rem)')
82
100
  const updateViewport = () => {
83
101
  const wasNarrow = isNarrowViewport()
102
+ if (media.matches) loadMobile()
84
103
  // Close before mounting a modal. A desktop-expanded host state is not
85
104
  // mobile intent, and opening the Sheet for one frame can steal focus.
86
105
  if (media.matches && !wasNarrow) props.onOpenChange(false)
@@ -90,10 +109,14 @@ export function ContextualSidebar(props: ContextualSidebarProps) {
90
109
  // A route can mount after a wide-loaded host crosses into mobile. Clear
91
110
  // that stale seed, but preserve a sidebar intentionally opened at a
92
111
  // narrow boot viewport.
112
+ if (media.matches) loadMobile()
93
113
  if (media.matches && props.wideViewportAtLoad && props.open) props.onOpenChange(false)
94
114
  setIsNarrowViewport(media.matches)
95
115
  media.addEventListener('change', updateViewport)
96
- onCleanup(() => media.removeEventListener('change', updateViewport))
116
+ onCleanup(() => {
117
+ mobileRequested = false
118
+ media.removeEventListener('change', updateViewport)
119
+ })
97
120
  })
98
121
 
99
122
  const renderSidebar = (mobile: boolean) => {
@@ -160,21 +183,23 @@ export function ContextualSidebar(props: ContextualSidebarProps) {
160
183
  }
161
184
 
162
185
  return (
163
- <Sheet
164
- open={isNarrowViewport() && props.open}
165
- onOpenChange={(open) => props.onOpenChange(open)}
166
- >
186
+ <>
167
187
  <Show when={!isNarrowViewport()}>{(_wide) => renderSidebar(false)}</Show>
168
- <Show when={isNarrowViewport()}>
169
- <SheetContent
170
- side="start"
171
- class={cn('gap-0 p-0', props.sheetClass)}
172
- restoreFocusRef={props.restoreFocusRef}
173
- >
174
- <SheetTitle class="sr-only">{props.title} navigation</SheetTitle>
175
- {renderSidebar(true)}
176
- </SheetContent>
188
+ <Show when={mobileLoad()} keyed>
189
+ {(loaded) => {
190
+ if ('error' in loaded) throw loaded.error
191
+ return (
192
+ <loaded.MobileSidebar
193
+ open={isNarrowViewport() && props.open}
194
+ onOpenChange={props.onOpenChange}
195
+ label={props.label}
196
+ sheetClass={props.sheetClass}
197
+ restoreFocusRef={props.restoreFocusRef}
198
+ renderSidebar={() => renderSidebar(true)}
199
+ />
200
+ )
201
+ }}
177
202
  </Show>
178
- </Sheet>
203
+ </>
179
204
  )
180
205
  }
@@ -0,0 +1,28 @@
1
+ import type { Accessor, JSX } from 'solid-js'
2
+ import { cn } from '#lib/utils'
3
+ import { Sheet, SheetContent } from '../../ui/sheet'
4
+
5
+ export type MobileContextualSidebarProps = {
6
+ open: boolean
7
+ onOpenChange(open: boolean): void
8
+ label: string
9
+ sheetClass?: string
10
+ restoreFocusRef?: Accessor<HTMLElement | undefined>
11
+ renderSidebar(): JSX.Element
12
+ }
13
+
14
+ /** Sheet wrappers are loaded only when a contextual sidebar enters mobile mode. */
15
+ export function MobileSidebar(props: MobileContextualSidebarProps) {
16
+ return (
17
+ <Sheet open={props.open} onOpenChange={props.onOpenChange}>
18
+ <SheetContent
19
+ side="start"
20
+ aria-label={props.label}
21
+ class={cn('gap-0 p-0', props.sheetClass)}
22
+ restoreFocusRef={props.restoreFocusRef}
23
+ >
24
+ {props.renderSidebar()}
25
+ </SheetContent>
26
+ </Sheet>
27
+ )
28
+ }
@@ -5,9 +5,14 @@ import {
5
5
  // Use the alert-specific export rather than DialogRoot.Content, which other imports can replace.
6
6
  import type { ComponentProps } from 'solid-js'
7
7
  import { createEffect, createSignal, splitProps } from 'solid-js'
8
- import { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'
8
+ import {
9
+ overlayMotion,
10
+ overlayPositioner,
11
+ overlayScrim,
12
+ overlaySurface,
13
+ overlayTitle,
14
+ } from '#lib/overlay'
9
15
  import { cn } from '#lib/utils'
10
- import { headingVariants } from '../typography'
11
16
 
12
17
  /**
13
18
  * AlertDialog.
@@ -116,12 +121,7 @@ export function AlertDialogFooter(props: ComponentProps<'div'>) {
116
121
 
117
122
  export function AlertDialogTitle(props: ComponentProps<typeof KobalteAlertDialog.Title>) {
118
123
  const [local, rest] = splitProps(props, ['class'])
119
- return (
120
- <KobalteAlertDialog.Title
121
- class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}
122
- {...rest}
123
- />
124
- )
124
+ return <KobalteAlertDialog.Title class={cn(overlayTitle, local.class)} {...rest} />
125
125
  }
126
126
 
127
127
  export function AlertDialogDescription(
@@ -7,9 +7,14 @@ import {
7
7
  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
- import { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '#lib/overlay'
10
+ import {
11
+ overlayMotion,
12
+ overlayPositioner,
13
+ overlayScrim,
14
+ overlaySurface,
15
+ overlayTitle,
16
+ } from '#lib/overlay'
11
17
  import { cn } from '#lib/utils'
12
- import { headingVariants } from '../typography'
13
18
 
14
19
  type FocusCycle = {
15
20
  content: HTMLElement
@@ -326,12 +331,7 @@ export function DialogFooter(props: ComponentProps<'div'>) {
326
331
 
327
332
  export function DialogTitle(props: ComponentProps<typeof KobalteDialog.Title>) {
328
333
  const [local, rest] = splitProps(props, ['class'])
329
- return (
330
- <KobalteDialog.Title
331
- class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}
332
- {...rest}
333
- />
334
- )
334
+ return <KobalteDialog.Title class={cn(overlayTitle, local.class)} {...rest} />
335
335
  }
336
336
 
337
337
  export function DialogDescription(props: ComponentProps<typeof KobalteDialog.Description>) {
@@ -8,9 +8,9 @@ import { X } from 'lucide-solid'
8
8
  import type { Accessor, ComponentProps, JSX } from 'solid-js'
9
9
  import { Show, splitProps } from 'solid-js'
10
10
  import { cva, type VariantProps } from '#lib/variants'
11
+ import { overlayTitle } from '#lib/overlay'
11
12
  import { cn } from '#lib/utils'
12
13
  import { createDialogFocusRestoration, DialogOverlay } from '../dialog/dialog'
13
- import { headingVariants } from '../typography'
14
14
 
15
15
  /**
16
16
  * Sheet.
@@ -215,12 +215,7 @@ export function SheetFooter(props: ComponentProps<'div'>) {
215
215
 
216
216
  export function SheetTitle(props: ComponentProps<typeof KobalteDialog.Title>) {
217
217
  const [local, rest] = splitProps(props, ['class'])
218
- return (
219
- <KobalteDialog.Title
220
- class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}
221
- {...rest}
222
- />
223
- )
218
+ return <KobalteDialog.Title class={cn(overlayTitle, local.class)} {...rest} />
224
219
  }
225
220
 
226
221
  export function SheetDescription(props: ComponentProps<typeof KobalteDialog.Description>) {
@@ -25,7 +25,8 @@ import { cn } from '#lib/utils'
25
25
  * stack already sets the rhythm (a card or dialog header), and is the only other
26
26
  * option.
27
27
  */
28
- export const headingVariants = cva('font-semibold', {
28
+ // cva only returns a closure. A heading-only consumer must discard Text's recipe.
29
+ export const headingVariants = /* @__PURE__ */ cva('font-semibold', {
29
30
  variants: {
30
31
  size: {
31
32
  /** 30px. An app-level headline — a first-run or empty-app screen. Once per app. */
@@ -130,7 +131,7 @@ export function Heading<T extends ValidComponent = 'h2'>(props: HeadingProps<T>)
130
131
  *
131
132
  * Defaults: `body` renders a `p`, `code` a `code`, every other variant a `span`.
132
133
  */
133
- export const textVariants = cva('', {
134
+ export const textVariants = /* @__PURE__ */ cva('', {
134
135
  variants: {
135
136
  variant: {
136
137
  /** 14px / 400. Body copy and descriptions. */
@@ -14,6 +14,12 @@
14
14
  export const overlaySurface =
15
15
  'bg-popover text-popover-foreground rounded-xl border border-border shadow-lg'
16
16
 
17
+ /**
18
+ * Overlay titles have one fixed typography role. Keep this small recipe shared
19
+ * without loading the configurable Heading component into every dialog.
20
+ */
21
+ export const overlayTitle = 'font-semibold text-base tracking-tight leading-none'
22
+
17
23
  /** The span of the portal wrapper that centres a dialog-like overlay. */
18
24
  export const overlayPositioner = 'fixed inset-0 z-(--z-dialog) grid place-items-center p-4'
19
25