@adea-ai/ui 0.106.2 → 0.108.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 (112) hide show
  1. package/dist/components/composites/appearance-editor/appearance-editor.d.ts +9 -3
  2. package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -1
  3. package/dist/components/composites/appearance-editor/appearance-editor.js +61 -29
  4. package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
  5. package/dist/components/composites/appearance-editor/appearance-types.d.ts +2 -0
  6. package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -1
  7. package/dist/components/composites/appearance-editor/index.d.ts +1 -1
  8. package/dist/components/composites/appearance-editor/index.d.ts.map +1 -1
  9. package/dist/components/composites/appearance-editor/index.js +2 -2
  10. package/dist/components/layout/contextual-sidebar/contextual-sidebar.d.ts +55 -0
  11. package/dist/components/layout/contextual-sidebar/contextual-sidebar.d.ts.map +1 -0
  12. package/dist/components/layout/contextual-sidebar/contextual-sidebar.js +199 -0
  13. package/dist/components/layout/contextual-sidebar/contextual-sidebar.js.map +1 -0
  14. package/dist/components/layout/contextual-sidebar/index.d.ts +3 -0
  15. package/dist/components/layout/contextual-sidebar/index.d.ts.map +1 -0
  16. package/dist/components/layout/contextual-sidebar/index.js +3 -0
  17. package/dist/components/layout/pixel-resize-handle/index.d.ts +2 -0
  18. package/dist/components/layout/pixel-resize-handle/index.d.ts.map +1 -0
  19. package/dist/components/layout/pixel-resize-handle/index.js +2 -0
  20. package/dist/components/layout/pixel-resize-handle/pixel-resize-handle.d.ts +29 -0
  21. package/dist/components/layout/pixel-resize-handle/pixel-resize-handle.d.ts.map +1 -0
  22. package/dist/components/layout/pixel-resize-handle/pixel-resize-handle.js +183 -0
  23. package/dist/components/layout/pixel-resize-handle/pixel-resize-handle.js.map +1 -0
  24. package/dist/components/layout/sidebar-nav/sidebar-nav-resize-handle.d.ts +3 -19
  25. package/dist/components/layout/sidebar-nav/sidebar-nav-resize-handle.d.ts.map +1 -1
  26. package/dist/components/layout/sidebar-nav/sidebar-nav-resize-handle.js +8 -76
  27. package/dist/components/layout/sidebar-nav/sidebar-nav-resize-handle.js.map +1 -1
  28. package/dist/components/ui/badge/badge.d.ts.map +1 -1
  29. package/dist/components/ui/badge/badge.js +9 -5
  30. package/dist/components/ui/badge/badge.js.map +1 -1
  31. package/dist/components/ui/combobox/combobox.d.ts.map +1 -1
  32. package/dist/components/ui/combobox/combobox.js +2 -2
  33. package/dist/components/ui/combobox/combobox.js.map +1 -1
  34. package/dist/components/ui/context-menu/context-menu.d.ts.map +1 -1
  35. package/dist/components/ui/context-menu/context-menu.js +3 -3
  36. package/dist/components/ui/context-menu/context-menu.js.map +1 -1
  37. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  38. package/dist/components/ui/dropdown-menu/dropdown-menu.js +7 -4
  39. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  40. package/dist/components/ui/menubar/menubar.d.ts.map +1 -1
  41. package/dist/components/ui/menubar/menubar.js +3 -3
  42. package/dist/components/ui/menubar/menubar.js.map +1 -1
  43. package/dist/components/ui/popover/popover.d.ts.map +1 -1
  44. package/dist/components/ui/popover/popover.js +2 -2
  45. package/dist/components/ui/popover/popover.js.map +1 -1
  46. package/dist/components/ui/resizable/resizable.d.ts.map +1 -1
  47. package/dist/components/ui/resizable/resizable.js +2 -2
  48. package/dist/components/ui/resizable/resizable.js.map +1 -1
  49. package/dist/components/ui/select/select.d.ts.map +1 -1
  50. package/dist/components/ui/select/select.js +2 -2
  51. package/dist/components/ui/select/select.js.map +1 -1
  52. package/dist/components/ui/sheet/sheet.d.ts +16 -0
  53. package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
  54. package/dist/components/ui/sheet/sheet.js +82 -16
  55. package/dist/components/ui/sheet/sheet.js.map +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +4 -2
  59. package/dist/lib/overlay.d.ts +15 -0
  60. package/dist/lib/overlay.d.ts.map +1 -1
  61. package/dist/lib/overlay.js +14 -1
  62. package/dist/lib/overlay.js.map +1 -1
  63. package/dist/lint/index.d.ts.map +1 -1
  64. package/dist/lint.js +154 -20
  65. package/dist/lint.js.map +1 -1
  66. package/dist/r/appearance-editor.json +1 -1
  67. package/dist/r/contextual-sidebar.json +25 -0
  68. package/dist/r/pixel-resize-handle.json +23 -0
  69. package/dist/r/registry.json +50 -2
  70. package/dist/r/sidebar-nav.json +1 -1
  71. package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +55 -33
  72. package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +2 -0
  73. package/dist/r/src/components/composites/appearance-editor/index.ts +1 -1
  74. package/dist/r/src/components/layout/contextual-sidebar/contextual-sidebar.tsx +180 -0
  75. package/dist/r/src/components/layout/contextual-sidebar/index.ts +6 -0
  76. package/dist/r/src/components/layout/pixel-resize-handle/index.ts +1 -0
  77. package/dist/r/src/components/layout/pixel-resize-handle/pixel-resize-handle.tsx +177 -0
  78. package/dist/r/src/components/layout/sidebar-nav/sidebar-nav-resize-handle.tsx +7 -55
  79. package/dist/r/src/components/ui/badge/badge.tsx +9 -5
  80. package/dist/r/src/components/ui/combobox/combobox.tsx +2 -1
  81. package/dist/r/src/components/ui/context-menu/context-menu.tsx +3 -0
  82. package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +9 -0
  83. package/dist/r/src/components/ui/menubar/menubar.tsx +3 -0
  84. package/dist/r/src/components/ui/popover/popover.tsx +8 -1
  85. package/dist/r/src/components/ui/resizable/resizable.tsx +4 -2
  86. package/dist/r/src/components/ui/select/select.tsx +2 -1
  87. package/dist/r/src/components/ui/sheet/sheet.tsx +78 -15
  88. package/dist/r/src/lib/overlay.ts +14 -0
  89. package/dist/r/src/styles/base.css +13 -0
  90. package/package.json +3 -1
  91. package/registry.json +50 -2
  92. package/src/components/composites/appearance-editor/appearance-editor.tsx +55 -33
  93. package/src/components/composites/appearance-editor/appearance-types.ts +2 -0
  94. package/src/components/composites/appearance-editor/index.ts +1 -1
  95. package/src/components/layout/contextual-sidebar/contextual-sidebar.tsx +180 -0
  96. package/src/components/layout/contextual-sidebar/index.ts +6 -0
  97. package/src/components/layout/pixel-resize-handle/index.ts +1 -0
  98. package/src/components/layout/pixel-resize-handle/pixel-resize-handle.tsx +177 -0
  99. package/src/components/layout/sidebar-nav/sidebar-nav-resize-handle.tsx +7 -55
  100. package/src/components/ui/badge/badge.tsx +9 -5
  101. package/src/components/ui/combobox/combobox.tsx +2 -1
  102. package/src/components/ui/context-menu/context-menu.tsx +3 -0
  103. package/src/components/ui/dropdown-menu/dropdown-menu.tsx +9 -0
  104. package/src/components/ui/menubar/menubar.tsx +3 -0
  105. package/src/components/ui/popover/popover.tsx +8 -1
  106. package/src/components/ui/resizable/resizable.tsx +4 -2
  107. package/src/components/ui/select/select.tsx +2 -1
  108. package/src/components/ui/sheet/sheet.tsx +78 -15
  109. package/src/index.ts +1 -0
  110. package/src/lib/overlay.ts +14 -0
  111. package/src/lint/index.ts +234 -22
  112. package/src/styles/base.css +13 -0
@@ -8,8 +8,14 @@ import type { AppearanceEditorProps, AppearancePopoverProps } from './appearance
8
8
  * accepted appearance surface; typeface settings are shared and host-persisted.
9
9
  */
10
10
  export declare function AppearanceEditor(props: AppearanceEditorProps): import("solid-js").JSX.Element;
