@adea-ai/ui 0.87.0 → 0.89.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 (44) hide show
  1. package/README.md +22 -0
  2. package/dist/components/composites/settings/index.d.ts +2 -0
  3. package/dist/components/composites/settings/index.d.ts.map +1 -1
  4. package/dist/components/composites/settings/index.js +3 -1
  5. package/dist/components/composites/settings/settings-layout.d.ts +28 -0
  6. package/dist/components/composites/settings/settings-layout.d.ts.map +1 -0
  7. package/dist/components/composites/settings/settings-layout.js +62 -0
  8. package/dist/components/composites/settings/settings-layout.js.map +1 -0
  9. package/dist/components/composites/settings/settings-navigation.d.ts +41 -0
  10. package/dist/components/composites/settings/settings-navigation.d.ts.map +1 -0
  11. package/dist/components/composites/settings/settings-navigation.js +102 -0
  12. package/dist/components/composites/settings/settings-navigation.js.map +1 -0
  13. package/dist/components/layout/sidebar-nav/index.d.ts +1 -1
  14. package/dist/components/layout/sidebar-nav/index.d.ts.map +1 -1
  15. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts +18 -2
  16. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts.map +1 -1
  17. package/dist/components/layout/sidebar-nav/sidebar-nav.js +42 -11
  18. package/dist/components/layout/sidebar-nav/sidebar-nav.js.map +1 -1
  19. package/dist/components/layout/top-bar/top-bar.d.ts +3 -1
  20. package/dist/components/layout/top-bar/top-bar.d.ts.map +1 -1
  21. package/dist/components/layout/top-bar/top-bar.js +4 -4
  22. package/dist/components/layout/top-bar/top-bar.js.map +1 -1
  23. package/dist/components/ui/tabs/tabs.d.ts.map +1 -1
  24. package/dist/components/ui/tabs/tabs.js +70 -13
  25. package/dist/components/ui/tabs/tabs.js.map +1 -1
  26. package/dist/index.js +3 -1
  27. package/dist/r/registry.json +12 -0
  28. package/dist/r/settings.json +12 -0
  29. package/dist/r/src/components/composites/settings/index.ts +7 -0
  30. package/dist/r/src/components/composites/settings/settings-layout.tsx +65 -0
  31. package/dist/r/src/components/composites/settings/settings-navigation.tsx +135 -0
  32. package/dist/r/src/components/layout/sidebar-nav/index.ts +2 -0
  33. package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +71 -16
  34. package/dist/r/src/components/layout/top-bar/top-bar.tsx +9 -5
  35. package/dist/r/src/components/ui/tabs/tabs.tsx +80 -10
  36. package/package.json +2 -1
  37. package/registry.json +12 -0
  38. package/src/components/composites/settings/index.ts +7 -0
  39. package/src/components/composites/settings/settings-layout.tsx +65 -0
  40. package/src/components/composites/settings/settings-navigation.tsx +135 -0
  41. package/src/components/layout/sidebar-nav/index.ts +2 -0
  42. package/src/components/layout/sidebar-nav/sidebar-nav.tsx +71 -16
  43. package/src/components/layout/top-bar/top-bar.tsx +9 -5
  44. package/src/components/ui/tabs/tabs.tsx +80 -10
