@moldable-ai/ui 0.2.25 → 0.2.26

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 (62) hide show
  1. package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
  2. package/dist/catalog/core-foundation-stories.js +2 -2
  3. package/dist/components/chat/chat-input.d.ts.map +1 -1
  4. package/dist/components/chat/chat-input.js +1 -1
  5. package/dist/components/chat/chat-message.js +1 -1
  6. package/dist/components/chat/index.d.ts +1 -0
  7. package/dist/components/chat/index.d.ts.map +1 -1
  8. package/dist/components/chat/index.js +1 -0
  9. package/dist/components/chat/orb-materials.d.ts +14 -0
  10. package/dist/components/chat/orb-materials.d.ts.map +1 -0
  11. package/dist/components/chat/orb-materials.js +340 -0
  12. package/dist/components/chat/voice-orb-shaders.d.ts +1 -1
  13. package/dist/components/chat/voice-orb-shaders.d.ts.map +1 -1
  14. package/dist/components/chat/voice-orb-shaders.js +11 -162
  15. package/dist/components/chat/voice-orb.d.ts.map +1 -1
  16. package/dist/components/chat/voice-orb.js +2 -1
  17. package/dist/components/native-capabilities/shortcut-recorder.js +1 -1
  18. package/dist/components/rich-media-player.js +1 -1
  19. package/dist/components/ui/app-frame.d.ts +1 -1
  20. package/dist/components/ui/app-frame.d.ts.map +1 -1
  21. package/dist/components/ui/app-frame.js +7 -39
  22. package/dist/components/ui/button-group.d.ts +1 -1
  23. package/dist/components/ui/button-group.js +1 -1
  24. package/dist/components/ui/button.d.ts +2 -2
  25. package/dist/components/ui/button.d.ts.map +1 -1
  26. package/dist/components/ui/checkbox.js +1 -1
  27. package/dist/components/ui/collapsible.js +1 -1
  28. package/dist/components/ui/combobox.js +1 -1
  29. package/dist/components/ui/command.d.ts.map +1 -1
  30. package/dist/components/ui/command.js +10 -2
  31. package/dist/components/ui/date-field.d.ts +1 -1
  32. package/dist/components/ui/date-field.js +1 -1
  33. package/dist/components/ui/input-group.d.ts +2 -2
  34. package/dist/components/ui/input-group.d.ts.map +1 -1
  35. package/dist/components/ui/input-otp.js +1 -1
  36. package/dist/components/ui/input.js +1 -1
  37. package/dist/components/ui/inspector.js +3 -3
  38. package/dist/components/ui/menubar.js +1 -1
  39. package/dist/components/ui/number-input.js +1 -1
  40. package/dist/components/ui/panel.d.ts +2 -2
  41. package/dist/components/ui/panel.js +2 -2
  42. package/dist/components/ui/radio-group.js +1 -1
  43. package/dist/components/ui/select.js +1 -1
  44. package/dist/components/ui/switch.js +1 -1
  45. package/dist/components/ui/toolbar.d.ts +15 -4
  46. package/dist/components/ui/toolbar.d.ts.map +1 -1
  47. package/dist/components/ui/toolbar.js +16 -5
  48. package/dist/components/ui/window-titlebar.d.ts +8 -0
  49. package/dist/components/ui/window-titlebar.d.ts.map +1 -0
  50. package/dist/components/ui/window-titlebar.js +40 -0
  51. package/dist/index.d.ts +1 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +1 -1
  54. package/dist/lib/commands.d.ts +29 -0
  55. package/dist/lib/commands.d.ts.map +1 -1
  56. package/dist/lib/commands.js +28 -0
  57. package/docs/app-anatomy.md +9 -7
  58. package/docs/standalone-app-windows.md +12 -8
  59. package/package.json +2 -2
  60. package/src/components/ui/app-frame.md +6 -8
  61. package/src/components/ui/toolbar.md +14 -1
  62. package/src/styles/index.css +28 -0
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
3
  declare const panelVariants: (props?: ({
4
- surface?: "default" | "muted" | "sidebar" | "transparent" | null | undefined;
5
- border?: "all" | "none" | "inline" | "block" | null | undefined;
4
+ surface?: "default" | "transparent" | "muted" | "sidebar" | null | undefined;
5
+ border?: "none" | "inline" | "all" | "block" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface PanelGroupProps extends React.ComponentProps<'div'> {
8
8
  orientation?: 'horizontal' | 'vertical';
@@ -29,12 +29,12 @@ function Panel({ surface, border, className, ...props }) {
29
29
  return (_jsx("section", { "data-slot": "panel", "data-surface": surface ?? 'default', className: cn(panelVariants({ surface, border }), className), ...props }));
30
30
  }
31
31
  function PanelHeader({ className, ...props }) {
32
- return (_jsx("header", { "data-slot": "panel-header", className: cn('border-border/70 flex min-h-row shrink-0 items-center gap-control-gap border-b px-control-inline py-1', className), ...props }));
32
+ return (_jsx("header", { "data-slot": "panel-header", className: cn('border-border/70 min-h-row gap-control-gap px-control-inline flex shrink-0 items-center border-b py-1', className), ...props }));
33
33
  }
34
34
  function PanelContent({ className, ...props }) {
35
35
  return (_jsx("div", { "data-slot": "panel-content", className: cn('min-h-0 min-w-0 flex-1 overflow-auto', className), ...props }));
36
36
  }
37
37
  function PanelFooter({ className, ...props }) {
38
- return (_jsx("footer", { "data-slot": "panel-footer", className: cn('border-border/70 flex min-h-row shrink-0 items-center gap-control-gap border-t px-control-inline py-1', className), ...props }));
38
+ return (_jsx("footer", { "data-slot": "panel-footer", className: cn('border-border/70 min-h-row gap-control-gap px-control-inline flex shrink-0 items-center border-t py-1', className), ...props }));
39
39
  }
40
40
  export { Panel, PanelContent, PanelFooter, PanelGroup, PanelHeader, panelVariants, };
@@ -7,6 +7,6 @@ function RadioGroup({ className, ...props }) {
7
7
  return (_jsx(RadioGroupPrimitive.Root, { "data-slot": "radio-group", className: cn('grid gap-3', className), ...props }));
8
8
  }
9
9
  function RadioGroupItem({ className, ...props }) {
10
- return (_jsx(RadioGroupPrimitive.Item, { "data-slot": "radio-group-item", className: cn('group/radio text-primary focus-visible:border-ring focus-visible:ring-ring aria-invalid:before:border-destructive rounded-pill relative size-control-xs shrink-0 cursor-pointer border border-transparent bg-transparent p-1 outline-none transition-[color,box-shadow] before:pointer-events-none before:absolute before:left-1/2 before:top-1/2 before:size-4 before:-translate-x-1/2 before:-translate-y-1/2 before:rounded-pill before:border before:border-input before:bg-transparent before:shadow-xs dark:before:bg-input/30 focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: _jsx(RadioGroupPrimitive.Indicator, { forceMount: true, "data-slot": "radio-group-indicator", className: "pointer-events-none absolute left-1/2 top-1/2 z-10 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center group-data-[state=unchecked]/radio:opacity-0", children: _jsx(CircleIcon, { className: "fill-primary absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2" }) }) }));
10
+ return (_jsx(RadioGroupPrimitive.Item, { "data-slot": "radio-group-item", className: cn('group/radio text-primary focus-visible:border-ring focus-visible:ring-ring aria-invalid:before:border-destructive rounded-pill size-control-xs before:rounded-pill before:border-input before:shadow-xs dark:before:bg-input/30 relative shrink-0 cursor-pointer border border-transparent bg-transparent p-1 outline-none transition-[color,box-shadow] before:pointer-events-none before:absolute before:left-1/2 before:top-1/2 before:size-4 before:-translate-x-1/2 before:-translate-y-1/2 before:border before:bg-transparent focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: _jsx(RadioGroupPrimitive.Indicator, { forceMount: true, "data-slot": "radio-group-indicator", className: "pointer-events-none absolute left-1/2 top-1/2 z-10 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center group-data-[state=unchecked]/radio:opacity-0", children: _jsx(CircleIcon, { className: "fill-primary absolute left-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2" }) }) }));
11
11
  }
12
12
  export { RadioGroup, RadioGroupItem };
@@ -13,7 +13,7 @@ function SelectValue({ ...props }) {
13
13
  return _jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
14
14
  }
15
15
  function SelectTrigger({ className, size = 'default', children, ...props }) {
16
- return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 shadow-xs rounded-control text-ui-body flex w-fit items-center justify-between gap-control-gap whitespace-nowrap border bg-transparent px-control-inline outline-none transition-[color,box-shadow] focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-control-md data-[size=sm]:h-control-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-control-gap [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })] }));
16
+ return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 shadow-xs rounded-control text-ui-body gap-control-gap px-control-inline data-[size=default]:h-control-md data-[size=sm]:h-control-sm *:data-[slot=select-value]:gap-control-gap flex w-fit items-center justify-between whitespace-nowrap border bg-transparent outline-none transition-[color,box-shadow] focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })] }));
17
17
  }
18
18
  function SelectContent({ className, children, position = 'item-aligned', align = 'center', ...props }) {
19
19
  return (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) rounded-overlay shadow-overlay relative z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden border', position === 'popper' &&
@@ -3,6 +3,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as SwitchPrimitive from '@radix-ui/react-switch';
4
4
  import { cn } from '../../lib/utils.js';
5
5
  function Switch({ className, size = 'default', ...props }) {
6
- return (_jsx(SwitchPrimitive.Root, { "data-slot": "switch", "data-size": size, className: cn('focus-visible:border-ring focus-visible:ring-ring group/switch rounded-pill peer relative inline-flex h-control-xs shrink-0 cursor-pointer items-center border border-transparent bg-transparent outline-none transition-all before:pointer-events-none before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:rounded-pill before:border before:border-transparent before:shadow-xs data-[state=checked]:before:bg-primary data-[state=unchecked]:before:bg-input dark:data-[state=unchecked]:before:bg-input/80 focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:w-8 data-[size=default]:before:h-[1.15rem] data-[size=default]:before:w-8 data-[size=sm]:w-6 data-[size=sm]:before:h-3.5 data-[size=sm]:before:w-6', className), ...props, children: _jsx(SwitchPrimitive.Thumb, { "data-slot": "switch-thumb", className: cn('bg-background border-separator-strong shadow-xs dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground rounded-pill pointer-events-none relative z-10 block border ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3') }) }));
6
+ return (_jsx(SwitchPrimitive.Root, { "data-slot": "switch", "data-size": size, className: cn('focus-visible:border-ring focus-visible:ring-ring group/switch rounded-pill h-control-xs before:rounded-pill before:shadow-xs data-[state=checked]:before:bg-primary data-[state=unchecked]:before:bg-input dark:data-[state=unchecked]:before:bg-input/80 peer relative inline-flex shrink-0 cursor-pointer items-center border border-transparent bg-transparent outline-none transition-all before:pointer-events-none before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:border before:border-transparent focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:w-8 data-[size=sm]:w-6 data-[size=default]:before:h-[1.15rem] data-[size=sm]:before:h-3.5 data-[size=default]:before:w-8 data-[size=sm]:before:w-6', className), ...props, children: _jsx(SwitchPrimitive.Thumb, { "data-slot": "switch-thumb", className: cn('bg-background border-separator-strong shadow-xs dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground rounded-pill pointer-events-none relative z-10 block border ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3') }) }));
7
7
  }
8
8
  export { Switch };
@@ -3,11 +3,12 @@ import type { MaterialVariant } from './material.js';
3
3
  import { Separator } from './separator.js';
4
4
  import { Text } from './text.js';
5
5
  import { type VariantProps } from 'class-variance-authority';
6
+ export type ToolbarInset = 'auto' | 'none' | 'windowControls' | 'windowControlsAndButton';
6
7
  declare const toolbarVariants: (props?: ({
7
- variant?: "default" | "panel" | "plain" | null | undefined;
8
- material?: "regular" | "none" | "clear" | null | undefined;
8
+ variant?: "panel" | "default" | "plain" | null | undefined;
9
+ material?: "regular" | "clear" | "none" | null | undefined;
9
10
  density?: "compact" | "default" | "comfortable" | null | undefined;
10
- position?: "top" | "bottom" | "static" | null | undefined;
11
+ position?: "static" | "top" | "bottom" | null | undefined;
11
12
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
13
  export interface ToolbarProps extends React.ComponentProps<'header'>, VariantProps<typeof toolbarVariants> {
13
14
  /**
@@ -15,8 +16,18 @@ export interface ToolbarProps extends React.ComponentProps<'header'>, VariantPro
15
16
  * plain or panel variants.
16
17
  */
17
18
  material?: MaterialVariant | 'none';
19
+ /**
20
+ * Clearance for native window controls. `auto` applies the host-advertised
21
+ * inset only when this is a top toolbar in an app-owned window.
22
+ */
23
+ inset?: ToolbarInset;
24
+ /**
25
+ * Top toolbars are draggable by default. Interactive descendants remain
26
+ * clickable and never initiate a native window drag.
27
+ */
28
+ draggable?: boolean;
18
29
  }
19
- declare function Toolbar({ variant, density, position, material, className, ...props }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
30
+ declare function Toolbar({ variant, density, position, material, inset, draggable, className, onDoubleClick, onMouseDown, ...props }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
20
31
  declare function ToolbarGroup({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
21
32
  declare function ToolbarContent({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
22
33
  declare function ToolbarTitle({ className, ...props }: React.ComponentProps<typeof Text>): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/toolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,0BAA0B,CAAA;AAEjE,QAAA,MAAM,eAAe;;;;;8EAsCpB,CAAA;AAED,MAAM,WAAW,YACf,SAAQ,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EACpC,YAAY,CAAC,OAAO,eAAe,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;CACpC;AAED,iBAAS,OAAO,CAAC,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,2CAyBd;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQzE;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ3E;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAWnC;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAYnC;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ3E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,2CASxC;AAED,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAChB,CAAA"}
1
+ {"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/toolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,0BAA0B,CAAA;AAMjE,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,MAAM,GACN,gBAAgB,GAChB,yBAAyB,CAAA;AAE7B,QAAA,MAAM,eAAe;;;;;8EAsCpB,CAAA;AAED,MAAM,WAAW,YACf,SAAQ,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EACpC,YAAY,CAAC,OAAO,eAAe,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,iBAAS,OAAO,CAAC,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,KAAc,EACd,SAAS,EACT,SAAS,EACT,aAAa,EACb,WAAW,EACX,GAAG,KAAK,EACT,EAAE,YAAY,2CAqCd;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQzE;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ3E;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAWnC;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAYnC;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ3E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,2CASxC;AAED,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAChB,CAAA"}
@@ -4,6 +4,7 @@ import { cn } from '../../lib/utils.js';
4
4
  import { Separator } from './separator.js';
5
5
  import { Text } from './text.js';
6
6
  import { cva } from 'class-variance-authority';
7
+ import { handleWindowTitlebarDoubleClick, handleWindowTitlebarMouseDown, } from './window-titlebar.js';
7
8
  const toolbarVariants = cva('z-20 flex min-h-toolbar w-full shrink-0 items-center gap-control-gap px-control-inline', {
8
9
  variants: {
9
10
  variant: {
@@ -40,15 +41,25 @@ const toolbarVariants = cva('z-20 flex min-h-toolbar w-full shrink-0 items-cente
40
41
  position: 'static',
41
42
  },
42
43
  });
43
- function Toolbar({ variant, density, position, material, className, ...props }) {
44
+ function Toolbar({ variant, density, position, material, inset = 'auto', draggable, className, onDoubleClick, onMouseDown, ...props }) {
44
45
  const resolvedVariant = variant ?? 'default';
45
46
  const resolvedMaterial = material ?? (resolvedVariant === 'default' ? 'regular' : 'none');
46
- return (_jsx("header", { "data-slot": "toolbar", "data-density": density ?? 'compact', "data-position": position ?? 'static', "data-variant": resolvedVariant, "data-material": resolvedMaterial === 'none' ? undefined : resolvedMaterial, "data-material-elevation": resolvedMaterial === 'none' ? undefined : 'none', className: cn(toolbarVariants({
47
+ const resolvedPosition = position ?? 'static';
48
+ const isDraggable = draggable ?? resolvedPosition === 'top';
49
+ return (_jsx("header", { "data-slot": "toolbar", "data-density": density ?? 'compact', "data-position": resolvedPosition, "data-variant": resolvedVariant, "data-window-inset": inset, "data-window-draggable": isDraggable ? 'true' : undefined, "data-material": resolvedMaterial === 'none' ? undefined : resolvedMaterial, "data-material-elevation": resolvedMaterial === 'none' ? undefined : 'none', className: cn(toolbarVariants({
47
50
  variant: resolvedVariant,
48
51
  material: resolvedMaterial,
49
52
  density,
50
- position,
51
- }), className), ...props }));
53
+ position: resolvedPosition,
54
+ }), className), onMouseDown: (event) => {
55
+ onMouseDown?.(event);
56
+ if (isDraggable)
57
+ handleWindowTitlebarMouseDown(event);
58
+ }, onDoubleClick: (event) => {
59
+ onDoubleClick?.(event);
60
+ if (isDraggable)
61
+ handleWindowTitlebarDoubleClick(event);
62
+ }, ...props }));
52
63
  }
53
64
  function ToolbarGroup({ className, ...props }) {
54
65
  return (_jsx("div", { "data-slot": "toolbar-group", className: cn('flex min-w-0 items-center gap-1.5', className), ...props }));
@@ -57,7 +68,7 @@ function ToolbarContent({ className, ...props }) {
57
68
  return (_jsx("div", { "data-slot": "toolbar-content", className: cn('flex min-w-0 flex-1 flex-col', className), ...props }));
58
69
  }
59
70
  function ToolbarTitle({ className, ...props }) {
60
- return (_jsx(Text, { as: "h2", variant: "strong", truncate: true, "data-slot": "toolbar-title", className: className, ...props }));
71
+ return (_jsx(Text, { as: "h2", variant: "strong", truncate: true, "data-slot": "toolbar-title", className: cn('text-[15px] font-medium', className), ...props }));
61
72
  }
62
73
  function ToolbarDescription({ className, ...props }) {
63
74
  return (_jsx(Text, { as: "p", variant: "small", color: "secondary", truncate: true, "data-slot": "toolbar-description", className: className, ...props }));
@@ -0,0 +1,8 @@
1
+ import type * as React from 'react';
2
+ export declare const WINDOW_TITLEBAR_INTERACTIVE_SELECTOR: string;
3
+ export declare function isAppOwnedWindowTitlebar(): boolean;
4
+ export declare function isInteractiveTitlebarTarget(target: EventTarget | null): boolean;
5
+ export declare function postWindowTitlebarMessage(type: string): void;
6
+ export declare function handleWindowTitlebarMouseDown(event: React.MouseEvent<HTMLElement>): void;
7
+ export declare function handleWindowTitlebarDoubleClick(event: React.MouseEvent<HTMLElement>): void;
8
+ //# sourceMappingURL=window-titlebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-titlebar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/window-titlebar.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,eAAO,MAAM,oCAAoC,QAUtC,CAAA;AAEX,wBAAgB,wBAAwB,IAAI,OAAO,CAMlD;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,WAAW,GAAG,IAAI,GACzB,OAAO,CAKT;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG5D;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,GACnC,IAAI,CASN;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,GACnC,IAAI,CAKN"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ export const WINDOW_TITLEBAR_INTERACTIVE_SELECTOR = [
3
+ 'a',
4
+ 'button',
5
+ 'input',
6
+ 'select',
7
+ 'textarea',
8
+ '[contenteditable]:not([contenteditable="false"])',
9
+ '[role="button"]',
10
+ '[role="link"]',
11
+ '[data-moldable-no-window-drag]',
12
+ ].join(',');
13
+ export function isAppOwnedWindowTitlebar() {
14
+ return (typeof document !== 'undefined' &&
15
+ document.documentElement.dataset.moldableDisplayMode === 'window' &&
16
+ document.documentElement.dataset.moldableWindowTitlebar === 'app');
17
+ }
18
+ export function isInteractiveTitlebarTarget(target) {
19
+ return (target instanceof Element &&
20
+ target.closest(WINDOW_TITLEBAR_INTERACTIVE_SELECTOR) !== null);
21
+ }
22
+ export function postWindowTitlebarMessage(type) {
23
+ if (!isAppOwnedWindowTitlebar())
24
+ return;
25
+ window.parent.postMessage({ type }, '*');
26
+ }
27
+ export function handleWindowTitlebarMouseDown(event) {
28
+ if (event.defaultPrevented ||
29
+ event.buttons !== 1 ||
30
+ isInteractiveTitlebarTarget(event.target)) {
31
+ return;
32
+ }
33
+ postWindowTitlebarMessage('startWindowDrag');
34
+ }
35
+ export function handleWindowTitlebarDoubleClick(event) {
36
+ if (event.defaultPrevented || isInteractiveTitlebarTarget(event.target)) {
37
+ return;
38
+ }
39
+ postWindowTitlebarMessage('titlebarDoubleClick');
40
+ }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { cn } from './lib/utils.js';
2
2
  export { ThemeProvider, useTheme, themeScript, type Theme } from './lib/theme.js';
3
3
  export { WorkspaceProvider, useWorkspace, WORKSPACE_HEADER, } from './lib/workspace.js';
4
- export { useMoldableCommands, useMoldableCommand, useMoldableAppCommands, useMoldableNavigationPop, useMoldableNavigationState, isInMoldable, sendToMoldable, pushMoldableNavigation, popMoldableNavigation, resetMoldableNavigation, downloadFile, publishMoldableArtifact, setMoldableWindowFullscreen, type AppCommand, type CommandAction, type CommandsResponse, type CommandMessage, type MoldableNavigationEntry, type MoldableNavigationPopMessage, type MoldableNavigationStateMessage, type DownloadFileOptions, type MoldableArtifactFile, type MoldableArtifactPublishOptions, type MoldableArtifactPublishResult, type MoldableWindowFullscreenMode, type MoldableWindowFullscreenOptions, type MoldableWindowFullscreenResult, type MoldableWindowFullscreenMessage, type MoldableWindowFullscreenResultMessage, } from './lib/commands.js';
4
+ export { useMoldableCommands, useMoldableCommand, useMoldableAppCommands, useMoldableWindowShortcuts, useMoldableNavigationPop, useMoldableNavigationState, isInMoldable, sendToMoldable, pushMoldableNavigation, popMoldableNavigation, resetMoldableNavigation, downloadFile, publishMoldableArtifact, setMoldableWindowFullscreen, type AppCommand, type CommandAction, type CommandsResponse, type CommandMessage, type MoldableNavigationEntry, type MoldableNavigationPopMessage, type MoldableNavigationStateMessage, type MoldableWindowShortcut, type MoldableWindowShortcutDefaults, type DownloadFileOptions, type MoldableArtifactFile, type MoldableArtifactPublishOptions, type MoldableArtifactPublishResult, type MoldableWindowFullscreenMode, type MoldableWindowFullscreenOptions, type MoldableWindowFullscreenResult, type MoldableWindowFullscreenMessage, type MoldableWindowFullscreenResultMessage, } from './lib/commands.js';
5
5
  export * from './lib/native-capabilities/index.js';
6
6
  export * from './components/ui/index.js';
7
7
  export * from './components/native-capabilities/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export { ThemeProvider, useTheme, themeScript } from './lib/theme.js';
5
5
  // Export workspace
6
6
  export { WorkspaceProvider, useWorkspace, WORKSPACE_HEADER, } from './lib/workspace.js';
7
7
  // Export commands
8
- export { useMoldableCommands, useMoldableCommand, useMoldableAppCommands, useMoldableNavigationPop, useMoldableNavigationState, isInMoldable, sendToMoldable, pushMoldableNavigation, popMoldableNavigation, resetMoldableNavigation, downloadFile, publishMoldableArtifact, setMoldableWindowFullscreen, } from './lib/commands.js';
8
+ export { useMoldableCommands, useMoldableCommand, useMoldableAppCommands, useMoldableWindowShortcuts, useMoldableNavigationPop, useMoldableNavigationState, isInMoldable, sendToMoldable, pushMoldableNavigation, popMoldableNavigation, resetMoldableNavigation, downloadFile, publishMoldableArtifact, setMoldableWindowFullscreen, } from './lib/commands.js';
9
9
  // Export typed desktop/native capability APIs
10
10
  export * from './lib/native-capabilities/index.js';
11
11
  // Export UI components
@@ -44,6 +44,27 @@ export interface AppCommand {
44
44
  /** What happens when the command is executed */
45
45
  action: CommandAction;
46
46
  }
47
+ /**
48
+ * A focused-window accelerator owned by an app.
49
+ *
50
+ * The command ID is delivered through the same `moldable:command` channel as
51
+ * command-menu actions. Accelerators use Tauri/Electron-style names such as
52
+ * `CmdOrCtrl+Shift+P`.
53
+ */
54
+ export interface MoldableWindowShortcut {
55
+ id: string;
56
+ label: string;
57
+ accelerator: string;
58
+ }
59
+ /**
60
+ * Host shortcuts are enabled unless an app explicitly opts out.
61
+ *
62
+ * Opting out releases the accelerator for an app-declared window shortcut.
63
+ */
64
+ export interface MoldableWindowShortcutDefaults {
65
+ commandMenu?: boolean;
66
+ closeWindow?: boolean;
67
+ }
47
68
  /**
48
69
  * Response from /_moldable/commands endpoint
49
70
  */
@@ -95,6 +116,14 @@ export declare function useMoldableCommands(handlers: Record<string, (payload?:
95
116
  * /api/moldable/commands response while the app is running.
96
117
  */
97
118
  export declare function useMoldableAppCommands(appId: string, commands: AppCommand[]): void;
119
+ /**
120
+ * Publish keyboard commands that must continue working while a native child
121
+ * surface inside the app window has focus.
122
+ *
123
+ * Keep `shortcuts` and `defaults` referentially stable with `useMemo` or
124
+ * module-level constants.
125
+ */
126
+ export declare function useMoldableWindowShortcuts(shortcuts: readonly MoldableWindowShortcut[], defaults?: MoldableWindowShortcutDefaults): void;
98
127
  /**
99
128
  * Hook to register a single command handler
100
129
  * Useful when you want to register handlers in different components
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAErC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,SAAS,CAAC,EAAE,mBAAmB,CAAA;IAC/B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gDAAgD;IAChD,MAAM,EAAE,aAAa,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,EAAE,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,yBAAyB,CAAA;IAC/B,KAAK,CAAC,EAAE,uBAAuB,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,2BAA2B,CAAA;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,uBAAuB,EAAE,CAAA;CACnC;AAED,MAAM,MAAM,4BAA4B,GAAG,CACzC,OAAO,EAAE,4BAA4B,KAClC,IAAI,CAAA;AAET;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,QAwBtD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAa3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,QAgBrC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,IAAI,CAAC,uBAAuB,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAO,GAChE,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,QAKrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,SAItC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,4BAA4B,QActC;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,CAAC,OAAO,EAAE,8BAA8B,KAAK,IAAI,QAc3D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAGtC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,QAMA;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,mBAAmB,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,4BAA4B,CAAC,CAAC,GAAG,OAAO;IACvD,IAAI,EAAE,0BAA0B,CAAA;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,CAAC,EAAE,CAAC,CAAA;IACV,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,KAAK,EAAE,oBAAoB,EAAE,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,4BAA4B,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE7D,MAAM,WAAW,+BAA+B;IAC9C,UAAU,CAAC,EAAE,4BAA4B,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,gCAAgC,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,4BAA4B,CAAA;CACzC;AAED,MAAM,WAAW,qCAAqC;IACpD,IAAI,EAAE,uCAAuC,CAAA;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,CAAC,EAAE,8BAA8B,CAAA;IACvC,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAUD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EACzC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,EAChB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,CAAC,CAAC,CAkDZ;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,GAAE,4BAAmC,EAC/C,OAAO,GAAE,IAAI,CAAC,+BAA+B,EAAE,YAAY,CAAM,GAChE,OAAO,CAAC,8BAA8B,CAAC,CAoDzC;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,6BAA6B,CAAC,CA6CxC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqExE"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"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"}
@@ -51,6 +51,34 @@ export function useMoldableAppCommands(appId, commands) {
51
51
  }, '*');
52
52
  }, [appId, commands]);
53
53
  }
54
+ /**
55
+ * Publish keyboard commands that must continue working while a native child
56
+ * surface inside the app window has focus.
57
+ *
58
+ * Keep `shortcuts` and `defaults` referentially stable with `useMemo` or
59
+ * module-level constants.
60
+ */
61
+ export function useMoldableWindowShortcuts(shortcuts, defaults) {
62
+ useEffect(() => {
63
+ if (!isInMoldable())
64
+ return;
65
+ sendToMoldable({
66
+ type: 'moldable:set-window-shortcuts',
67
+ shortcuts,
68
+ ...(defaults ? { defaults } : {}),
69
+ });
70
+ return () => {
71
+ sendToMoldable({
72
+ type: 'moldable:set-window-shortcuts',
73
+ shortcuts: [],
74
+ defaults: {
75
+ commandMenu: true,
76
+ closeWindow: true,
77
+ },
78
+ });
79
+ };
80
+ }, [defaults, shortcuts]);
81
+ }
54
82
  /**
55
83
  * Hook to register a single command handler
56
84
  * Useful when you want to register handlers in different components
@@ -8,19 +8,21 @@ canvas independent of the desktop shell.
8
8
 
9
9
  ```tsx
10
10
  <AppFrame>
11
- <AppFrameTitlebar>
12
- <AppFrameToolbar>
13
- {/* title, view controls, primary actions */}
14
- </AppFrameToolbar>
15
- </AppFrameTitlebar>
11
+ <Toolbar position="top">
12
+ <ToolbarContent>
13
+ <ToolbarTitle>{/* current view or document */}</ToolbarTitle>
14
+ </ToolbarContent>
15
+ <ToolbarActions>{/* primary actions */}</ToolbarActions>
16
+ </Toolbar>
16
17
  <AppFrameContent scrollable={false}>
17
18
  {/* app-owned canvas and panes */}
18
19
  </AppFrameContent>
19
20
  </AppFrame>
20
21
  ```
21
22
 
22
- The host renders native window controls and drag regions. Do not draw those
23
- inside app UI.
23
+ The host renders native window controls. `Toolbar` consumes their safe inset
24
+ and bridges dragging to the native host when the app owns its titlebar. Do not
25
+ draw operating-system controls inside app UI.
24
26
 
25
27
  ## Recommended pane shell
26
28
 
@@ -44,10 +44,11 @@ not individual apps.
44
44
  Dedicated windows use the host titlebar by default. An app with a unified
45
45
  toolbar can declare `{ "window": { "titlebar": "app" } }` in `moldable.json`.
46
46
  In that mode the host removes its strip and advertises the titlebar height and
47
- leading window-control inset. `AppFrameTitlebar` consumes those values, sends
48
- `startWindowDrag` on a non-interactive pointerdown, and sends
47
+ leading window-control inset. A top `Toolbar` consumes those values, sends
48
+ `startWindowDrag` on a non-interactive mousedown, and sends
49
49
  `titlebarDoubleClick` on a non-interactive double-click. The latter toggles
50
50
  maximize as a cross-platform approximation of the macOS titlebar zoom action.
51
+ Interactive descendants are automatically excluded from dragging.
51
52
 
52
53
  Window appearance roles are `--window-chrome-background`,
53
54
  `--window-chrome-foreground`, `--window-chrome-muted-foreground`,
@@ -69,15 +70,16 @@ Keep the root bounded and make one descendant own each scroll region:
69
70
  paddingBottom: 'var(--window-content-inset-bottom)',
70
71
  }}
71
72
  >
72
- <Toolbar>{/* app title and primary actions */}</Toolbar>
73
+ <Toolbar position="top">
74
+ {/* current view/document title and primary actions */}
75
+ </Toolbar>
73
76
  <PanelContent>{/* the primary canvas or collection */}</PanelContent>
74
77
  </main>
75
78
  ```
76
79
 
77
- This conservative layout places app chrome below any overlay titlebar. A
78
- future shared window-shell recipe may integrate a toolbar into a host-declared
79
- drag region, but only the platform adapter should mark draggable and
80
- non-draggable areas.
80
+ In an app-owned window, the top toolbar becomes a 52-point unified row and
81
+ clears the traffic-light lane automatically. In embedded presentation it keeps
82
+ the selected density and all native window insets resolve to zero.
81
83
 
82
84
  In embedded presentation all window insets resolve to zero. If chat overlays
83
85
  the app, the owning bottom scroll region uses `--chat-safe-padding`. A
@@ -88,7 +90,9 @@ actually overlaid in that window.
88
90
 
89
91
  A standalone app should identify itself without relying on a global sidebar:
90
92
 
91
- - Put the current app or document identity in its own top region.
93
+ - Put the current view or document identity in its top region. Keep the native
94
+ window title for system metadata; do not repeat the app name as visual chrome
95
+ when it adds no context.
92
96
  - Keep the primary object visually dominant.
93
97
  - Place frequent tools near the edge of the canvas they affect.
94
98
  - Use a sidebar or inspector only when the task needs one.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moldable-ai/ui",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Shared UI components for Moldable applications",
5
5
  "author": "Desiderata LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -51,7 +51,7 @@
51
51
  "test": "vitest run",
52
52
  "test:visual": "pnpm build:visual-host && playwright test --config playwright.visual.config.ts",
53
53
  "test:visual:update": "pnpm build:visual-host && playwright test --config playwright.visual.config.ts --update-snapshots",
54
- "filmstrip:orb-spawn": "node scripts/render-orb-spawn-filmstrip.mjs",
54
+ "filmstrip:orb-spawn": "node scripts/render-orb-spawn-gl.mjs",
55
55
  "visual:serve": "vite preview --config vite.visual.config.ts --host 127.0.0.1 --port 4179 --strictPort"
56
56
  },
57
57
  "dependencies": {
@@ -5,12 +5,10 @@ surface.
5
5
 
6
6
  ```tsx
7
7
  <AppFrame>
8
- <AppFrameTitlebar>
9
- <AppFrameToolbar>
10
- <strong>Calendar</strong>
11
- <div className="ml-auto">{/* compact actions */}</div>
12
- </AppFrameToolbar>
13
- </AppFrameTitlebar>
8
+ <Toolbar position="top">
9
+ <ToolbarTitle>Today</ToolbarTitle>
10
+ <ToolbarActions>{/* compact actions */}</ToolbarActions>
11
+ </Toolbar>
14
12
  <AppFrameContent>{/* the app-owned canvas */}</AppFrameContent>
15
13
  <AppFrameStatusbar>Saved locally</AppFrameStatusbar>
16
14
  </AppFrame>
@@ -24,8 +22,8 @@ surface.
24
22
  - Titlebars and status bars use `material="regular"` by default. Use
25
23
  `material="clear"` only when compact chrome overlays a rich canvas, or
26
24
  `material="none"` when the composition supplies an opaque surface.
27
- - The app frame does not make the outer window draggable. A decorated native
28
- titlebar or host-owned drag region must provide that behavior.
25
+ - Use a top `Toolbar` for app-owned window chrome. It consumes the traffic-light
26
+ inset and bridges non-interactive drags to the native host.
29
27
  - The host owns the `--window-*` inset variables. The component only consumes
30
28
  them.
31
29
  - `AppFrameContent` applies the shared chat-safe padding by default. The value is
@@ -1,6 +1,9 @@
1
1
  # Toolbar
2
2
 
3
- Compact pane chrome for context and actions.
3
+ Native-window-aware toolbar chrome for context and actions. A top toolbar is
4
+ draggable and automatically clears the host-advertised traffic-light lane when
5
+ the app owns its titlebar. The same component remains compact pane chrome in an
6
+ embedded view.
4
7
 
5
8
  ```tsx
6
9
  <Toolbar position="top">
@@ -20,6 +23,16 @@ Use one toolbar per pane. Put the current context before actions and keep one
20
23
  clear primary action. Toolbars are not marketing headers. Icon-only actions
21
24
  need labels and tooltips.
22
25
 
26
+ `ToolbarTitle` names the current view or document, not the app itself. Omit it
27
+ when there is no useful view context; the remaining toolbar still provides a
28
+ drag surface and a safe home for right-aligned actions.
29
+
30
+ The `inset` prop defaults to `auto`. Use `none` for a top toolbar that is not
31
+ window chrome, `windowControls` to force the standard control lane, or
32
+ `windowControlsAndButton` when another leading control sits beside the native
33
+ traffic lights. Set `draggable={false}` only for top toolbars that are nested
34
+ inside app content.
35
+
23
36
  The default toolbar uses `material="regular"`. The `plain` and `panel` variants
24
37
  default to `material="none"`; pass a material explicitly only when the toolbar
25
38
  actually floats over content. Reserve `material="clear"` for compact controls
@@ -946,6 +946,34 @@
946
946
  --chat-safe-padding: 0px;
947
947
  }
948
948
 
949
+ /*
950
+ * A top Toolbar becomes unified native window chrome only when the host gives
951
+ * the app ownership of the titlebar. Embedded views and ordinary pane
952
+ * toolbars retain their density-specific compact sizing.
953
+ */
954
+ :root[data-moldable-display-mode='window'][data-moldable-window-titlebar='app']
955
+ [data-slot='toolbar'][data-position='top']:not(
956
+ [data-window-inset='none']
957
+ ) {
958
+ min-height: max(3.25rem, var(--window-titlebar-height, 0px));
959
+ padding-inline-start: max(
960
+ var(--density-control-padding-inline, 0.625rem),
961
+ var(--window-control-inset-inline-start, 0px)
962
+ );
963
+ padding-inline-end: max(
964
+ var(--density-control-padding-inline, 0.625rem),
965
+ var(--window-control-inset-inline-end, 0px)
966
+ );
967
+ }
968
+
969
+ :root[data-moldable-display-mode='window'][data-moldable-window-titlebar='app']
970
+ [data-slot='toolbar'][data-position='top'][data-window-inset='windowControlsAndButton'] {
971
+ padding-inline-start: max(
972
+ var(--density-control-padding-inline, 0.625rem),
973
+ calc(var(--window-control-inset-inline-start, 0px) + 2.75rem)
974
+ );
975
+ }
976
+
949
977
  :where([data-density='compact']) {
950
978
  --density-control-height-xs: 1.375rem;
951
979
  --density-control-height-sm: 1.75rem;