11
- /** Modal anchoring/dismissal and nested-menu behavior come from Kobalte.
12
- * Its measured available height also bounds scrolling, keeping footer actions
13
- * reachable when a narrow popup begins below its trigger. */
11
+ /**
12
+ * Reset, Cancel and Save, with the reason Save is unavailable. Rendered by the
13
+ * editor itself, or — with `hideActions` — by a host that pins them in its own
14
+ * footer, as `AppearancePopover` does.
15
+ */
16
+ export declare function AppearanceEditorActions(props: AppearanceEditorProps): import("solid-js").JSX.Element;
17
+ /** The editor in an inset Sheet docked beside the main view: the body scrolls and
18
+ * Reset/Cancel/Save sit in the panel's full-width footer, always reachable.
19
+ * Dismissal (Escape, the close button, an outside click) is `onDismiss`. */
14
20
  export declare function AppearancePopover(props: AppearancePopoverProps): import("solid-js").JSX.Element;
15
21
  //# sourceMappingURL=appearance-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-editor.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAIvF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kCA2K5D;AAED;;6DAE6D;AAC7D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,kCA8B9D"}
1
+ {"version":3,"file":"appearance-editor.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAIvF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kCA0I5D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,kCA6CnE;AAED;;4EAE4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,kCA8B9D"}
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
2
  import { Button } from "../../ui/button/button.js";
3
3
  import { Input } from "../../ui/input/input.js";
