@adea-ai/ui 0.104.2 → 0.105.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 (71) hide show
  1. package/README.md +11 -0
  2. package/dist/components/layout/split-layout/geometry.js +1 -1
  3. package/dist/components/layout/split-layout/index.js +2 -1
  4. package/dist/components/layout/split-layout/model.d.ts +2 -20
  5. package/dist/components/layout/split-layout/model.d.ts.map +1 -1
  6. package/dist/components/layout/split-layout/model.js +2 -14
  7. package/dist/components/layout/split-layout/model.js.map +1 -1
  8. package/dist/components/layout/split-layout/split-layout.js +1 -1
  9. package/dist/components/layout/split-layout/tree.d.ts +21 -0
  10. package/dist/components/layout/split-layout/tree.d.ts.map +1 -0
  11. package/dist/components/layout/split-layout/tree.js +18 -0
  12. package/dist/components/layout/split-layout/tree.js.map +1 -0
  13. package/dist/components/ui/kbd/index.d.ts +1 -1
  14. package/dist/components/ui/kbd/index.d.ts.map +1 -1
  15. package/dist/components/ui/kbd/index.js +2 -2
  16. package/dist/components/ui/kbd/kbd.d.ts +40 -2
  17. package/dist/components/ui/kbd/kbd.d.ts.map +1 -1
  18. package/dist/components/ui/kbd/kbd.js +74 -7
  19. package/dist/components/ui/kbd/kbd.js.map +1 -1
  20. package/dist/index.js +4 -3
  21. package/dist/r/about-dialog.json +1 -1
  22. package/dist/r/accordion.json +1 -1
  23. package/dist/r/account-menu.json +1 -1
  24. package/dist/r/alert.json +1 -1
  25. package/dist/r/appearance-editor.json +2 -2
  26. package/dist/r/breadcrumb.json +1 -1
  27. package/dist/r/calendar.json +1 -1
  28. package/dist/r/carousel.json +1 -1
  29. package/dist/r/catalog-browser.json +1 -1
  30. package/dist/r/checkbox.json +1 -1
  31. package/dist/r/code-block.json +1 -1
  32. package/dist/r/combobox.json +1 -1
  33. package/dist/r/command.json +1 -1
  34. package/dist/r/context-menu.json +1 -1
  35. package/dist/r/conversation.json +1 -1
  36. package/dist/r/detail-panel.json +1 -1
  37. package/dist/r/dialog.json +1 -1
  38. package/dist/r/dropdown-menu.json +1 -1
  39. package/dist/r/empty.json +1 -1
  40. package/dist/r/floating-preview.json +1 -1
  41. package/dist/r/help-center.json +1 -1
  42. package/dist/r/lib.json +1 -1
  43. package/dist/r/menubar.json +1 -1
  44. package/dist/r/native-select.json +1 -1
  45. package/dist/r/navigation-menu.json +1 -1
  46. package/dist/r/pagination.json +1 -1
  47. package/dist/r/radio-group.json +1 -1
  48. package/dist/r/registry.json +47 -42
  49. package/dist/r/resizable.json +1 -1
  50. package/dist/r/scene-controls.json +1 -1
  51. package/dist/r/select.json +1 -1
  52. package/dist/r/sheet.json +1 -1
  53. package/dist/r/sidebar-nav.json +1 -1
  54. package/dist/r/spinner.json +1 -1
  55. package/dist/r/split-layout.json +6 -1
  56. package/dist/r/src/components/layout/split-layout/model.ts +11 -30
  57. package/dist/r/src/components/layout/split-layout/tree.ts +51 -0
  58. package/dist/r/src/components/ui/kbd/index.ts +10 -1
  59. package/dist/r/src/components/ui/kbd/kbd.tsx +77 -14
  60. package/dist/r/stat.json +1 -1
  61. package/dist/r/theming.json +2 -2
  62. package/dist/r/toast.json +1 -1
  63. package/dist/r/top-bar.json +1 -1
  64. package/dist/r/tree.json +1 -1
  65. package/dist/r/update-dialog.json +1 -1
  66. package/package.json +13 -7
  67. package/registry.json +47 -42
  68. package/src/components/layout/split-layout/model.ts +11 -30
  69. package/src/components/layout/split-layout/tree.ts +51 -0
  70. package/src/components/ui/kbd/index.ts +10 -1
  71. package/src/components/ui/kbd/kbd.tsx +77 -14