@@ -20,7 +20,7 @@ function TopBar(props) {
20
20
  return (() => {
21
21
  var _el$ = _tmpl$();
22
22
  spread(_el$, mergeProps({ get ["class"]() {
23
- return cn("h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)] items-center gap-3 border-b border-border px-3", local.glass && "glass-panel", local.draggable && "window-drag", local.macosInset && "window-inset-macos", local.windowsInset && "window-inset-windows", local.class);
23
+ return cn("h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border-b border-border bg-card text-card-foreground px-3 md:grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)]", local.glass && "glass-panel", local.draggable && "window-drag", local.macosInset && "window-inset-macos", local.windowsInset && "window-inset-windows", local.class);
24
24
  } }, rest), false, false);
25
25
  return _el$;
26
26
  })();
@@ -31,17 +31,17 @@ function TopBarSection(props) {
31
31
  return (() => {
32
32
  var _el$2 = _tmpl$2();
33
33
  spread(_el$2, mergeProps({ get ["class"]() {
34
- return cn("flex min-w-0 items-center gap-2 overflow-hidden", local.align === "end" && "justify-end", local.align !== "end" && "justify-start", local.class);
34
+ return cn("window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden", local.align === "end" && "justify-end", local.align !== "end" && "justify-start", local.class);
35
35
  } }, rest), false, false);
36
36
  return _el$2;
37
37
  })();
38
38
  }
39
39
  function TopBarTitle(props) {
40
- const [local, rest] = splitProps(props, ["class"]);
40
+ const [local, rest] = splitProps(props, ["class", "align"]);
41
41
  return (() => {
42
42
  var _el$3 = _tmpl$3();
43
43
  spread(_el$3, mergeProps({ get ["class"]() {
44
- return cn("truncate text-sm font-medium", local.class);
44
+ return cn("truncate text-sm font-medium", local.align === "center" && "text-center", local.class);
45
45
  } }, rest), false, false);
46
46
  return _el$3;
47
47
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"top-bar.js","names":["ComponentProps","Show","splitProps","cn","TopBarProps","draggable","macosInset","windowsInset","glass","TopBar","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","TopBarSection","align","_el$2","_tmpl$2","TopBarTitle","_el$3","_tmpl$3","TopBarBreadcrumb","_el$4","_tmpl$4","TopBarSearchProps","placeholder","shortcut","TopBarSearch","_el$5","_tmpl$6","_el$6","firstChild","_$insert","_$createComponent","when","children","_el$7","_tmpl$5","TopBarPill","label","_el$8","_tmpl$7","_el$9","_$mergeProps","_$createComponent"],"sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * TopBar.\n *\n * The window's title row and primary toolbar. Three tracks: a leading group, a\n * centred search, and a trailing group. The search is a fixed function of the\n * window width and the two side groups are equal remainders, which is what\n * makes the search *exactly* window-centred by construction — no measurement,\n * no observer, no absolutely-positioned overlay to keep clear of.\n *\n * On a frameless desktop window this row is also the drag region, so it carries\n * `window-drag` and the controls inside it opt back out. `macos-inset` and\n * `windows-inset` reserve the space the native window controls occupy, which is\n * why the row can look off-centre in a frameless window and be correct: it is\n * centred in the space the user can actually see.\n */\nexport type TopBarProps = ComponentProps<'header'> & {\n /** Make the row draggable, for a frameless window. */\n draggable?: boolean\n /** Reserve space for the macOS traffic lights. */\n macosInset?: boolean\n /** Reserve space for the Windows caption buttons. */\n windowsInset?: boolean\n /** Blur the content scrolling under the bar. */\n glass?: boolean\n}\n\nexport function TopBar(props: TopBarProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'draggable',\n 'macosInset',\n 'windowsInset',\n 'glass',\n ])\n\n return (\n <header\n data-slot=\"top-bar\"\n class={cn(\n 'h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)] items-center gap-3 border-b border-border px-3',\n local.glass && 'glass-panel',\n local.draggable && 'window-drag',\n local.macosInset && 'window-inset-macos',\n local.windowsInset && 'window-inset-windows',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A side group. Both sides are equal remainders, which centres the search. */\nexport function TopBarSection(props: ComponentProps<'div'> & { align?: 'start' | 'end' }) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n\n return (\n <div\n data-slot=\"top-bar-section\"\n class={cn(\n 'flex min-w-0 items-center gap-2 overflow-hidden',\n local.align === 'end' && 'justify-end',\n local.align !== 'end' && 'justify-start',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function TopBarTitle(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"top-bar-title\"\n class={cn('truncate text-sm font-medium', local.class)}\n {...rest}\n />\n )\n}\n\n/** A breadcrumb or path readout that yields to the actions when space runs out. */\nexport function TopBarBreadcrumb(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"top-bar-breadcrumb\"\n class={cn('flex min-w-0 items-center gap-1.5 text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport type TopBarSearchProps = ComponentProps<'button'> & {\n /** The hint shown inside the field, e.g. \"Search projects and files\". */\n placeholder?: string\n /** The shortcut chip drawn at the trailing edge, e.g. \"⌘K\". */\n shortcut?: string\n}\n\n/**\n * The search affordance in the middle track.\n *\n * It is a button, not an input, and that is deliberate: clicking it opens the\n * command palette, which already owns the input, the ranking and the keyboard\n * handling. A second live input here would be a second source of truth for the\n * same query. It is styled to read as a field because that is what it behaves\n * like from the user's side.\n */\nexport function TopBarSearch(props: TopBarSearchProps) {\n const [local, rest] = splitProps(props, ['class', 'placeholder', 'shortcut'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-search\"\n class={cn(\n 'text-muted-foreground flex h-control-md w-full items-center gap-2 rounded-md border border-input px-3 text-sm',\n 'transition-colors ease-out outline-none',\n 'hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag',\n local.class\n )}\n {...rest}\n >\n <span class=\"truncate\">{local.placeholder ?? 'Search'}</span>\n <Show when={local.shortcut}>\n <kbd class=\"bg-muted ms-auto hidden h-5 shrink-0 items-center rounded-sm border border-border px-1.5 font-mono text-2xs sm:flex\">\n {local.shortcut}\n </kbd>\n </Show>\n </button>\n )\n}\n\n/**\n * A labelled top-bar control — the readouts KiroCrew puts in the trailing\n * group. Container queries on the group decide which of these survive a narrow\n * window; a caller marks the cheap-to-drop ones and the group handles the rest.\n */\nexport function TopBarPill(props: ComponentProps<'button'> & { label: string }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'children'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-pill\"\n class={cn(\n 'text-muted-foreground inline-flex h-control-sm shrink-0 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium',\n 'transition-colors ease-out outline-none',\n 'hover:border-input hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag [&_svg]:size-3.5 [&_svg]:shrink-0',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <span>{local.label}</span>\n </button>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"top-bar.js","names":["ComponentProps","Show","splitProps","cn","TopBarProps","draggable","macosInset","windowsInset","glass","TopBar","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","TopBarSection","align","_el$2","_tmpl$2","TopBarTitle","_el$3","_tmpl$3","TopBarBreadcrumb","_el$4","_tmpl$4","TopBarSearchProps","placeholder","shortcut","TopBarSearch","_el$5","_tmpl$6","_el$6","firstChild","_$insert","_$createComponent","when","children","_el$7","_tmpl$5","TopBarPill","label","_el$8","_tmpl$7","_el$9","_$mergeProps","_$createComponent"],"sources":["../../../../src/components/layout/top-bar/top-bar.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * TopBar.\n *\n * The window's title row and primary toolbar. Three tracks: a leading group, a\n * centred search, and a trailing group. The search is a fixed function of the\n * window width and the two side groups are equal remainders, which is what\n * makes the search *exactly* window-centred by construction — no measurement,\n * no observer, no absolutely-positioned overlay to keep clear of.\n *\n * On a frameless desktop window this row is also the drag region, so it carries\n * `window-drag` and the controls inside it opt back out. `macos-inset` and\n * `windows-inset` reserve the space the native window controls occupy, which is\n * why the row can look off-centre in a frameless window and be correct: it is\n * centred in the space the user can actually see.\n */\nexport type TopBarProps = ComponentProps<'header'> & {\n /** Make the row draggable, for a frameless window. */\n draggable?: boolean\n /** Reserve space for the macOS traffic lights. */\n macosInset?: boolean\n /** Reserve space for the Windows caption buttons. */\n windowsInset?: boolean\n /** Blur the content scrolling under the bar. */\n glass?: boolean\n}\n\nexport function TopBar(props: TopBarProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'draggable',\n 'macosInset',\n 'windowsInset',\n 'glass',\n ])\n\n return (\n <header\n data-slot=\"top-bar\"\n class={cn(\n 'h-topbar relative z-(--z-sticky) grid shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border-b border-border bg-card text-card-foreground px-3 md:grid-cols-[minmax(0,1fr)_clamp(240px,22vw,480px)_minmax(0,1fr)]',\n local.glass && 'glass-panel',\n local.draggable && 'window-drag',\n local.macosInset && 'window-inset-macos',\n local.windowsInset && 'window-inset-windows',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A side group. Both sides are equal remainders, which centres the search. */\nexport function TopBarSection(props: ComponentProps<'div'> & { align?: 'start' | 'end' }) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n\n return (\n <div\n data-slot=\"top-bar-section\"\n class={cn(\n 'window-no-drag flex min-w-0 items-center gap-2 overflow-x-auto overflow-y-hidden',\n local.align === 'end' && 'justify-end',\n local.align !== 'end' && 'justify-start',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function TopBarTitle(props: ComponentProps<'div'> & { align?: 'start' | 'center' }) {\n const [local, rest] = splitProps(props, ['class', 'align'])\n return (\n <div\n data-slot=\"top-bar-title\"\n class={cn(\n 'truncate text-sm font-medium',\n local.align === 'center' && 'text-center',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A breadcrumb or path readout that yields to the actions when space runs out. */\nexport function TopBarBreadcrumb(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"top-bar-breadcrumb\"\n class={cn('flex min-w-0 items-center gap-1.5 text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport type TopBarSearchProps = ComponentProps<'button'> & {\n /** The hint shown inside the field, e.g. \"Search projects and files\". */\n placeholder?: string\n /** The shortcut chip drawn at the trailing edge, e.g. \"⌘K\". */\n shortcut?: string\n}\n\n/**\n * The search affordance in the middle track.\n *\n * It is a button, not an input, and that is deliberate: clicking it opens the\n * command palette, which already owns the input, the ranking and the keyboard\n * handling. A second live input here would be a second source of truth for the\n * same query. It is styled to read as a field because that is what it behaves\n * like from the user's side.\n */\nexport function TopBarSearch(props: TopBarSearchProps) {\n const [local, rest] = splitProps(props, ['class', 'placeholder', 'shortcut'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-search\"\n class={cn(\n 'text-muted-foreground flex h-control-md w-full items-center gap-2 rounded-md border border-input px-3 text-sm',\n 'transition-colors ease-out outline-none',\n 'hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag',\n local.class\n )}\n {...rest}\n >\n <span class=\"truncate\">{local.placeholder ?? 'Search'}</span>\n <Show when={local.shortcut}>\n <kbd class=\"bg-muted ms-auto hidden h-5 shrink-0 items-center rounded-sm border border-border px-1.5 font-mono text-2xs sm:flex\">\n {local.shortcut}\n </kbd>\n </Show>\n </button>\n )\n}\n\n/**\n * A labelled top-bar control — the readouts KiroCrew puts in the trailing\n * group. Container queries on the group decide which of these survive a narrow\n * window; a caller marks the cheap-to-drop ones and the group handles the rest.\n */\nexport function TopBarPill(props: ComponentProps<'button'> & { label: string }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'children'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"top-bar-pill\"\n class={cn(\n 'text-muted-foreground inline-flex h-control-sm shrink-0 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium',\n 'transition-colors ease-out outline-none',\n 'hover:border-input hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'window-no-drag [&_svg]:size-3.5 [&_svg]:shrink-0',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <span>{local.label}</span>\n </button>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tabs/tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,kCAQ7D;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG;IACpE,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;CACvC,CAAA;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,kCAgB5C;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG;IAC1E,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;CACvC,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,kCAoBlD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,kCAG5E"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tabs/tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,UAAU,CAAA;AA2BxD;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,kCAiC7D;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG;IACpE,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;CACvC,CAAA;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,kCAgB5C;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG;IAC1E,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;CACvC,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,kCA+BlD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,kCAc5E"}
@@ -1,8 +1,14 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
2
  import { createComponent, mergeProps } from "solid-js/web";
3
- import { splitProps } from "solid-js";
3
+ import { createContext, createRenderEffect, createSignal, createUniqueId, onCleanup, splitProps, useContext } from "solid-js";
4
4
  import { Tabs } from "@kobalte/core/tabs";
5
5
  //#region src/components/ui/tabs/tabs.tsx
6
+ var TabsIdContext = createContext();
7
+ function useTabsId() {
8
+ const tabs = useContext(TabsIdContext);
9
+ if (!tabs) throw new Error("[adea-ui]: Tabs parts must be used within Tabs.");
10
+ return tabs;
11
+ }
6
12
  /**
7
13
  * Tabs.
8
14
  *
@@ -14,10 +20,38 @@ import { Tabs } from "@kobalte/core/tabs";
14
20
  * where a full-width underline would collide with the panel's own header rule.
15
21
  */
16
22
  function Tabs$1(props) {
17
- const [local, rest] = splitProps(props, ["class"]);
18
- return createComponent(Tabs, mergeProps({ get ["class"]() {
19
- return cn("flex flex-col gap-2 data-[orientation=vertical]:flex-row", local.class);
20
- } }, rest));
23
+ const [local, rest] = splitProps(props, ["class", "id"]);
24
+ const generatedId = `tabs-${createUniqueId()}`;
25
+ const id = () => local.id ?? generatedId;
26
+ const [triggerIds, setTriggerIds] = createSignal(/* @__PURE__ */ new Map());
27
+ const tabs = {
28
+ id,
29
+ triggerIds,
30
+ registerTriggerId: (value, triggerId) => {
31
+ setTriggerIds((current) => new Map(current).set(value, triggerId));
32
+ },
33
+ unregisterTriggerId: (value, triggerId) => {
34
+ setTriggerIds((current) => {
35
+ if (current.get(value) !== triggerId) return current;
36
+ const next = new Map(current);
37
+ next.delete(value);
38
+ return next;
39
+ });
40
+ }
41
+ };
42
+ return createComponent(TabsIdContext.Provider, {
43
+ value: tabs,
44
+ get children() {
45
+ return createComponent(Tabs, mergeProps({
46
+ get id() {
47
+ return id();
48
+ },
49
+ get ["class"]() {
50
+ return cn("flex min-h-0 min-w-0 flex-col gap-2 data-[orientation=vertical]:flex-row", local.class);
51
+ }
52
+ }, rest));
53
+ }
54
+ });
21
55
  }
22
56
  function TabsList(props) {
23
57
  const [local, rest] = splitProps(props, ["class", "appearance"]);
@@ -26,16 +60,39 @@ function TabsList(props) {
26
60
  } }, rest));
27
61
  }
28
62
  function TabsTrigger(props) {
29
- const [local, rest] = splitProps(props, ["class", "appearance"]);
30
- return createComponent(Tabs.Trigger, mergeProps({ get ["class"]() {
31
- return cn("inline-flex shrink-0 items-center justify-center gap-1.5 whitespace-nowrap text-sm font-medium", "transition-colors ease-out outline-none select-none", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", "disabled:pointer-events-none disabled:opacity-50", "text-foreground", "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4", local.appearance === "segmented" ? "h-control-sm rounded-md px-control-sm data-[selected]:bg-card data-[selected]:shadow-xs" : "h-control-md -mb-px rounded-none border-b-2 border-transparent px-2 pb-2 data-[selected]:border-primary", local.class);
32
- } }, rest));
63
+ const [local, rest] = splitProps(props, [
64
+ "class",
65
+ "appearance",
66
+ "id"
67
+ ]);
68
+ const tabs = useTabsId();
69
+ const triggerId = () => local.id ?? `${tabs.id()}-trigger-${rest.value}`;
70
+ createRenderEffect(() => {
71
+ const value = rest.value;
72
+ const id = triggerId();
73
+ tabs.registerTriggerId(value, id);
74
+ onCleanup(() => tabs.unregisterTriggerId(value, id));
75
+ });
76
+ return createComponent(Tabs.Trigger, mergeProps({
77
+ get id() {
78
+ return triggerId();
79
+ },
80
+ get ["class"]() {
81
+ return cn("inline-flex shrink-0 items-center justify-center gap-1.5 whitespace-nowrap text-sm font-medium", "transition-colors ease-out outline-none select-none", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", "disabled:pointer-events-none disabled:opacity-50", "text-foreground", "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4", local.appearance === "segmented" ? "h-control-sm rounded-md px-control-sm data-[selected]:bg-card data-[selected]:shadow-xs" : "h-control-md -mb-px rounded-none border-b-2 border-transparent px-2 pb-2 data-[selected]:border-primary", local.class);
82
+ }
83
+ }, rest));
33
84
  }
34
85
  function TabsContent(props) {
35
- const [local, rest] = splitProps(props, ["class"]);
36
- return createComponent(Tabs.Content, mergeProps({ get ["class"]() {
37
- return cn("flex-1 outline-none", local.class);
38
- } }, rest));
86
+ const [local, rest] = splitProps(props, ["class", "aria-labelledby"]);
87
+ const tabs = useTabsId();
88
+ return createComponent(Tabs.Content, mergeProps({
89
+ get ["aria-labelledby"]() {
90
+ return local["aria-labelledby"] ?? tabs.triggerIds().get(rest.value) ?? `${tabs.id()}-trigger-${rest.value}`;
91
+ },
92
+ get ["class"]() {
93
+ return cn("min-h-0 min-w-0 flex-1 outline-none", local.class);
94
+ }
95
+ }, rest));
39
96
  }
40
97
  //#endregion
41
98
  export { Tabs$1 as Tabs, TabsContent, TabsList, TabsTrigger };
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","names":["Tabs","KobalteTabs","ComponentProps","splitProps","cn","props","local","rest","_$createComponent","_$mergeProps","class","TabsListProps","List","appearance","TabsList","TabsTriggerProps","Trigger","TabsTrigger","TabsContent","Content","Tabs","_$createComponent","KobalteTabs","_$mergeProps"],"sources":["../../../../src/components/ui/tabs/tabs.tsx"],"sourcesContent":["import { Tabs as KobalteTabs } from '@kobalte/core/tabs'\nimport type { ComponentProps } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Tabs.\n *\n * For switching between sibling views of the *same* subject — a file's code,\n * diff and history. Not for moving between pages: a tab is expected to keep\n * its panel and its scroll position, which a route does not.\n *\n * `appearance=\"segmented\"` gives the joined bar KiroCrew uses inside a pane\n * where a full-width underline would collide with the panel's own header rule.\n */\nexport function Tabs(props: ComponentProps<typeof KobalteTabs>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTabs\n class={cn('flex flex-col gap-2 data-[orientation=vertical]:flex-row', local.class)}\n {...rest}\n />\n )\n}\n\nexport type TabsListProps = ComponentProps<typeof KobalteTabs.List> & {\n appearance?: 'underline' | 'segmented'\n}\n\nexport function TabsList(props: TabsListProps) {\n const [local, rest] = splitProps(props, ['class', 'appearance'])\n\n return (\n <KobalteTabs.List\n class={cn(\n 'inline-flex w-fit shrink-0 items-center justify-center',\n local.appearance === 'segmented'\n ? 'gap-0.5 rounded-lg bg-surface-hover p-0.5'\n : 'gap-1 rounded-none border-b border-border',\n 'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type TabsTriggerProps = ComponentProps<typeof KobalteTabs.Trigger> & {\n appearance?: 'underline' | 'segmented'\n}\n\nexport function TabsTrigger(props: TabsTriggerProps) {\n const [local, rest] = splitProps(props, ['class', 'appearance'])\n\n return (\n <KobalteTabs.Trigger\n class={cn(\n 'inline-flex shrink-0 items-center justify-center gap-1.5 whitespace-nowrap text-sm font-medium',\n 'transition-colors ease-out outline-none select-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'text-foreground',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4',\n local.appearance === 'segmented'\n ? 'h-control-sm rounded-md px-control-sm data-[selected]:bg-card data-[selected]:shadow-xs'\n : 'h-control-md -mb-px rounded-none border-b-2 border-transparent px-2 pb-2 data-[selected]:border-primary',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function TabsContent(props: ComponentProps<typeof KobalteTabs.Content>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteTabs.Content class={cn('flex-1 outline-none', local.class)} {...rest} />\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAgBA,OAAKK,OAA2C;CAC9D,MAAM,CAACC,OAAOC,QAAQJ,WAAWE,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGP,MAAWQ,WAAA,EAAA,KAAA,WAAA;EAAA,OACHL,GAAG,4DAA4DE,MAAMI,KAAK;CAAC,EAAA,GAC9EH,IAAI,CAAA;AAGd;AAMA,SAAgBO,SAAST,OAAsB;CAC7C,MAAM,CAACC,OAAOC,QAAQJ,WAAWE,OAAO,CAAC,SAAS,YAAY,CAAC;CAE/D,OAAAG,gBACGP,KAAYW,MAAIH,WAAA,EAAA,KAAA,WAAA;EAAA,OACRL,GACL,0DACAE,MAAMO,eAAe,cACjB,8CACA,6CACJ,kFACAP,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAMA,SAAgBU,YAAYZ,OAAyB;CACnD,MAAM,CAACC,OAAOC,QAAQJ,WAAWE,OAAO,CAAC,SAAS,YAAY,CAAC;CAE/D,OAAAG,gBACGP,KAAYe,SAAOP,WAAA,EAAA,KAAA,WAAA;EAAA,OACXL,GACL,kGACA,uDACA,oFACA,oDACA,mBACA,+DACAE,MAAMO,eAAe,cACjB,4FACA,2GACJP,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAEA,SAAgBW,YAAYb,OAAmD;CAC7E,MAAM,CAACC,OAAOC,QAAQJ,WAAWE,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBAAQP,KAAYkB,SAAOV,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQL,GAAG,uBAAuBE,MAAMI,KAAK;CAAC,EAAA,GAAMH,IAAI,CAAA;AACrF"}
1
+ {"version":3,"file":"tabs.js","names":["Tabs","KobalteTabs","Accessor","ComponentProps","createContext","createRenderEffect","createSignal","createUniqueId","onCleanup","splitProps","useContext","cn","TabsIdContextValue","id","triggerIds","ReadonlyMap","registerTriggerId","value","unregisterTriggerId","TabsIdContext","useTabsId","tabs","Error","props","local","rest","generatedId","setTriggerIds","Map","triggerId","current","set","get","next","delete","_$createComponent","Provider","children","_$mergeProps","class","TabsListProps","List","appearance","TabsList","TabsTriggerProps","Trigger","TabsTrigger","TabsContent","Content","aria-labelledby","Tabs","_$createComponent","KobalteTabs","_$mergeProps"],"sources":["../../../../src/components/ui/tabs/tabs.tsx"],"sourcesContent":["import { Tabs as KobalteTabs } from '@kobalte/core/tabs'\nimport type { Accessor, ComponentProps } from 'solid-js'\nimport {\n createContext,\n createRenderEffect,\n createSignal,\n createUniqueId,\n onCleanup,\n splitProps,\n useContext,\n} from 'solid-js'\nimport { cn } from '#lib/utils'\n\ntype TabsIdContextValue = {\n id: Accessor<string>\n triggerIds: Accessor<ReadonlyMap<string, string>>\n registerTriggerId: (value: string, id: string) => void\n unregisterTriggerId: (value: string, id: string) => void\n}\n\nconst TabsIdContext = createContext<TabsIdContextValue>()\n\nfunction useTabsId() {\n const tabs = useContext(TabsIdContext)\n if (!tabs) throw new Error('[adea-ui]: Tabs parts must be used within Tabs.')\n return tabs\n}\n\n/**\n * Tabs.\n *\n * For switching between sibling views of the *same* subject — a file's code,\n * diff and history. Not for moving between pages: a tab is expected to keep\n * its panel and its scroll position, which a route does not.\n *\n * `appearance=\"segmented\"` gives the joined bar KiroCrew uses inside a pane\n * where a full-width underline would collide with the panel's own header rule.\n */\nexport function Tabs(props: ComponentProps<typeof KobalteTabs>) {\n const [local, rest] = splitProps(props, ['class', 'id'])\n const generatedId = `tabs-${createUniqueId()}`\n const id = () => local.id ?? generatedId\n const [triggerIds, setTriggerIds] = createSignal<ReadonlyMap<string, string>>(new Map())\n const tabs: TabsIdContextValue = {\n id,\n triggerIds,\n registerTriggerId: (value, triggerId) => {\n setTriggerIds((current) => new Map(current).set(value, triggerId))\n },\n unregisterTriggerId: (value, triggerId) => {\n setTriggerIds((current) => {\n if (current.get(value) !== triggerId) return current\n const next = new Map(current)\n next.delete(value)\n return next\n })\n },\n }\n\n return (\n <TabsIdContext.Provider value={tabs}>\n <KobalteTabs\n id={id()}\n class={cn(\n 'flex min-h-0 min-w-0 flex-col gap-2 data-[orientation=vertical]:flex-row',\n local.class\n )}\n {...rest}\n />\n </TabsIdContext.Provider>\n )\n}\n\nexport type TabsListProps = ComponentProps<typeof KobalteTabs.List> & {\n appearance?: 'underline' | 'segmented'\n}\n\nexport function TabsList(props: TabsListProps) {\n const [local, rest] = splitProps(props, ['class', 'appearance'])\n\n return (\n <KobalteTabs.List\n class={cn(\n 'inline-flex w-fit shrink-0 items-center justify-center',\n local.appearance === 'segmented'\n ? 'gap-0.5 rounded-lg bg-surface-hover p-0.5'\n : 'gap-1 rounded-none border-b border-border',\n 'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type TabsTriggerProps = ComponentProps<typeof KobalteTabs.Trigger> & {\n appearance?: 'underline' | 'segmented'\n}\n\nexport function TabsTrigger(props: TabsTriggerProps) {\n const [local, rest] = splitProps(props, ['class', 'appearance', 'id'])\n const tabs = useTabsId()\n const triggerId = () => local.id ?? `${tabs.id()}-trigger-${rest.value}`\n\n // Register before panels render, including SSR where createEffect is skipped.\n createRenderEffect(() => {\n const value = rest.value\n const id = triggerId()\n tabs.registerTriggerId(value, id)\n onCleanup(() => tabs.unregisterTriggerId(value, id))\n })\n\n return (\n <KobalteTabs.Trigger\n id={triggerId()}\n class={cn(\n 'inline-flex shrink-0 items-center justify-center gap-1.5 whitespace-nowrap text-sm font-medium',\n 'transition-colors ease-out outline-none select-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'text-foreground',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4',\n local.appearance === 'segmented'\n ? 'h-control-sm rounded-md px-control-sm data-[selected]:bg-card data-[selected]:shadow-xs'\n : 'h-control-md -mb-px rounded-none border-b-2 border-transparent px-2 pb-2 data-[selected]:border-primary',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function TabsContent(props: ComponentProps<typeof KobalteTabs.Content>) {\n const [local, rest] = splitProps(props, ['class', 'aria-labelledby'])\n const tabs = useTabsId()\n return (\n <KobalteTabs.Content\n aria-labelledby={\n local['aria-labelledby'] ??\n tabs.triggerIds().get(rest.value) ??\n `${tabs.id()}-trigger-${rest.value}`\n }\n class={cn('min-h-0 min-w-0 flex-1 outline-none', local.class)}\n {...rest}\n />\n )\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -106,6 +106,8 @@ import { CatalogBrowser } from "./components/composites/catalog-browser/catalog-
106
106
  import { CatalogDetail, CatalogDetailSection } from "./components/composites/catalog-browser/catalog-detail.js";
107
107
  import { ListGroup, ListRow } from "./components/composites/list-row/list-row.js";
108
108
  import { SettingsField, SettingsPage, SettingsRow, SettingsSection } from "./components/composites/settings/settings.js";
109
+ import { SettingsNavigation } from "./components/composites/settings/settings-navigation.js";
110
+ import { SettingsLayout } from "./components/composites/settings/settings-layout.js";
109
111
  import { PropertyList, PropertyRow, PropertyTerm, PropertyValue, Stat, StatGroup } from "./components/composites/stat/stat.js";
110
112
  import { PalettePreview, ThemeMiniature, ThemeMiniatureSplit } from "./components/composites/appearance-editor/theme-preview.js";
111
113
  import { AppearanceEditor, AppearancePopover } from "./components/composites/appearance-editor/appearance-editor.js";
@@ -113,4 +115,4 @@ import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from "./lib/ver
113
115
  import { UpdateDialog } from "./components/composites/update-dialog/update-dialog.js";
114
116
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
115
117
  import { writeClipboardText } from "./lib/clipboard.js";
116
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogBrowser, CatalogDetail, CatalogDetailSection, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, EntityIcon, FLOATING_PREVIEW_CORNER_RADIUS, FLOATING_PREVIEW_EDGE_GAP, Field, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, FloatingPreview, FormField, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputControl, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NO_FLOATING_PREVIEW_OBSTACLES, NO_PREVIEW_MINI_PLAYER_OBSTACLES, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, NumberField, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, PREVIEW_MINI_PLAYER_CORNER_RADIUS, PREVIEW_MINI_PLAYER_EDGE_GAP, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, SecretInputGroup, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavResizeHandle, SidebarNavSection, SidebarNavTitle, Skeleton, SkipLink, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TextLink, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, clampFloatingPreviewPosition, clampPreviewMiniPlayerPosition, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, writeClipboardText, zIndexTokens };
118
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogBrowser, CatalogDetail, CatalogDetailSection, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, EntityIcon, FLOATING_PREVIEW_CORNER_RADIUS, FLOATING_PREVIEW_EDGE_GAP, Field, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, FloatingPreview, FormField, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputControl, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NO_FLOATING_PREVIEW_OBSTACLES, NO_PREVIEW_MINI_PLAYER_OBSTACLES, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, NumberField, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, PREVIEW_MINI_PLAYER_CORNER_RADIUS, PREVIEW_MINI_PLAYER_EDGE_GAP, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, SecretInputGroup, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsLayout, SettingsNavigation, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavResizeHandle, SidebarNavSection, SidebarNavTitle, Skeleton, SkipLink, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TextLink, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, ValueCombobox, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, clampFloatingPreviewPosition, clampPreviewMiniPlayerPosition, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeFloatingPreview, resizePreviewMiniPlayer, resizeSplit, resolveFloatingPreviewFrame, resolvePreviewMiniPlayerFrame, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, writeClipboardText, zIndexTokens };
@@ -1960,6 +1960,8 @@
1960
1960
  "description": "",
1961
1961
  "dependencies": [],
1962
1962
  "registryDependencies": [
1963
+ "@adea-ai/ui/sidebar-nav",
1964
+ "@adea-ai/ui/tabs",
1963
1965
  "lib"
1964
1966
  ],
1965
1967
  "files": [
@@ -1968,6 +1970,16 @@
1968
1970
  "type": "registry:ui",
1969
1971
  "target": "components/composites/settings/index.ts"
1970
1972
  },
1973
+ {
1974
+ "path": "src/components/composites/settings/settings-layout.tsx",
1975
+ "type": "registry:ui",
1976
+ "target": "components/composites/settings/settings-layout.tsx"
1977
+ },
1978
+ {
1979
+ "path": "src/components/composites/settings/settings-navigation.tsx",
1980
+ "type": "registry:ui",
1981
+ "target": "components/composites/settings/settings-navigation.tsx"
1982
+ },
1971
1983
  {
1972
1984
  "path": "src/components/composites/settings/settings.tsx",
1973
1985
  "type": "registry:ui",
@@ -5,6 +5,8 @@
5
5
  "description": "",
6
6
  "dependencies": [],
7
7
  "registryDependencies": [
8
+ "@adea-ai/ui/sidebar-nav",
9
+ "@adea-ai/ui/tabs",
8
10
  "lib"
9
11
  ],
10
12
  "files": [
@@ -13,6 +15,16 @@
13
15
  "type": "registry:ui",
14
16
  "target": "components/composites/settings/index.ts"
15
17
  },
18
+ {
19
+ "path": "src/components/composites/settings/settings-layout.tsx",
20
+ "type": "registry:ui",
21
+ "target": "components/composites/settings/settings-layout.tsx"
22
+ },
23
+ {
24
+ "path": "src/components/composites/settings/settings-navigation.tsx",
25
+ "type": "registry:ui",
26
+ "target": "components/composites/settings/settings-navigation.tsx"
27
+ },
16
28
  {
17
29
  "path": "src/components/composites/settings/settings.tsx",
18
30
  "type": "registry:ui",
@@ -1 +1,8 @@
1
1
  export { SettingsField, SettingsPage, SettingsRow, SettingsSection } from './settings'
2
+ export { SettingsLayout, type SettingsLayoutProps } from './settings-layout'
3
+ export {
4
+ SettingsNavigation,
5
+ type SettingsNavigationGroup,
6
+ type SettingsNavigationItem,
7
+ type SettingsNavigationProps,
8
+ } from './settings-navigation'
@@ -0,0 +1,65 @@
1
+ import type { ComponentProps, JSX } from 'solid-js'
2
+ import { splitProps } from 'solid-js'
3
+ import { cn } from '../../../lib/utils'
4
+ import { Tabs } from '../../ui/tabs'
5
+ import { SettingsNavigation, type SettingsNavigationGroup } from './settings-navigation'
6
+
7
+ export type SettingsLayoutProps = Omit<
8
+ ComponentProps<typeof Tabs>,
9
+ 'children' | 'orientation' | 'value' | 'defaultValue' | 'onChange'
10
+ > & {
11
+ /** Grouped navigation entries; the host owns their values and panel content. */
12
+ groups: readonly SettingsNavigationGroup[]
13
+ /** Accessible name for the vertical tab list. */
14
+ 'aria-label': string
15
+ /** The host-controlled selected destination. */
16
+ value: string
17
+ /** Updates the host-controlled selected destination. */
18
+ onChange: (value: string) => void
19
+ /** Called when the already-selected destination is activated again. */
20
+ onReselect?: (value: string) => void
21
+ /** Reveal the selected row on value changes and window resizes. Defaults to nearest scroll. */
22
+ revealSelected?: boolean | ((trigger: HTMLButtonElement | undefined) => void)
23
+ /** Panels must be rendered as `TabsContent` descendants. */
24
+ children?: JSX.Element
25
+ }
26
+
27
+ /**
28
+ * SettingsLayout.
29
+ *
30
+ * A controlled, vertical settings rail beside its scrollable panel viewport.
31
+ * The host keeps ownership of selection, URL/hash state and panel content.
32
+ * At narrow viewports the rail contracts while both columns remain shrinkable.
33
+ */
34
+ export function SettingsLayout(props: SettingsLayoutProps) {
35
+ const [local, rest] = splitProps(props, [
36
+ 'class',
37
+ 'children',
38
+ 'groups',
39
+ 'aria-label',
40
+ 'value',
41
+ 'onReselect',
42
+ 'revealSelected',
43
+ ])
44
+
45
+ return (
46
+ <Tabs
47
+ {...rest}
48
+ orientation="vertical"
49
+ value={local.value}
50
+ class={cn('min-h-0 min-w-0 flex-1 gap-0', local.class)}
51
+ >
52
+ <SettingsNavigation
53
+ aria-label={local['aria-label']}
54
+ groups={local.groups}
55
+ value={local.value}
56
+ onReselect={local.onReselect}
57
+ revealSelected={local.revealSelected}
58
+ class="w-24 md:w-sidebar"
59
+ />
60
+ <div data-slot="settings-layout-panels" class="min-h-0 min-w-0 flex-1 overflow-y-auto p-4">
61
+ {local.children}
62
+ </div>
63
+ </Tabs>
64
+ )
65
+ }
@@ -0,0 +1,135 @@
1
+ import type { JSX } from 'solid-js'
2
+ import { createEffect, createUniqueId, onCleanup, splitProps } from 'solid-js'
3
+ import { cn } from '../../../lib/utils'
4
+ import { sidebarNavItemClass, sidebarNavItemStateClass } from '../../layout/sidebar-nav/sidebar-nav'
5
+ import { TabsList, TabsTrigger, type TabsListProps } from '../../ui/tabs'
6
+
7
+ /** One host-owned destination in a settings tab list. Values must be unique. */
8
+ export type SettingsNavigationItem = {
9
+ value: string
10
+ label: string
11
+ icon?: JSX.Element
12
+ disabled?: boolean
13
+ }
14
+
15
+ /** A visible, accessibly named group of settings destinations. */
16
+ export type SettingsNavigationGroup = {
17
+ label: string
18
+ items: readonly SettingsNavigationItem[]
19
+ }
20
+
21
+ export type SettingsNavigationProps = Omit<
22
+ TabsListProps,
23
+ 'appearance' | 'children' | 'orientation'
24
+ > & {
25
+ /** Groups are presentation only; the host owns the tab values and panels. */
26
+ groups: readonly SettingsNavigationGroup[]
27
+ /** The same controlled value supplied to the enclosing `Tabs`. */
28
+ value: string
29
+ /** Called when the already-selected destination is activated again. */
30
+ onReselect?: (value: string) => void
31
+ /** Reveal the selected row on value changes and window resizes. Defaults to nearest scroll. */
32
+ revealSelected?: boolean | ((trigger: HTMLButtonElement | undefined) => void)
33
+ /** Every tab list needs a label independent of its visible group headings. */
34
+ 'aria-label': string
35
+ }
36
+
37
+ /**
38
+ * SettingsNavigation.
39
+ *
40
+ * A grouped vertical tab list for sibling settings panels. It composes the
41
+ * shared Tabs behaviour with the shared sidebar row recipe; the host supplies
42
+ * the controlled value, panel content, icons and any persistence or routing.
43
+ * Use ordinary tabs for a short, ungrouped row of view choices.
44
+ *
45
+ * Kobalte owns roving focus, arrow keys, selection and tab/panel ARIA. This
46
+ * component adds no URL, storage or host-specific state. Set
47
+ * `revealSelected={false}` when the surrounding layout does not use an internal
48
+ * scrolling viewport.
49
+ */
50
+ export function SettingsNavigation(props: SettingsNavigationProps) {
51
+ const [local, rest] = splitProps(props, [
52
+ 'class',
53
+ 'aria-label',
54
+ 'groups',
55
+ 'value',
56
+ 'onReselect',
57
+ 'revealSelected',
58
+ ])
59
+ const triggers = new Map<string, HTMLButtonElement>()
60
+ const groupIdPrefix = `settings-navigation-${createUniqueId()}`
61
+
62
+ createEffect(() => {
63
+ const value = local.value
64
+ const reveal = local.revealSelected
65
+ if (reveal === false) return
66
+
67
+ const revealCurrent = () => {
68
+ const trigger = triggers.get(value)
69
+ if (typeof reveal === 'function') reveal(trigger)
70
+ else trigger?.scrollIntoView({ block: 'nearest', inline: 'nearest' })
71
+ }
72
+
73
+ revealCurrent()
74
+ window.addEventListener('resize', revealCurrent)
75
+ onCleanup(() => window.removeEventListener('resize', revealCurrent))
76
+ })
77
+
78
+ return (
79
+ <TabsList
80
+ data-slot="settings-navigation"
81
+ aria-label={local['aria-label']}
82
+ orientation="vertical"
83
+ class={cn(
84
+ 'flex max-h-full min-h-0 min-w-0 shrink-0 flex-col items-stretch justify-start gap-2 overflow-x-hidden overflow-y-auto px-2 py-2',
85
+ local.class
86
+ )}
87
+ {...rest}
88
+ >
89
+ {local.groups.map((group, groupIndex) => {
90
+ const groupId = `${groupIdPrefix}-group-${groupIndex}`
91
+ return (
92
+ <div
93
+ role="none"
94
+ data-slot="settings-navigation-group"
95
+ class="flex min-w-0 flex-col gap-0.5"
96
+ >
97
+ <span id={groupId} class="sr-only">
98
+ {group.label}
99
+ </span>
100
+ <span
101
+ aria-hidden="true"
102
+ class="px-2 py-1.5 text-2xs font-medium tracking-wide text-sidebar-muted-foreground uppercase"
103
+ >
104
+ {group.label}
105
+ </span>
106
+ {group.items.map((item) => (
107
+ <TabsTrigger
108
+ data-slot="settings-navigation-trigger"
109
+ orientation="vertical"
110
+ aria-describedby={groupId}
111
+ value={item.value}
112
+ disabled={item.disabled}
113
+ ref={(element: HTMLButtonElement | undefined) => {
114
+ if (element) triggers.set(item.value, element)
115
+ else triggers.delete(item.value)
116
+ }}
117
+ onClick={() => {
118
+ if (local.value === item.value) local.onReselect?.(item.value)
119
+ }}
120
+ class={cn(
121
+ sidebarNavItemClass,
122
+ sidebarNavItemStateClass.idle,
123
+ 'h-row-lg w-full justify-start border-0 px-3 py-2 text-left data-[selected]:bg-primary-subtle data-[selected]:text-foreground'
124
+ )}
125
+ >
126
+ {item.icon}
127
+ <span class="min-w-0 truncate">{item.label}</span>
128
+ </TabsTrigger>
129
+ ))}
130
+ </div>
131
+ )
132
+ })}
133
+ </TabsList>
134
+ )
135
+ }
@@ -11,6 +11,8 @@ export {
11
11
  sidebarNavItemStateClass,
12
12
  type SidebarNavItemProps,
13
13
  type SidebarNavProps,
14
+ type SidebarNavSectionProps,
15
+ type SidebarNavSectionTriggerProps,
14
16
  type SidebarNavTitleProps,
15
17
  } from './sidebar-nav'
16
18
  export {