4
- import { Popover, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger } from "../../ui/popover/popover.js";
4
+ import { Sheet, SheetBody, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "../../ui/sheet/sheet.js";
5
5
  import { Switch } from "../../ui/switch/switch.js";
6
6
  import { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS } from "../../../lib/appearance-font-settings.js";
7
7
  import { SettingsRow, TerminalRow, ThemeRow } from "./appearance-rows.js";
@@ -15,8 +15,10 @@ var _tmpl$ = /*#__PURE__*/ template(`<p role=status class="px-4 py-2 text-sm tex
15
15
  var _tmpl$2 = /*#__PURE__*/ template(`<p role=alert class="mt-1 text-xs text-foreground">`);
16
16
  var _tmpl$3 = /*#__PURE__*/ template(`<div class="px-4 py-3"><label class="mb-2 block text-xs font-medium">Custom accent`);
17
17
  var _tmpl$4 = /*#__PURE__*/ template(`<p role=status class="px-4 py-2 text-xs text-muted-foreground">`);
18
- var _tmpl$5 = /*#__PURE__*/ template(`<p role=status class="px-4 pt-3 text-xs text-muted-foreground">`);
19
- var _tmpl$6 = /*#__PURE__*/ template(`<div data-appearance-editor><div class="divide-y divide-border rounded-lg border"></div><div class="global-appearance-editor-actions sticky bottom-0 z-10 mt-2 flex flex-wrap items-center gap-2 border-t bg-background px-4 py-3"><div class="ml-auto flex gap-2">`);
18
+ var _tmpl$5 = /*#__PURE__*/ template(`<div class="sticky bottom-0 z-10 mt-2 border-t bg-background px-4 py-3">`);
19
+ var _tmpl$6 = /*#__PURE__*/ template(`<div data-appearance-editor><div class="divide-y divide-border rounded-lg border">`);
20
+ var _tmpl$7 = /*#__PURE__*/ template(`<p role=status class="text-xs text-muted-foreground">`);
21
+ var _tmpl$8 = /*#__PURE__*/ template(`<div class="flex w-full flex-col gap-2"><div class="global-appearance-editor-actions flex flex-wrap items-center gap-2"><div class="ml-auto flex gap-2">`);
20
22
  /**
21
23
  * A live editor whose persistence and preview authority belong to its host.
22
24
  * No ThemeProvider is required, and no catalogue, renderer engine or storage is
@@ -27,7 +29,6 @@ var _tmpl$6 = /*#__PURE__*/ template(`<div data-appearance-editor><div class="di
27
29
  */
28
30
  function AppearanceEditor(props) {
29
31
  const errorId = createUniqueId();
30
- const saveReasonId = createUniqueId();
31
32
  const custom = () => isCustomAccent(props);
32
33
  const accentDescription = () => {
33
34
  if (props.draft.accent === "theme") return "Theme default · Uses the palette's intended color.";
@@ -39,7 +40,7 @@ function AppearanceEditor(props) {
39
40
  };
40
41
  const glassDescription = () => props.draft.surface === "opaque" ? "Solid surfaces for every theme." : props.draft.surface === "frosted" ? "Theme-colored glass where supported." : props.surfaceCapability.themeDefaultDescription ?? "Uses this theme's default surface.";
41
42
  return (() => {
42
- var _el$ = _tmpl$6(), _el$3 = _el$.firstChild, _el$9 = _el$3.nextSibling, _el$0 = _el$9.firstChild;
43
+ var _el$ = _tmpl$6(), _el$3 = _el$.firstChild;
43
44
  insert(_el$, createComponent(Show, {
44
45
  get when() {
45
46
  return props.recoveryNotice;
@@ -230,16 +231,39 @@ function AppearanceEditor(props) {
230
231
  }), null);
231
232
  insert(_el$, createComponent(Show, {
232
233
  get when() {
233
- return props.saveDisabledReason;
234
+ return !props.hideActions;
234
235
  },
235
236
  get children() {
236
237
  var _el$8 = _tmpl$5();
237
- setAttribute(_el$8, "id", saveReasonId);
238
- insert(_el$8, () => props.saveDisabledReason);
238
+ insert(_el$8, createComponent(AppearanceEditorActions, props));
239
239
  return _el$8;
240
240
  }
241
- }), _el$9);
242
- insert(_el$9, createComponent(Button, {
241
+ }), null);
242
+ effect(() => className(_el$, cn("min-w-0", props.class)));
243
+ return _el$;
244
+ })();
245
+ }
246
+ /**
247
+ * Reset, Cancel and Save, with the reason Save is unavailable. Rendered by the
248
+ * editor itself, or — with `hideActions` — by a host that pins them in its own
249
+ * footer, as `AppearancePopover` does.
250
+ */
251
+ function AppearanceEditorActions(props) {
252
+ const saveReasonId = createUniqueId();
253
+ return (() => {
254
+ var _el$9 = _tmpl$8(), _el$1 = _el$9.firstChild, _el$10 = _el$1.firstChild;
255
+ insert(_el$9, createComponent(Show, {
256
+ get when() {
257
+ return props.saveDisabledReason;
258
+ },
259
+ get children() {
260
+ var _el$0 = _tmpl$7();
261
+ setAttribute(_el$0, "id", saveReasonId);
262
+ insert(_el$0, () => props.saveDisabledReason);
263
+ return _el$0;
264
+ }
265
+ }), _el$1);
266
+ insert(_el$1, createComponent(Button, {
243
267
  type: "button",
244
268
  size: "sm",
245
269
  variant: "ghost",
@@ -248,8 +272,8 @@ function AppearanceEditor(props) {
248
272
  },
249
273
  onClick: () => props.onReset(),
250
274
  children: "Reset"
251
- }), _el$0);
252
- insert(_el$0, createComponent(Button, {
275
+ }), _el$10);
276
+ insert(_el$10, createComponent(Button, {
253
277
  type: "button",
254
278
  size: "sm",
255
279
  variant: "outline",
@@ -259,7 +283,7 @@ function AppearanceEditor(props) {
259
283
  onClick: () => props.onCancel(),
260
284
  children: "Cancel"
261
285
  }), null);
262
- insert(_el$0, createComponent(Button, {
286
+ insert(_el$10, createComponent(Button, {
263
287
  type: "button",
264
288
  size: "sm",
265
289
  get disabled() {
@@ -276,23 +300,21 @@ function AppearanceEditor(props) {
276
300
  return props.saving ? "Saving…" : "Save";
277
301
  }
278
302
  }), null);
279
- effect(() => className(_el$, cn("min-w-0", props.class)));
280
- return _el$;
303
+ return _el$9;
281
304
  })();
282
305
  }
283
- /** Modal anchoring/dismissal and nested-menu behavior come from Kobalte.
284
- * Its measured available height also bounds scrolling, keeping footer actions
285
- * reachable when a narrow popup begins below its trigger. */
306
+ /** The editor in an inset Sheet docked beside the main view: the body scrolls and
307
+ * Reset/Cancel/Save sit in the panel's full-width footer, always reachable.
308
+ * Dismissal (Escape, the close button, an outside click) is `onDismiss`. */
286
309
  function AppearancePopover(props) {
287
310
  const [menuPortalMount, setMenuPortalMount] = createSignal();
288
- return createComponent(Popover, {
311
+ return createComponent(Sheet, {
289
312
  get open() {
290
313
  return props.open;
291
314
  },
292
- modal: true,
293
315
  onOpenChange: (open) => open ? props.onOpen() : props.onDismiss(),
294
316
  get children() {
295
- return [createComponent(PopoverTrigger, {
317
+ return [createComponent(SheetTrigger, {
296
318
  as: Button,
297
319
  type: "button",
298
320
  variant: "ghost",
@@ -301,16 +323,26 @@ function AppearancePopover(props) {
301
323
  get children() {
302
324
  return createComponent(Palette, {});
303
325
  }
304
- }), createComponent(PopoverContent, {
326
+ }), createComponent(SheetContent, {
327
+ side: "end",
328
+ closeLabel: "Close appearance settings",
305
329
  ref: setMenuPortalMount,
306
- "class": "w-lg max-w-[calc(100vw-2rem)] max-h-(--kb-popper-content-available-height) overflow-y-auto",
307
330
  get children() {
308
331
  return [
309
- createComponent(PopoverTitle, { children: "Appearance" }),
310
- createComponent(PopoverDescription, { children: "Changes preview immediately. Save keeps them; Cancel restores the previous appearance." }),
311
- createComponent(AppearanceEditor, mergeProps(props, { get menuPortalMount() {
312
- return menuPortalMount();
313
- } }))
332
+ createComponent(SheetHeader, { get children() {
333
+ return [createComponent(SheetTitle, { children: "Appearance" }), createComponent(SheetDescription, { children: "Changes preview immediately. Save keeps them; Cancel restores the previous appearance." })];
334
+ } }),
335
+ createComponent(SheetBody, { get children() {
336
+ return createComponent(AppearanceEditor, mergeProps(props, {
337
+ get menuPortalMount() {
338
+ return menuPortalMount();
339
+ },
340
+ hideActions: true
341
+ }));
342
+ } }),
343
+ createComponent(SheetFooter, { get children() {
344
+ return createComponent(AppearanceEditorActions, props);
345
+ } })
314
346
  ];
315
347
  }
316
348
  })];
@@ -318,6 +350,6 @@ function AppearancePopover(props) {
318
350
  });
319
351
  }
320
352
  //#endregion
321
- export { AppearanceEditor, AppearancePopover };
353
+ export { AppearanceEditor, AppearanceEditorActions, AppearancePopover };
322
354
 
323
355
  //# sourceMappingURL=appearance-editor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-editor.js","names":["EyeOff","Palette","PanelsTopLeft","SlidersHorizontal","Show","createSignal","createUniqueId","cn","Button","Input","AppearanceFontSettingsGroup","DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS","Switch","Popover","PopoverContent","PopoverDescription","PopoverTitle","PopoverTrigger","AppearanceEditorProps","AppearancePopoverProps","ModeChoices","AccentChoices","GlassChoices","isCustomAccent","SettingsRow","TerminalRow","ThemeRow","AppearanceEditor","props","errorId","saveReasonId","custom","accentDescription","draft","accent","preset","accentOptions","find","option","id","label","offered","themeAccentOptions","toLowerCase","glassDescription","surface","surfaceCapability","themeDefaultDescription","_el$","_tmpl$6","_el$3","firstChild","_el$9","nextSibling","_el$0","_$insert","_$createComponent","when","recoveryNotice","children","_el$2","_tmpl$","appearance","selectedId","lightThemeId","preview","lightTheme","themes","disabled","saving","onSelect","onChange","darkThemeId","darkTheme","terminalThemeId","undefined","_$memo","resolvedAppearance","title","icon","description","_el$4","_tmpl$3","_el$5","_$setAttribute","value","aria-invalid","customAccentError","aria-describedby","onInput","event","currentTarget","_el$6","_tmpl$2","settings","fonts","menuPortalMount","frosted","reason","_el$7","_tmpl$4","checked","reduceTransparency","onManageThemes","type","size","variant","onClick","saveDisabledReason","_el$8","_tmpl$5","onReset","onCancel","aria-busy","onSave","_$effect","_$className","class","AppearancePopover","setMenuPortalMount","HTMLElement","open","modal","onOpenChange","onOpen","onDismiss","as","ref","_$mergeProps","_$createComponent","_$memo","_$className","_$mergeProps"],"sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n/*\n * Composition substantially translated from Zeron settings/appearance.rs and\n * settings/widgets.rs, pinned at 30a9a9537c5ec96226c87f4bf349b6f77c5dfb59,\n * preserving Adea's existing appearance-surface.tsx port: System/Light/Dark\n * miniatures, compact independent theme rows, accent swatches and helper copy,\n * glass chips, and theme library affordance. Kobalte replaces the port's manual\n * radio keyboard model. The controlled draft and explicit action ports replace\n * GPUI globals and app-specific storage/native authority. Save/Cancel/Reset and\n * custom accent/reduced-transparency are accepted Adea divergences (#425).\n */\nimport { EyeOff, Palette, PanelsTopLeft, SlidersHorizontal } from 'lucide-solid'\nimport { Show, createSignal, createUniqueId } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button } from '../../ui/button/button'\nimport { Input } from '../../ui/input/input'\nimport { AppearanceFontSettingsGroup } from './font-settings-group'\nimport { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS } from '#lib/appearance-font-settings'\n\nimport { Switch } from '../../ui/switch/switch'\nimport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverTitle,\n PopoverTrigger,\n} from '../../ui/popover/popover'\nimport type { AppearanceEditorProps, AppearancePopoverProps } from './appearance-types'\nimport { ModeChoices, AccentChoices, GlassChoices, isCustomAccent } from './appearance-choices'\nimport { SettingsRow, TerminalRow, ThemeRow } from './appearance-rows'\n\n/**\n * A live editor whose persistence and preview authority belong to its host.\n * No ThemeProvider is required, and no catalogue, renderer engine or storage is\n * imported. Hosts normalize unknown IDs and custom colors, report recovery,\n * snapshot on open, preview on changes, commit on Save, and restore on dismissal.\n * Both theme rows remain mounted when mode changes. Density remains outside the\n * accepted appearance surface; typeface settings are shared and host-persisted.\n */\nexport function AppearanceEditor(props: AppearanceEditorProps) {\n const errorId = createUniqueId()\n const saveReasonId = createUniqueId()\n const custom = () => isCustomAccent(props)\n const accentDescription = () => {\n if (props.draft.accent === 'theme') return \"Theme default · Uses the palette's intended color.\"\n const preset = props.accentOptions.find((option) => option.id === props.draft.accent)\n if (preset) return `${preset.label} · Controls, glyphs, selections, code, and activity.`\n if (custom()) return 'Custom · Controls, glyphs, selections, code, and activity.'\n const offered = props.themeAccentOptions?.find((option) => option.id === props.draft.accent)\n // A stored theme accent survives a theme switch by id; when the new pair\n // cannot offer that slot the host falls back to the theme's own primary,\n // and the description says so rather than naming a colour not on screen.\n return offered\n ? `Theme ${offered.label.toLowerCase()} · The theme's own color, on controls and activity.`\n : \"Theme default · This theme does not carry that accent, so it uses the palette's intended color.\"\n }\n const glassDescription = () =>\n props.draft.surface === 'opaque'\n ? 'Solid surfaces for every theme.'\n : props.draft.surface === 'frosted'\n ? 'Theme-colored glass where supported.'\n : (props.surfaceCapability.themeDefaultDescription ?? \"Uses this theme's default surface.\")\n return (\n <div data-appearance-editor class={cn('min-w-0', props.class)}>\n <Show when={props.recoveryNotice}>\n <p role=\"status\" class=\"px-4 py-2 text-sm text-muted-foreground\">\n {props.recoveryNotice}\n </p>\n </Show>\n <ModeChoices {...props} />\n <div class=\"divide-y divide-border rounded-lg border\">\n <ThemeRow\n appearance=\"light\"\n selectedId={props.draft.lightThemeId}\n preview={props.lightTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(lightThemeId) => props.onChange({ lightThemeId })}\n />\n <ThemeRow\n appearance=\"dark\"\n selectedId={props.draft.darkThemeId}\n preview={props.darkTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(darkThemeId) => props.onChange({ darkThemeId })}\n />\n {/* The row exists only when the host carries a terminal preference:\n the draft field is the show/hide switch, so the editor can never\n render a terminal row that writes nothing. */}\n <Show when={props.draft.terminalThemeId !== undefined}>\n <TerminalRow\n selectedId={props.draft.terminalThemeId ?? 'theme'}\n preview={props.resolvedAppearance === 'dark' ? props.darkTheme : props.lightTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(terminalThemeId) => props.onChange({ terminalThemeId })}\n />\n </Show>\n <SettingsRow title=\"Accent\" icon={<SlidersHorizontal />} description={accentDescription()}>\n <AccentChoices {...props} />\n </SettingsRow>\n <Show when={custom()}>\n <div class=\"px-4 py-3\">\n <label class=\"mb-2 block text-xs font-medium\" for={`${errorId}-input`}>\n Custom accent\n </label>\n <Input\n id={`${errorId}-input`}\n value={props.draft.accent}\n disabled={props.saving}\n aria-invalid={!!props.customAccentError}\n aria-describedby={props.customAccentError ? errorId : undefined}\n onInput={(event) => props.onChange({ accent: event.currentTarget.value })}\n />\n <Show when={props.customAccentError}>\n <p id={errorId} role=\"alert\" class=\"mt-1 text-xs text-foreground\">\n {props.customAccentError}\n </p>\n </Show>\n </div>\n </Show>\n <AppearanceFontSettingsGroup\n settings={props.draft.fonts ?? DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS}\n menuPortalMount={props.menuPortalMount}\n disabled={props.saving}\n onChange={(fonts) => props.onChange({ fonts })}\n />\n <SettingsRow title=\"Glass\" icon={<PanelsTopLeft />} description={glassDescription()}>\n <GlassChoices {...props} />\n </SettingsRow>\n <Show when={!props.surfaceCapability.frosted && props.surfaceCapability.reason}>\n <p role=\"status\" class=\"px-4 py-2 text-xs text-muted-foreground\">\n {props.surfaceCapability.reason}\n </p>\n </Show>\n <SettingsRow\n title=\"Reduce transparency\"\n icon={<EyeOff />}\n description=\"Prefer solid surfaces, including during live preview.\"\n >\n <Switch\n checked={props.draft.reduceTransparency}\n disabled={props.saving}\n onChange={(reduceTransparency: boolean) => props.onChange({ reduceTransparency })}\n aria-label=\"Reduce transparency\"\n />\n </SettingsRow>\n <SettingsRow\n title=\"Theme library\"\n icon={<Palette />}\n description={\n props.onManageThemes\n ? 'Manage themes through the application.'\n : 'Theme import is unavailable.'\n }\n >\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={!props.onManageThemes || props.saving}\n onClick={() => props.onManageThemes?.()}\n >\n Manage themes\n </Button>\n </SettingsRow>\n </div>\n <Show when={props.saveDisabledReason}>\n <p id={saveReasonId} role=\"status\" class=\"px-4 pt-3 text-xs text-muted-foreground\">\n {props.saveDisabledReason}\n </p>\n </Show>\n {/* Sticky so Save/Cancel stay reachable in a tall scroll container: the\n editor scrolls with its host panel, and actions parked at the bottom\n of a long form were unreachable without scrolling past every row. */}\n <div class=\"global-appearance-editor-actions sticky bottom-0 z-10 mt-2 flex flex-wrap items-center gap-2 border-t bg-background px-4 py-3\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n disabled={props.saving}\n onClick={() => props.onReset()}\n >\n Reset\n </Button>\n <div class=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={props.saving}\n onClick={() => props.onCancel()}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={props.saving || !!props.customAccentError || !!props.saveDisabledReason}\n aria-busy={props.saving}\n aria-describedby={props.saveDisabledReason ? saveReasonId : undefined}\n onClick={() => props.onSave()}\n >\n {props.saving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\n/** Modal anchoring/dismissal and nested-menu behavior come from Kobalte.\n * Its measured available height also bounds scrolling, keeping footer actions\n * reachable when a narrow popup begins below its trigger. */\nexport function AppearancePopover(props: AppearancePopoverProps) {\n const [menuPortalMount, setMenuPortalMount] = createSignal<HTMLElement>()\n\n return (\n <Popover\n open={props.open}\n modal\n onOpenChange={(open) => (open ? props.onOpen() : props.onDismiss())}\n >\n <PopoverTrigger\n as={Button}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Appearance settings\"\n >\n <Palette />\n </PopoverTrigger>\n <PopoverContent\n ref={setMenuPortalMount}\n class=\"w-lg max-w-[calc(100vw-2rem)] max-h-(--kb-popper-content-available-height) overflow-y-auto\"\n >\n <PopoverTitle>Appearance</PopoverTitle>\n <PopoverDescription>\n Changes preview immediately. Save keeps them; Cancel restores the previous appearance.\n </PopoverDescription>\n <AppearanceEditor {...props} menuPortalMount={menuPortalMount()} />\n </PopoverContent>\n </Popover>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB2B,iBAAiBC,OAA8B;CAC7D,MAAMC,UAAUvB,eAAe;CAC/B,MAAMwB,eAAexB,eAAe;CACpC,MAAMyB,eAAeR,eAAeK,KAAK;CACzC,MAAMI,0BAA0B;EAC9B,IAAIJ,MAAMK,MAAMC,WAAW,SAAS,OAAO;EAC3C,MAAMC,SAASP,MAAMQ,cAAcC,MAAMC,WAAWA,OAAOC,OAAOX,MAAMK,MAAMC,MAAM;EACpF,IAAIC,QAAQ,OAAO,GAAGA,OAAOK,MAAK;EAClC,IAAIT,OAAO,GAAG,OAAO;EACrB,MAAMU,UAAUb,MAAMc,oBAAoBL,MAAMC,WAAWA,OAAOC,OAAOX,MAAMK,MAAMC,MAAM;EAI3F,OAAOO,UACH,SAASA,QAAQD,MAAMG,YAAY,EAAC,uDACpC;CACN;CACA,MAAMC,yBACJhB,MAAMK,MAAMY,YAAY,WACpB,oCACAjB,MAAMK,MAAMY,YAAY,YACtB,yCACCjB,MAAMkB,kBAAkBC,2BAA2B;CAC5D,cAAA;EAAA,IAAAC,OAAAC,QAAA,GAAAC,QAAAF,KAAAG,YAAAC,QAAAF,MAAAG,aAAAC,QAAAF,MAAAD;EAAAI,OAAAP,MAAAQ,gBAEKpD,MAAI;GAAA,IAACqD,OAAI;IAAA,OAAE7B,MAAM8B;GAAc;GAAA,IAAAC,WAAA;IAAA,IAAAC,QAAAC,OAAA;IAAAN,OAAAK,aAE3BhC,MAAM8B,cAAc;IAAA,OAAAE;GAAA;EAAA,CAAA,GAAAV,KAAA;EAAAK,OAAAP,MAAAQ,gBAGxBpC,aAAgBQ,KAAK,GAAAsB,KAAA;EAAAK,OAAAL,OAAAM,gBAEnB9B,UAAQ;GACPoC,YAAU;GAAA,IACVC,aAAU;IAAA,OAAEnC,MAAMK,MAAM+B;GAAY;GAAA,IACpCC,UAAO;IAAA,OAAErC,MAAMsC;GAAU;GAAA,IACzBC,SAAM;IAAA,OAAEvC,MAAMuC;GAAM;GAAA,IACpBC,WAAQ;IAAA,OAAExC,MAAMyC;GAAM;GACtBC,WAAWN,iBAAiBpC,MAAM2C,SAAS,EAAEP,aAAa,CAAC;EAAC,CAAA,GAAA,IAAA;EAAAT,OAAAL,OAAAM,gBAE7D9B,UAAQ;GACPoC,YAAU;GAAA,IACVC,aAAU;IAAA,OAAEnC,MAAMK,MAAMuC;GAAW;GAAA,IACnCP,UAAO;IAAA,OAAErC,MAAM6C;GAAS;GAAA,IACxBN,SAAM;IAAA,OAAEvC,MAAMuC;GAAM;GAAA,IACpBC,WAAQ;IAAA,OAAExC,MAAMyC;GAAM;GACtBC,WAAWE,gBAAgB5C,MAAM2C,SAAS,EAAEC,YAAY,CAAC;EAAC,CAAA,GAAA,IAAA;EAAAjB,OAAAL,OAAAM,gBAK3DpD,MAAI;GAAA,IAACqD,OAAI;IAAA,OAAE7B,MAAMK,MAAMyC,oBAAoBC,KAAAA;GAAS;GAAA,IAAAhB,WAAA;IAAA,OAAAH,gBAClD/B,aAAW;KAAA,IACVsC,aAAU;MAAA,OAAEnC,MAAMK,MAAMyC,mBAAmB;KAAO;KAAA,IAClDT,UAAO;MAAA,OAAEW,WAAAhD,MAAMiD,uBAAuB,MAAM,CAAA,CAAA,IAAGjD,MAAM6C,YAAY7C,MAAMsC;KAAU;KAAA,IACjFC,SAAM;MAAA,OAAEvC,MAAMuC;KAAM;KAAA,IACpBC,WAAQ;MAAA,OAAExC,MAAMyC;KAAM;KACtBC,WAAWI,oBAAoB9C,MAAM2C,SAAS,EAAEG,gBAAgB,CAAC;IAAC,CAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAAnB,OAAAL,OAAAM,gBAGrEhC,aAAW;GAACsD,OAAK;GAAA,IAAUC,OAAI;IAAA,OAAAvB,gBAAGrD,mBAAiB,CAAA,CAAA;GAAA;GAAA,IAAK6E,cAAW;IAAA,OAAEhD,kBAAkB;GAAC;GAAA,IAAA2B,WAAA;IAAA,OAAAH,gBACtFnC,eAAkBO,KAAK;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA2B,OAAAL,OAAAM,gBAEzBpD,MAAI;GAAA,IAACqD,OAAI;IAAA,OAAE1B,OAAO;GAAC;GAAA,IAAA4B,WAAA;IAAA,IAAAsB,QAAAC,QAAA,GAAAC,QAAAF,MAAA9B;IAAAiC,aAAAD,OAAA,OAEmC,GAAGtD,QAAO,OAAQ;IAAA0B,OAAA0B,OAAAzB,gBAGpE/C,OAAK;KACJ8B,IAAI,GAAGV,QAAO;KAAQ,IACtBwD,QAAK;MAAA,OAAEzD,MAAMK,MAAMC;KAAM;KAAA,IACzBkC,WAAQ;MAAA,OAAExC,MAAMyC;KAAM;KAAA,KAAA,kBAAA;MAAA,OACR,CAAC,CAACzC,MAAM2D;KAAiB;KAAA,KAAA,sBAAA;MAAA,OACrB3D,MAAM2D,oBAAoB1D,UAAU8C,KAAAA;KAAS;KAC/Dc,UAAUC,UAAU9D,MAAM2C,SAAS,EAAErC,QAAQwD,MAAMC,cAAcN,MAAM,CAAC;IAAC,CAAA,GAAA,IAAA;IAAA9B,OAAA0B,OAAAzB,gBAE1EpD,MAAI;KAAA,IAACqD,OAAI;MAAA,OAAE7B,MAAM2D;KAAiB;KAAA,IAAA5B,WAAA;MAAA,IAAAiC,QAAAC,QAAA;MAAAT,aAAAQ,OAAA,MAC1B/D,OAAO;MAAA0B,OAAAqC,aACXhE,MAAM2D,iBAAiB;MAAA,OAAAK;KAAA;IAAA,CAAA,GAAA,IAAA;IAAA,OAAAX;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA1B,OAAAL,OAAAM,gBAK/B9C,6BAA2B;GAAA,IAC1BoF,WAAQ;IAAA,OAAElE,MAAMK,MAAM8D,SAASpF;GAAuC;GAAA,IACtEqF,kBAAe;IAAA,OAAEpE,MAAMoE;GAAe;GAAA,IACtC5B,WAAQ;IAAA,OAAExC,MAAMyC;GAAM;GACtBE,WAAWwB,UAAUnE,MAAM2C,SAAS,EAAEwB,MAAM,CAAC;EAAC,CAAA,GAAA,IAAA;EAAAxC,OAAAL,OAAAM,gBAE/ChC,aAAW;GAACsD,OAAK;GAAA,IAASC,OAAI;IAAA,OAAAvB,gBAAGtD,eAAa,CAAA,CAAA;GAAA;GAAA,IAAK8E,cAAW;IAAA,OAAEpC,iBAAiB;GAAC;GAAA,IAAAe,WAAA;IAAA,OAAAH,gBAChFlC,cAAiBM,KAAK;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA2B,OAAAL,OAAAM,gBAExBpD,MAAI;GAAA,IAACqD,OAAI;IAAA,OAAEmB,WAAA,CAAA,CAAA,CAAChD,MAAMkB,kBAAkBmD,OAAO,CAAA,CAAA,KAAIrE,MAAMkB,kBAAkBoD;GAAM;GAAA,IAAAvC,WAAA;IAAA,IAAAwC,QAAAC,QAAA;IAAA7C,OAAA4C,aAEzEvE,MAAMkB,kBAAkBoD,MAAM;IAAA,OAAAC;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA5C,OAAAL,OAAAM,gBAGlChC,aAAW;GACVsD,OAAK;GAAA,IACLC,OAAI;IAAA,OAAAvB,gBAAGxD,QAAM,CAAA,CAAA;GAAA;GACbgF,aAAW;GAAA,IAAArB,WAAA;IAAA,OAAAH,gBAEV5C,QAAM;KAAA,IACLyF,UAAO;MAAA,OAAEzE,MAAMK,MAAMqE;KAAkB;KAAA,IACvClC,WAAQ;MAAA,OAAExC,MAAMyC;KAAM;KACtBE,WAAW+B,uBAAgC1E,MAAM2C,SAAS,EAAE+B,mBAAmB,CAAC;KAAC,cAAA;IAAA,CAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAA/C,OAAAL,OAAAM,gBAIpFhC,aAAW;GACVsD,OAAK;GAAA,IACLC,OAAI;IAAA,OAAAvB,gBAAGvD,SAAO,CAAA,CAAA;GAAA;GAAA,IACd+E,cAAW;IAAA,OACTpD,MAAM2E,iBACF,2CACA;GAA8B;GAAA,IAAA5C,WAAA;IAAA,OAAAH,gBAGnChD,QAAM;KACLgG,MAAI;KACJC,MAAI;KACJC,SAAO;KAAA,IACPtC,WAAQ;MAAA,OAAE,CAACxC,MAAM2E,kBAAkB3E,MAAMyC;KAAM;KAC/CsC,eAAe/E,MAAM2E,iBAAiB;KAAC5C,UAAA;IAAA,CAAA;GAAA;EAAA,CAAA,GAAA,IAAA;EAAAJ,OAAAP,MAAAQ,gBAM5CpD,MAAI;GAAA,IAACqD,OAAI;IAAA,OAAE7B,MAAMgF;GAAkB;GAAA,IAAAjD,WAAA;IAAA,IAAAkD,QAAAC,QAAA;IAAA1B,aAAAyB,OAAA,MAC3B/E,YAAY;IAAAyB,OAAAsD,aAChBjF,MAAMgF,kBAAkB;IAAA,OAAAC;GAAA;EAAA,CAAA,GAAAzD,KAAA;EAAAG,OAAAH,OAAAI,gBAO1BhD,QAAM;GACLgG,MAAI;GACJC,MAAI;GACJC,SAAO;GAAA,IACPtC,WAAQ;IAAA,OAAExC,MAAMyC;GAAM;GACtBsC,eAAe/E,MAAMmF,QAAQ;GAACpD,UAAA;EAAA,CAAA,GAAAL,KAAA;EAAAC,OAAAD,OAAAE,gBAK7BhD,QAAM;GACLgG,MAAI;GACJC,MAAI;GACJC,SAAO;GAAA,IACPtC,WAAQ;IAAA,OAAExC,MAAMyC;GAAM;GACtBsC,eAAe/E,MAAMoF,SAAS;GAACrD,UAAA;EAAA,CAAA,GAAA,IAAA;EAAAJ,OAAAD,OAAAE,gBAIhChD,QAAM;GACLgG,MAAI;GACJC,MAAI;GAAA,IACJrC,WAAQ;IAAA,OAAExC,MAAMyC,UAAU,CAAC,CAACzC,MAAM2D,qBAAqB,CAAC,CAAC3D,MAAMgF;GAAkB;GAAA,KAAA,eAAA;IAAA,OACtEhF,MAAMyC;GAAM;GAAA,KAAA,sBAAA;IAAA,OACLzC,MAAMgF,qBAAqB9E,eAAe6C,KAAAA;GAAS;GACrEgC,eAAe/E,MAAMsF,OAAO;GAAC,IAAAvD,WAAA;IAAA,OAE5B/B,MAAMyC,SAAS,YAAY;GAAM;EAAA,CAAA,GAAA,IAAA;EAAA8C,aAAAC,UAAApE,MA7IPzC,GAAG,WAAWqB,MAAMyF,KAAK,CAAC,CAAA;EAAA,OAAArE;CAAA,EAAA,CAAA;AAmJjE;;;;AAKA,SAAgBsE,kBAAkB1F,OAA+B;CAC/D,MAAM,CAACoE,iBAAiBuB,sBAAsBlH,aAA0B;CAExE,OAAAmD,gBACG3C,SAAO;EAAA,IACN4G,OAAI;GAAA,OAAE7F,MAAM6F;EAAI;EAChBC,OAAK;EACLC,eAAeF,SAAUA,OAAO7F,MAAMgG,OAAO,IAAIhG,MAAMiG,UAAU;EAAE,IAAAlE,WAAA;GAAA,OAAA,CAAAH,gBAElEvC,gBAAc;IACb6G,IAAItH;IACJgG,MAAI;IACJE,SAAO;IACPD,MAAI;IAAA,cAAA;IAAA,IAAA9C,WAAA;KAAA,OAAAH,gBAGHvD,SAAO,CAAA,CAAA;IAAA;GAAA,CAAA,GAAAuD,gBAET1C,gBAAc;IAAAiH,KACRR;IAAkB,SAAA;IAAA,IAAA5D,WAAA;KAAA,OAAA;MAAAH,gBAGtBxC,cAAY,EAAA2C,UAAA,aAAA,CAAA;MAAAH,gBACZzC,oBAAkB,EAAA4C,UAAA,yFAAA,CAAA;MAAAH,gBAGlB7B,kBAAgBqG,WAAKpG,OAAK,EAAA,IAAEoE,kBAAe;OAAA,OAAEA,gBAAgB;MAAC,EAAA,CAAA,CAAA;KAAA;IAAA;GAAA,CAAA,CAAA;EAAA;CAAA,CAAA;AAIvE"}
1
+ {"version":3,"file":"appearance-editor.js","names":["EyeOff","Palette","PanelsTopLeft","SlidersHorizontal","Show","createSignal","createUniqueId","cn","Button","Input","AppearanceFontSettingsGroup","DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS","Switch","Sheet","SheetBody","SheetContent","SheetDescription","SheetFooter","SheetHeader","SheetTitle","SheetTrigger","AppearanceEditorProps","AppearancePopoverProps","ModeChoices","AccentChoices","GlassChoices","isCustomAccent","SettingsRow","TerminalRow","ThemeRow","AppearanceEditor","props","errorId","custom","accentDescription","draft","accent","preset","accentOptions","find","option","id","label","offered","themeAccentOptions","toLowerCase","glassDescription","surface","surfaceCapability","themeDefaultDescription","_el$","_tmpl$6","_el$3","firstChild","_$insert","_$createComponent","when","recoveryNotice","children","_el$2","_tmpl$","appearance","selectedId","lightThemeId","preview","lightTheme","themes","disabled","saving","onSelect","onChange","darkThemeId","darkTheme","terminalThemeId","undefined","_$memo","resolvedAppearance","title","icon","description","_el$4","_tmpl$3","_el$5","_$setAttribute","value","aria-invalid","customAccentError","aria-describedby","onInput","event","currentTarget","_el$6","_tmpl$2","settings","fonts","menuPortalMount","frosted","reason","_el$7","_tmpl$4","checked","reduceTransparency","onManageThemes","type","size","variant","onClick","hideActions","_el$8","_tmpl$5","AppearanceEditorActions","_$effect","_$className","class","saveReasonId","_el$9","_tmpl$8","_el$1","_el$10","saveDisabledReason","_el$0","_tmpl$7","onReset","onCancel","aria-busy","onSave","AppearancePopover","setMenuPortalMount","HTMLElement","open","onOpenChange","onOpen","onDismiss","as","side","closeLabel","ref","_$mergeProps","_$createComponent","_$memo","_$className","_$mergeProps"],"sources":["../../../../src/components/composites/appearance-editor/appearance-editor.tsx"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2026 Wing\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n/*\n * Composition substantially translated from Zeron settings/appearance.rs and\n * settings/widgets.rs, pinned at 30a9a9537c5ec96226c87f4bf349b6f77c5dfb59,\n * preserving Adea's existing appearance-surface.tsx port: System/Light/Dark\n * miniatures, compact independent theme rows, accent swatches and helper copy,\n * glass chips, and theme library affordance. Kobalte replaces the port's manual\n * radio keyboard model. The controlled draft and explicit action ports replace\n * GPUI globals and app-specific storage/native authority. Save/Cancel/Reset and\n * custom accent/reduced-transparency are accepted Adea divergences (#425).\n */\nimport { EyeOff, Palette, PanelsTopLeft, SlidersHorizontal } from 'lucide-solid'\nimport { Show, createSignal, createUniqueId } from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button } from '../../ui/button/button'\nimport { Input } from '../../ui/input/input'\nimport { AppearanceFontSettingsGroup } from './font-settings-group'\nimport { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS } from '#lib/appearance-font-settings'\n\nimport { Switch } from '../../ui/switch/switch'\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '../../ui/sheet/sheet'\nimport type { AppearanceEditorProps, AppearancePopoverProps } from './appearance-types'\nimport { ModeChoices, AccentChoices, GlassChoices, isCustomAccent } from './appearance-choices'\nimport { SettingsRow, TerminalRow, ThemeRow } from './appearance-rows'\n\n/**\n * A live editor whose persistence and preview authority belong to its host.\n * No ThemeProvider is required, and no catalogue, renderer engine or storage is\n * imported. Hosts normalize unknown IDs and custom colors, report recovery,\n * snapshot on open, preview on changes, commit on Save, and restore on dismissal.\n * Both theme rows remain mounted when mode changes. Density remains outside the\n * accepted appearance surface; typeface settings are shared and host-persisted.\n */\nexport function AppearanceEditor(props: AppearanceEditorProps) {\n const errorId = createUniqueId()\n const custom = () => isCustomAccent(props)\n const accentDescription = () => {\n if (props.draft.accent === 'theme') return \"Theme default · Uses the palette's intended color.\"\n const preset = props.accentOptions.find((option) => option.id === props.draft.accent)\n if (preset) return `${preset.label} · Controls, glyphs, selections, code, and activity.`\n if (custom()) return 'Custom · Controls, glyphs, selections, code, and activity.'\n const offered = props.themeAccentOptions?.find((option) => option.id === props.draft.accent)\n // A stored theme accent survives a theme switch by id; when the new pair\n // cannot offer that slot the host falls back to the theme's own primary,\n // and the description says so rather than naming a colour not on screen.\n return offered\n ? `Theme ${offered.label.toLowerCase()} · The theme's own color, on controls and activity.`\n : \"Theme default · This theme does not carry that accent, so it uses the palette's intended color.\"\n }\n const glassDescription = () =>\n props.draft.surface === 'opaque'\n ? 'Solid surfaces for every theme.'\n : props.draft.surface === 'frosted'\n ? 'Theme-colored glass where supported.'\n : (props.surfaceCapability.themeDefaultDescription ?? \"Uses this theme's default surface.\")\n return (\n <div data-appearance-editor class={cn('min-w-0', props.class)}>\n <Show when={props.recoveryNotice}>\n <p role=\"status\" class=\"px-4 py-2 text-sm text-muted-foreground\">\n {props.recoveryNotice}\n </p>\n </Show>\n <ModeChoices {...props} />\n <div class=\"divide-y divide-border rounded-lg border\">\n <ThemeRow\n appearance=\"light\"\n selectedId={props.draft.lightThemeId}\n preview={props.lightTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(lightThemeId) => props.onChange({ lightThemeId })}\n />\n <ThemeRow\n appearance=\"dark\"\n selectedId={props.draft.darkThemeId}\n preview={props.darkTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(darkThemeId) => props.onChange({ darkThemeId })}\n />\n {/* The row exists only when the host carries a terminal preference:\n the draft field is the show/hide switch, so the editor can never\n render a terminal row that writes nothing. */}\n <Show when={props.draft.terminalThemeId !== undefined}>\n <TerminalRow\n selectedId={props.draft.terminalThemeId ?? 'theme'}\n preview={props.resolvedAppearance === 'dark' ? props.darkTheme : props.lightTheme}\n themes={props.themes}\n disabled={props.saving}\n onSelect={(terminalThemeId) => props.onChange({ terminalThemeId })}\n />\n </Show>\n <SettingsRow title=\"Accent\" icon={<SlidersHorizontal />} description={accentDescription()}>\n <AccentChoices {...props} />\n </SettingsRow>\n <Show when={custom()}>\n <div class=\"px-4 py-3\">\n <label class=\"mb-2 block text-xs font-medium\" for={`${errorId}-input`}>\n Custom accent\n </label>\n <Input\n id={`${errorId}-input`}\n value={props.draft.accent}\n disabled={props.saving}\n aria-invalid={!!props.customAccentError}\n aria-describedby={props.customAccentError ? errorId : undefined}\n onInput={(event) => props.onChange({ accent: event.currentTarget.value })}\n />\n <Show when={props.customAccentError}>\n <p id={errorId} role=\"alert\" class=\"mt-1 text-xs text-foreground\">\n {props.customAccentError}\n </p>\n </Show>\n </div>\n </Show>\n <AppearanceFontSettingsGroup\n settings={props.draft.fonts ?? DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS}\n menuPortalMount={props.menuPortalMount}\n disabled={props.saving}\n onChange={(fonts) => props.onChange({ fonts })}\n />\n <SettingsRow title=\"Glass\" icon={<PanelsTopLeft />} description={glassDescription()}>\n <GlassChoices {...props} />\n </SettingsRow>\n <Show when={!props.surfaceCapability.frosted && props.surfaceCapability.reason}>\n <p role=\"status\" class=\"px-4 py-2 text-xs text-muted-foreground\">\n {props.surfaceCapability.reason}\n </p>\n </Show>\n <SettingsRow\n title=\"Reduce transparency\"\n icon={<EyeOff />}\n description=\"Prefer solid surfaces, including during live preview.\"\n >\n <Switch\n checked={props.draft.reduceTransparency}\n disabled={props.saving}\n onChange={(reduceTransparency: boolean) => props.onChange({ reduceTransparency })}\n aria-label=\"Reduce transparency\"\n />\n </SettingsRow>\n <SettingsRow\n title=\"Theme library\"\n icon={<Palette />}\n description={\n props.onManageThemes\n ? 'Manage themes through the application.'\n : 'Theme import is unavailable.'\n }\n >\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={!props.onManageThemes || props.saving}\n onClick={() => props.onManageThemes?.()}\n >\n Manage themes\n </Button>\n </SettingsRow>\n </div>\n <Show when={!props.hideActions}>\n {/* Sticky so Save/Cancel stay reachable in a tall scroll container: the\n editor scrolls with its host panel, and actions parked at the bottom\n of a long form were unreachable without scrolling past every row. */}\n <div class=\"sticky bottom-0 z-10 mt-2 border-t bg-background px-4 py-3\">\n <AppearanceEditorActions {...props} />\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Reset, Cancel and Save, with the reason Save is unavailable. Rendered by the\n * editor itself, or — with `hideActions` — by a host that pins them in its own\n * footer, as `AppearancePopover` does.\n */\nexport function AppearanceEditorActions(props: AppearanceEditorProps) {\n const saveReasonId = createUniqueId()\n return (\n <div class=\"flex w-full flex-col gap-2\">\n <Show when={props.saveDisabledReason}>\n <p id={saveReasonId} role=\"status\" class=\"text-xs text-muted-foreground\">\n {props.saveDisabledReason}\n </p>\n </Show>\n {/* `global-appearance-editor-actions` lets these buttons grow with the UI\n font preference, like the rest of Appearance's own controls. */}\n <div class=\"global-appearance-editor-actions flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n disabled={props.saving}\n onClick={() => props.onReset()}\n >\n Reset\n </Button>\n <div class=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={props.saving}\n onClick={() => props.onCancel()}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={props.saving || !!props.customAccentError || !!props.saveDisabledReason}\n aria-busy={props.saving}\n aria-describedby={props.saveDisabledReason ? saveReasonId : undefined}\n onClick={() => props.onSave()}\n >\n {props.saving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\n/** The editor in an inset Sheet docked beside the main view: the body scrolls and\n * Reset/Cancel/Save sit in the panel's full-width footer, always reachable.\n * Dismissal (Escape, the close button, an outside click) is `onDismiss`. */\nexport function AppearancePopover(props: AppearancePopoverProps) {\n const [menuPortalMount, setMenuPortalMount] = createSignal<HTMLElement>()\n\n return (\n <Sheet open={props.open} onOpenChange={(open) => (open ? props.onOpen() : props.onDismiss())}>\n <SheetTrigger\n as={Button}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Appearance settings\"\n >\n <Palette />\n </SheetTrigger>\n <SheetContent side=\"end\" closeLabel=\"Close appearance settings\" ref={setMenuPortalMount}>\n <SheetHeader>\n <SheetTitle>Appearance</SheetTitle>\n <SheetDescription>\n Changes preview immediately. Save keeps them; Cancel restores the previous appearance.\n </SheetDescription>\n </SheetHeader>\n <SheetBody>\n <AppearanceEditor {...props} menuPortalMount={menuPortalMount()} hideActions />\n </SheetBody>\n <SheetFooter>\n <AppearanceEditorActions {...props} />\n </SheetFooter>\n </SheetContent>\n </Sheet>\n )\n}\n"],"mappings":"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"}
@@ -57,6 +57,8 @@ export type AppearanceEditorProps = {
57
57
  /** Mount nested font menus inside the containing overlay when one exists. */
58
58
  menuPortalMount?: HTMLElement;
59
59
  class?: string;
60
+ /** Leave Reset/Cancel/Save to the host, which renders `AppearanceEditorActions`. */
61
+ hideActions?: boolean;
60
62
  };
61
63
  export type AppearancePopoverProps = AppearanceEditorProps & {
62
64
  open: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"appearance-types.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC/E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAEjF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,4BAA4B,CAAA;IACpC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;IACvC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,eAAe,CAAA;IACtB,8EAA8E;IAC9E,UAAU,EAAE,SAAS,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAC5C,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IACnD,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1F,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,WAAW,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG;IAC3D,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA"}
1
+ {"version":3,"file":"appearance-types.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/appearance-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC/E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAEjF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,4BAA4B,CAAA;IACpC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;IACvC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,eAAe,CAAA;IACtB,8EAA8E;IAC9E,UAAU,EAAE,SAAS,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAC5C,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IACnD,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1F,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,WAAW,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oFAAoF;IACpF,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG;IAC3D,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA"}
@@ -1,4 +1,4 @@
1
- export { AppearanceEditor, AppearancePopover } from './appearance-editor';
1
+ export { AppearanceEditor, AppearanceEditorActions, AppearancePopover } from './appearance-editor';
2
2
  export { AppearanceFontSettingsGroup, type AppearanceFontSettingsGroupProps, } from './font-settings-group';
3
3
  export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize, type AppearanceEditorFontAxis, type AppearanceEditorFontFamilyId, type AppearanceEditorFontSetting, type AppearanceEditorFontSettings, type NormalizedAppearanceEditorFontSettings, } from '#lib/appearance-font-settings';
4
4
  export type { AppearanceDraft, AppearanceEditorProps, AppearancePopoverProps, } from './appearance-types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EACL,2BAA2B,EAC3B,KAAK,gCAAgC,GACtC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,+BAA+B,EAC/B,uCAAuC,EACvC,2BAA2B,EAC3B,2BAA2B,EAC3B,qCAAqC,EACrC,iCAAiC,EACjC,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,sCAAsC,GAC5C,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/appearance-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAClG,OAAO,EACL,2BAA2B,EAC3B,KAAK,gCAAgC,GACtC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,+BAA+B,EAC/B,uCAAuC,EACvC,2BAA2B,EAC3B,2BAA2B,EAC3B,qCAAqC,EACrC,iCAAiC,EACjC,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,sCAAsC,GAC5C,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize } from "../../../lib/appearance-font-settings.js";
2
2
  import { PalettePreview, ThemeMiniature, ThemeMiniatureSplit } from "./theme-preview.js";
3
3
  import { AppearanceFontSettingsGroup } from "./font-settings-group.js";
4
- import { AppearanceEditor, AppearancePopover } from "./appearance-editor.js";
5
- export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, AppearanceEditor, AppearanceFontSettingsGroup, AppearancePopover, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, PalettePreview, ThemeMiniature, ThemeMiniatureSplit, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize };
4
+ import { AppearanceEditor, AppearanceEditorActions, AppearancePopover } from "./appearance-editor.js";
5
+ export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, AppearanceEditor, AppearanceEditorActions, AppearanceFontSettingsGroup, AppearancePopover, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, PalettePreview, ThemeMiniature, ThemeMiniatureSplit, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize };
@@ -0,0 +1,55 @@
1
+ import type { Accessor, JSX } from 'solid-js';
2
+ export type ContextualSidebarRenderContext = {
3
+ /** Whether the slot is being rendered inside the modal mobile sheet. */
4
+ mobile: boolean;
5
+ /** Mount nested popovers and menus inside the mobile dialog's accessibility tree. */
6
+ portalMount(): HTMLElement | undefined;
7
+ };
8
+ export type ContextualSidebarProps = {
9
+ /** Stable host id prefix; generated when omitted. */
10
+ id?: string;
11
+ /** Landmark name shared by the desktop and mobile navigation. */
12
+ label: string;
13
+ /** Visible navigation title and mobile dialog title. */
14
+ title: string;
15
+ /** Host-controlled expanded state for the desktop panel and mobile dialog. */
16
+ open: boolean;
17
+ onOpenChange(open: boolean): void;
18
+ /** Current host-owned pixel width, reflected by the resize handle. */
19
+ width: number;
20
+ minimum: number;
21
+ maximum: number;
22
+ step?: number;
23
+ /** Pass the host's initial viewport seed to distinguish stale desktop state. */
24
+ wideViewportAtLoad?: boolean;
25
+ resizeLabel?: string;
26
+ /** Stable external opener used when the modal mobile sheet closes. */
27
+ restoreFocusRef?: Accessor<HTMLElement | undefined>;
28
+ /** Called with the nav node so a host can project width onto its layout root. */
29
+ onSidebarElement?: (element: HTMLElement | undefined, mobile: boolean) => void;
30
+ /** Host-owned layout classes applied to both nav instances. */
31
+ sidebarClass?: string;
32
+ /** Host-owned responsive constraints for the modal sheet. */
33
+ sheetClass?: string;
34
+ headerClass?: string;
35
+ contentClass?: string;
36
+ footerClass?: string;
37
+ headingAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
38
+ /** Optional action/content slot alongside the shared heading. */
39
+ header?(context: ContextualSidebarRenderContext): JSX.Element;
40
+ /** View-specific navigation rows, projects, rooms, files, or sessions. */
41
+ content(context: ContextualSidebarRenderContext): JSX.Element;
42
+ /** Optional view-specific footer, such as an archive affordance. */
43
+ footer?(context: ContextualSidebarRenderContext): JSX.Element;
44
+ onWidthChange(width: number): void;
45
+ onWidthCommit?(width: number): void;
46
+ };
47
+ /**
48
+ * ContextualSidebar.
49
+ *
50
+ * Shared navigation geometry and interaction policy for an application's
51
+ * contextual sidebar. The host keeps ownership of the actual grid width,
52
+ * persisted preference, open state, and view-specific navigation content.
53
+ */
54
+ export declare function ContextualSidebar(props: ContextualSidebarProps): JSX.Element;
55
+ //# sourceMappingURL=contextual-sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextual-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/contextual-sidebar/contextual-sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAa7C,MAAM,MAAM,8BAA8B,GAAG;IAC3C,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAA;IACf,qFAAqF;IACrF,WAAW,IAAI,WAAW,GAAG,SAAS,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,qDAAqD;IACrD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;IACjC,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,eAAe,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;IACnD,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IAC9E,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACnD,iEAAiE;IACjE,MAAM,CAAC,CAAC,OAAO,EAAE,8BAA8B,GAAG,GAAG,CAAC,OAAO,CAAA;IAC7D,0EAA0E;IAC1E,OAAO,CAAC,OAAO,EAAE,8BAA8B,GAAG,GAAG,CAAC,OAAO,CAAA;IAC7D,oEAAoE;IACpE,MAAM,CAAC,CAAC,OAAO,EAAE,8BAA8B,GAAG,GAAG,CAAC,OAAO,CAAA;IAC7D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,eAgH9D"}
@@ -0,0 +1,199 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { Sheet, SheetContent, SheetTitle } from "../../ui/sheet/sheet.js";
3
+ import { SidebarNav, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavTitle } from "../sidebar-nav/sidebar-nav.js";
4
+ import { PixelResizeHandle } from "../pixel-resize-handle/pixel-resize-handle.js";
5
+ import { createComponent, memo } from "solid-js/web";
6
+ import { Show, createSignal, createUniqueId, onCleanup, onMount } from "solid-js";
7
+ //#region src/components/layout/contextual-sidebar/contextual-sidebar.tsx
8
+ /**
9
+ * ContextualSidebar.
10
+ *
11
+ * Shared navigation geometry and interaction policy for an application's
12
+ * contextual sidebar. The host keeps ownership of the actual grid width,
13
+ * persisted preference, open state, and view-specific navigation content.
14
+ */
15
+ function ContextualSidebar(props) {
16
+ const [isNarrowViewport, setIsNarrowViewport] = createSignal(false);
17
+ const [mobileMount, setMobileMount] = createSignal();
18
+ const id = props.id ?? `contextual-sidebar-${createUniqueId()}`;
19
+ const resizeLabel = () => props.resizeLabel ?? `Resize ${props.label}`;
20
+ const portalMount = () => {
21
+ const mount = mobileMount();
22
+ return mount?.connected && mount.element.isConnected ? mount.element : void 0;
23
+ };
24
+ onMount(() => {
25
+ const media = window.matchMedia("(max-width: 48rem)");
26
+ const updateViewport = () => {
27
+ const wasNarrow = isNarrowViewport();
28
+ if (media.matches && !wasNarrow) props.onOpenChange(false);
29
+ setIsNarrowViewport(media.matches);
30
+ };
31
+ if (media.matches && props.wideViewportAtLoad && props.open) props.onOpenChange(false);
32
+ setIsNarrowViewport(media.matches);
33
+ media.addEventListener("change", updateViewport);
34
+ onCleanup(() => media.removeEventListener("change", updateViewport));
35
+ });
36
+ const renderSidebar = (mobile) => {
37
+ let element;
38
+ const context = {
39
+ mobile,
40
+ portalMount: () => mobile ? portalMount() : void 0
41
+ };
42
+ const navigationId = `${id}-${mobile ? "mobile" : "desktop"}`;
43
+ onCleanup(() => {
44
+ if (mobile && mobileMount()?.element === element) setMobileMount(void 0);
45
+ element = void 0;
46
+ props.onSidebarElement?.(void 0, mobile);
47
+ });
48
+ return createComponent(SidebarNav, {
49
+ as: "aside",
50
+ id: navigationId,
51
+ get ["aria-label"]() {
52
+ return props.label;
53
+ },
54
+ get ["aria-hidden"]() {
55
+ return !mobile && !props.open ? "true" : void 0;
56
+ },
57
+ get inert() {
58
+ return !mobile && !props.open;
59
+ },
60
+ "data-contextual-sidebar": mobile ? "mobile" : "desktop",
61
+ get ["data-open"]() {
62
+ return mobile ? void 0 : String(props.open);
63
+ },
64
+ ref: (node) => {
65
+ element = node;
66
+ if (mobile) {
67
+ setMobileMount({
68
+ element: node,
69
+ connected: node.isConnected
70
+ });
71
+ queueMicrotask(() => {
72
+ if (node.isConnected && mobileMount()?.element === node) setMobileMount({
73
+ element: node,
74
+ connected: true
75
+ });
76
+ });
77
+ }
78
+ props.onSidebarElement?.(node, mobile);
79
+ },
80
+ get ["class"]() {
81
+ return cn("relative h-full w-full max-w-full", props.sidebarClass);
82
+ },
83
+ get children() {
84
+ return [createComponent(Show, {
85
+ get when() {
86
+ return !mobile && props.open;
87
+ },
88
+ get children() {
89
+ return createComponent(PixelResizeHandle, {
90
+ side: "left",
91
+ get value() {
92
+ return props.width;
93
+ },
94
+ get minimum() {
95
+ return props.minimum;
96
+ },
97
+ get maximum() {
98
+ return props.maximum;
99
+ },
100
+ get step() {
101
+ return props.step;
102
+ },
103
+ get label() {
104
+ return resizeLabel();
105
+ },
106
+ controls: navigationId,
107
+ get onChange() {
108
+ return props.onWidthChange;
109
+ },
110
+ get onCommit() {
111
+ return props.onWidthCommit;
112
+ }
113
+ });
114
+ }
115
+ }), createComponent(Show, {
116
+ get when() {
117
+ return !mobile || mobileMount()?.connected;
118
+ },
119
+ get children() {
120
+ return [
121
+ createComponent(SidebarNavHeader, {
122
+ get ["class"]() {
123
+ return cn(mobile && "pe-12", props.headerClass);
124
+ },
125
+ get children() {
126
+ return [createComponent(SidebarNavTitle, {
127
+ get as() {
128
+ return props.headingAs ?? "h2";
129
+ },
130
+ get children() {
131
+ return props.title;
132
+ }
133
+ }), memo(() => props.header?.(context))];
134
+ }
135
+ }),
136
+ createComponent(SidebarNavContent, {
137
+ get ["class"]() {
138
+ return props.contentClass;
139
+ },
140
+ get children() {
141
+ return props.content(context);
142
+ }
143
+ }),
144
+ memo(() => memo(() => !!props.footer)() ? createComponent(SidebarNavFooter, {
145
+ get ["class"]() {
146
+ return props.footerClass;
147
+ },
148
+ get children() {
149
+ return props.footer(context);
150
+ }
151
+ }) : null)
152
+ ];
153
+ }
154
+ })];
155
+ }
156
+ });
157
+ };
158
+ return createComponent(Sheet, {
159
+ get open() {
160
+ return memo(() => !!isNarrowViewport())() && props.open;
161
+ },
162
+ onOpenChange: (open) => props.onOpenChange(open),
163
+ get children() {
164
+ return [createComponent(Show, {
165
+ get when() {
166
+ return !isNarrowViewport();
167
+ },
168
+ children: (_wide) => renderSidebar(false)
169
+ }), createComponent(Show, {
170
+ get when() {
171
+ return isNarrowViewport();
172
+ },
173
+ get children() {
174
+ return createComponent(SheetContent, {
175
+ side: "start",
176
+ get ["class"]() {
177
+ return cn("gap-0 p-0", props.sheetClass);
178
+ },
179
+ get restoreFocusRef() {
180
+ return props.restoreFocusRef;
181
+ },
182
+ get children() {
183
+ return [createComponent(SheetTitle, {
184
+ "class": "sr-only",
185
+ get children() {
186
+ return [memo(() => props.title), " navigation"];
187
+ }
188
+ }), memo(() => renderSidebar(true))];
189
+ }
190
+ });
191
+ }
192
+ })];
193
+ }
194
+ });
195
+ }
196
+ //#endregion
197
+ export { ContextualSidebar };
198
+
199
+ //# sourceMappingURL=contextual-sidebar.js.map