@@ -15,21 +15,18 @@
15
15
  * See NOTICE and docs/research/dev-view-donor-audit.md.
16
16
  */
17
17
 
18
- /** A visual identity only. Extend this with host-owned payload; UI never interprets it. */
19
- export type SplitLayoutLeaf = Readonly<{ kind: 'leaf'; id: string }>
20
- export type SplitLayoutBranch<L extends SplitLayoutLeaf = SplitLayoutLeaf> = Readonly<{
21
- kind: 'split'
22
- id: string
23
- direction: 'row' | 'column'
24
- ratio: number
25
- children: readonly [SplitLayoutNode<L>, SplitLayoutNode<L>]
26
- }>
27
- export type SplitLayoutNode<L extends SplitLayoutLeaf = SplitLayoutLeaf> = L | SplitLayoutBranch<L>
18
+ import {
19
+ MAX_LAYOUT_LEAVES,
20
+ MAX_LAYOUT_DEPTH,
21
+ MIN_SPLIT_RATIO,
22
+ MAX_SPLIT_RATIO,
23
+ listLeaves,
24
+ countLeaves,
25
+ layoutDepth,
26
+ } from './tree'
27
+ import type { SplitLayoutLeaf, SplitLayoutBranch, SplitLayoutNode } from './tree'
28
28
 
29
- export const MAX_LAYOUT_LEAVES = 8
30
- export const MAX_LAYOUT_DEPTH = 8
31
- export const MIN_SPLIT_RATIO = 0.1
32
- export const MAX_SPLIT_RATIO = 0.9
29
+ export * from './tree'
33
30
 
34
31
  export type SplitLayoutState<L extends SplitLayoutLeaf = SplitLayoutLeaf> = Readonly<{
35
32
  center: SplitLayoutNode<L>
@@ -44,22 +41,6 @@ export type SplitPaneInput<L extends SplitLayoutLeaf = SplitLayoutLeaf> = Readon
44
41
  splitId: string
45
42
  }>
46
43
 
47
- export function listLeaves<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): readonly L[] {
48
- return node.kind === 'leaf'
49
- ? [node]
50
- : [...listLeaves(node.children[0]), ...listLeaves(node.children[1])]
51
- }
52
-
53
- export function countLeaves<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): number {
54
- return node.kind === 'leaf' ? 1 : countLeaves(node.children[0]) + countLeaves(node.children[1])
55
- }
56
-
57
- export function layoutDepth<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): number {
58
- return node.kind === 'leaf'
59
- ? 1
60
- : 1 + Math.max(layoutDepth(node.children[0]), layoutDepth(node.children[1]))
61
- }
62
-
63
44
  function replaceLeaf<L extends SplitLayoutLeaf>(
64
45
  node: SplitLayoutNode<L>,
65
46
  leafId: string,
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright (c) 2026 Michael Yong
3
+ * Copyright (c) 2026 Muxy
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Portions of the binary split behavior are substantially translated from:
7
+ * - get-bb/bb apps/app/src/lib/split-layout/ops.ts (MIT), revision
8
+ * 52a9256373d4d36f9b60e9e2a7f333464091a2ac.
9
+ * - muxy-app/muxy Muxy/Models/Workspace/SplitNode.swift (MIT), revision
10
+ * 5c5be8697c57a2fe70cda97fdbaf7c912e2e31b6.
11
+ * Adapted first in Adea packages/dev-view/src/layout/operations.ts at
12
+ * 0322ab09ff5e9775bfddc0bf2d81e1df436dbef7. Extracted here with opaque
13
+ * host-owned leaves and an injected final-pane placeholder; immutable strict
14
+ * binary operations, accepted limits and undoable close are preserved.
15
+ * See NOTICE and docs/research/dev-view-donor-audit.md.
16
+ */
17
+
18
+ // Read-only tree shape, limits, and traversal form a small import boundary.
19
+ // Persistence decoders can use these without loading pane-editing operations.
20
+
21
+ /** A visual identity only. Extend this with host-owned payload; UI never interprets it. */
22
+ export type SplitLayoutLeaf = Readonly<{ kind: 'leaf'; id: string }>
23
+ export type SplitLayoutBranch<L extends SplitLayoutLeaf = SplitLayoutLeaf> = Readonly<{
24
+ kind: 'split'
25
+ id: string
26
+ direction: 'row' | 'column'
27
+ ratio: number
28
+ children: readonly [SplitLayoutNode<L>, SplitLayoutNode<L>]
29
+ }>
30
+ export type SplitLayoutNode<L extends SplitLayoutLeaf = SplitLayoutLeaf> = L | SplitLayoutBranch<L>
31
+
32
+ export const MAX_LAYOUT_LEAVES = 8
33
+ export const MAX_LAYOUT_DEPTH = 8
34
+ export const MIN_SPLIT_RATIO = 0.1
35
+ export const MAX_SPLIT_RATIO = 0.9
36
+
37
+ export function listLeaves<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): readonly L[] {
38
+ return node.kind === 'leaf'
39
+ ? [node]
40
+ : [...listLeaves(node.children[0]), ...listLeaves(node.children[1])]
41
+ }
42
+
43
+ export function countLeaves<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): number {
44
+ return node.kind === 'leaf' ? 1 : countLeaves(node.children[0]) + countLeaves(node.children[1])
45
+ }
46
+
47
+ export function layoutDepth<L extends SplitLayoutLeaf>(node: SplitLayoutNode<L>): number {
48
+ return node.kind === 'leaf'
49
+ ? 1
50
+ : 1 + Math.max(layoutDepth(node.children[0]), layoutDepth(node.children[1]))
51
+ }
@@ -1 +1,10 @@
1
- export { Kbd, KbdGroup } from './kbd'
1
+ export {
2
+ Kbd,
3
+ KbdChord,
4
+ KbdGroup,
5
+ kbdChordKeys,
6
+ kbdGroupVariants,
7
+ kbdVariants,
8
+ type KbdChordProps,
9
+ type KbdSize,
10
+ } from './kbd'
@@ -1,5 +1,6 @@
1
1
  import type { ComponentProps } from 'solid-js'
2
- import { splitProps } from 'solid-js'
2
+ import { For, splitProps } from 'solid-js'
3
+ import { cva, type VariantProps } from '../../../lib/variants'
3
4
  import { cn } from '../../../lib/utils'
4
5
 
5
6
  /**
@@ -9,32 +10,94 @@ import { cn } from '../../../lib/utils'
9
10
  * `<kbd>` so the semantics survive copy-paste, and the mono face is what makes
10
11
  * a shortcut visually distinct from the sentence around it.
11
12
  *
13
+ * `size="compact"` exists for the dense rows a default cap would outweigh — a
14
+ * rail search row, a sidebar shortcut hint. It drops a height rung, and it
15
+ * lightens the fill and weight with it because at that size a solid muted cap
16
+ * reads heavier than the row text it sits in. The default rendering is every
17
+ * cap that is not inside such a row, and it is untouched by the rung.
18
+ *
12
19
  * `KbdGroup` exists because a shortcut is a sequence: typing `⌘` then `K`
13
20
  * needs a gap between them that is a layout concern, not punctuation.
14
21
  */
15
- export function Kbd(props: ComponentProps<'kbd'>) {
16
- const [local, rest] = splitProps(props, ['class'])
22
+ export const kbdVariants = cva(
23
+ 'bg-muted text-muted-foreground pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm border border-border px-1 font-mono text-2xs font-medium select-none',
24
+ {
25
+ variants: {
26
+ size: {
27
+ default: '',
28
+ compact: 'h-4 min-w-4 bg-muted/40 px-0.5 font-normal leading-none',
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ size: 'default',
33
+ },
34
+ }
35
+ )
36
+
37
+ export type KbdSize = NonNullable<VariantProps<typeof kbdVariants>['size']>
38
+
39
+ export function Kbd(props: ComponentProps<'kbd'> & { size?: KbdSize }) {
40
+ const [local, rest] = splitProps(props, ['size', 'class'])
17
41
 
18
42
  return (
19
- <kbd
20
- data-slot="kbd"
21
- class={cn(
22
- 'bg-muted text-muted-foreground pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm border border-border px-1 font-mono text-2xs font-medium select-none',
23
- local.class
24
- )}
25
- {...rest}
26
- />
43
+ <kbd data-slot="kbd" class={cn(kbdVariants({ size: local.size }), local.class)} {...rest} />
27
44
  )
28
45
  }
29
46
 
30
- export function KbdGroup(props: ComponentProps<'span'>) {
31
- const [local, rest] = splitProps(props, ['class'])
47
+ export const kbdGroupVariants = cva('inline-flex items-center gap-1', {
48
+ variants: {
49
+ size: {
50
+ default: '',
51
+ /** The gap is what separates caps, so it tightens with them. */
52
+ compact: 'gap-0.5',
53
+ },
54
+ },
55
+ defaultVariants: {
56
+ size: 'default',
57
+ },
58
+ })
59
+
60
+ export function KbdGroup(props: ComponentProps<'span'> & { size?: KbdSize }) {
61
+ const [local, rest] = splitProps(props, ['size', 'class'])
32
62
 
33
63
  return (
34
64
  <span
35
65
  data-slot="kbd-group"
36
- class={cn('inline-flex items-center gap-1', local.class)}
66
+ class={cn(kbdGroupVariants({ size: local.size }), local.class)}
37
67
  {...rest}
38
68
  />
39
69
  )
40
70
  }
71
+
72
+ /**
73
+ * Split a written chord into one entry per key cap. Every character is a key:
74
+ * `⌘K` renders as `⌘` + `K`, and a longer chord like `⇧⌘P` stays three caps
75
+ * wide, which matches how the system draws chords in menus.
76
+ */
77
+ export function kbdChordKeys(keys: string): string[] {
78
+ return [...keys]
79
+ }
80
+
81
+ export type KbdChordProps = Omit<ComponentProps<'span'>, 'children'> & {
82
+ /** The chord as it is drawn, e.g. `"⌘K"` or `"⇧⌘P"`. One cap per character. */
83
+ keys: string
84
+ size?: KbdSize
85
+ }
86
+
87
+ /**
88
+ * KbdChord.
89
+ *
90
+ * A written chord drawn as caps, one per character. Decoration only: the
91
+ * composition renders `aria-hidden`, so the accessible name and the parseable
92
+ * `aria-keyshortcuts` stay on the control the chord belongs to. That is why
93
+ * there is no children — the chord says what was drawn, nothing more.
94
+ */
95
+ export function KbdChord(props: KbdChordProps) {
96
+ const [local, rest] = splitProps(props, ['keys', 'size', 'class'])
97
+
98
+ return (
99
+ <KbdGroup {...rest} size={local.size} class={local.class} aria-hidden="true">
100
+ <For each={kbdChordKeys(local.keys)}>{(key) => <Kbd size={local.size}>{key}</Kbd>}</For>
101
+ </KbdGroup>
102
+ )
103
+ }
package/dist/r/stat.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "title": "Stat",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "lucide-solid@^1.48.0"
7
+ "lucide-solid@^1.51.0"
8
8
  ],
9
9
  "registryDependencies": [
10
10
  "@adea-ai/ui/typography",
@@ -4,8 +4,8 @@
4
4
  "title": "Theming",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "@adea-ai/themes@^0.9.5",
8
- "lucide-solid@^1.48.0"
7
+ "@adea-ai/themes@^0.9.6",
8
+ "lucide-solid@^1.51.0"
9
9
  ],
10
10
  "registryDependencies": [
11
11
  "@adea-ai/ui/button",
package/dist/r/toast.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "",
6
6
  "dependencies": [
7
7
  "@kobalte/core@^0.13.14",
8
- "lucide-solid@^1.48.0"
8
+ "lucide-solid@^1.51.0"
9
9
  ],
10
10
  "registryDependencies": [
11
11
  "lib"
@@ -4,7 +4,7 @@
4
4
  "title": "Top Bar",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "lucide-solid@^1.48.0"
7
+ "lucide-solid@^1.51.0"
8
8
  ],
9
9
  "registryDependencies": [
10
10
  "lib"
package/dist/r/tree.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "title": "Tree",
5
5
  "description": "Keyboard-accessible tree rows with virtualization-aware focus handoff.",
6
6
  "dependencies": [
7
- "lucide-solid@^1.48.0"
7
+ "lucide-solid@^1.51.0"
8
8
  ],
9
9
  "registryDependencies": [
10
10
  "lib"
@@ -4,7 +4,7 @@
4
4
  "title": "Update Dialog",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "lucide-solid@^1.48.0"
7
+ "lucide-solid@^1.51.0"
8
8
  ],
9
9
  "registryDependencies": [
10
10
  "@adea-ai/ui/action-button",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.104.2",
3
+ "version": "0.105.0",
4
4
  "description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
5
5
  "keywords": [
6
6
  "adea",
@@ -87,6 +87,12 @@
87
87
  "solid": "./src/components/conversation/transcript-composition.tsx",
88
88
  "development": "./src/components/conversation/transcript-composition.tsx",
89
89
  "import": "./dist/components/conversation/transcript-composition.js"
90
+ },
91
+ "./components/layout/split-layout/tree": {
92
+ "types": "./dist/components/layout/split-layout/tree.d.ts",
93
+ "solid": "./src/components/layout/split-layout/tree.ts",
94
+ "development": "./src/components/layout/split-layout/tree.ts",
95
+ "import": "./dist/components/layout/split-layout/tree.js"
90
96
  }
91
97
  },
92
98
  "scripts": {
@@ -104,7 +110,7 @@
104
110
  "theme:build": "bun scripts/build-default-theme.ts",
105
111
  "theme:check": "bun scripts/build-default-theme.ts --check",
106
112
  "design-system:build": "bun scripts/design-system/build.ts",
107
- "check:packed-layout": "node --test scripts/check-packed-layout-process.test.mjs && node scripts/check-packed-layout.mjs",
113
+ "check:packed-layout": "node --test scripts/check-packed-layout-process.test.mjs && node scripts/check-packed-layout.mjs && node scripts/check-packed-layout-tree.mjs",
108
114
  "check:packed-consumer": "bun scripts/check-packed-consumer.ts",
109
115
  "check:packed-list-row": "bun scripts/check-packed-list-row.ts",
110
116
  "check:packed-scene-controls": "bun scripts/check-packed-scene-controls.ts",
@@ -119,7 +125,7 @@
119
125
  "check:packed-paste-model": "node scripts/check-packed-paste-model.mjs"
120
126
  },
121
127
  "dependencies": {
122
- "@adea-ai/themes": "^0.9.5",
128
+ "@adea-ai/themes": "^0.9.6",
123
129
  "@corvu/calendar": "^0.1.2",
124
130
  "@corvu/drawer": "^0.2.4",
125
131
  "@corvu/otp-field": "^0.1.4",
@@ -132,20 +138,20 @@
132
138
  "class-variance-authority": "^0.7.1",
133
139
  "cmdk-solid": "^1.2.0",
134
140
  "cn": "^0.4.0",
135
- "lucide-solid": "^1.48.0",
141
+ "lucide-solid": "^1.51.0",
136
142
  "solid-motionone": "^1.0.4",
137
143
  "tw-animate-css": "^1.4.0"
138
144
  },
139
145
  "devDependencies": {
140
- "@storybook/addon-docs": "^10.6.0",
146
+ "@storybook/addon-docs": "^10.6.1",
141
147
  "chart.js": "^4.5.1",
142
148
  "embla-carousel": "^8.6.0",
143
149
  "embla-carousel-solid": "^8.6.0",
144
150
  "solid-chartjs": "^1.3.11",
145
151
  "solid-js": "^1.9.15",
146
- "storybook": "^10.6.0",
152
+ "storybook": "^10.6.1",
147
153
  "storybook-solidjs-vite": "^10.7.2",
148
- "vite": "^8.0.14",
154
+ "vite": "^8.3.2",
149
155
  "vite-plugin-solid": "^2.11.14"
150
156
  },
151
157
  "peerDependencies": {