@moldable-ai/ui 0.2.25 → 0.2.29

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 (68) hide show
  1. package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
  2. package/dist/catalog/core-foundation-stories.js +15 -3
  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 +1 -1
  25. package/dist/components/ui/button.d.ts.map +1 -1
  26. package/dist/components/ui/button.js +1 -0
  27. package/dist/components/ui/checkbox.js +1 -1
  28. package/dist/components/ui/collapsible.js +1 -1
  29. package/dist/components/ui/combobox.js +1 -1
  30. package/dist/components/ui/command.d.ts.map +1 -1
  31. package/dist/components/ui/command.js +10 -2
  32. package/dist/components/ui/date-field.js +1 -1
  33. package/dist/components/ui/index.d.ts +1 -0
  34. package/dist/components/ui/index.d.ts.map +1 -1
  35. package/dist/components/ui/index.js +1 -0
  36. package/dist/components/ui/input-group.d.ts.map +1 -1
  37. package/dist/components/ui/input-otp.js +1 -1
  38. package/dist/components/ui/input.js +1 -1
  39. package/dist/components/ui/inspector.js +3 -3
  40. package/dist/components/ui/menubar.js +1 -1
  41. package/dist/components/ui/number-input.js +1 -1
  42. package/dist/components/ui/panel.d.ts +2 -2
  43. package/dist/components/ui/panel.js +2 -2
  44. package/dist/components/ui/radio-group.js +1 -1
  45. package/dist/components/ui/select.js +1 -1
  46. package/dist/components/ui/switch.js +1 -1
  47. package/dist/components/ui/toolbar-controls.d.ts +47 -0
  48. package/dist/components/ui/toolbar-controls.d.ts.map +1 -0
  49. package/dist/components/ui/toolbar-controls.js +40 -0
  50. package/dist/components/ui/toolbar.d.ts +15 -4
  51. package/dist/components/ui/toolbar.d.ts.map +1 -1
  52. package/dist/components/ui/toolbar.js +16 -5
  53. package/dist/components/ui/window-titlebar.d.ts +8 -0
  54. package/dist/components/ui/window-titlebar.d.ts.map +1 -0
  55. package/dist/components/ui/window-titlebar.js +40 -0
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/lib/commands.d.ts +29 -0
  60. package/dist/lib/commands.d.ts.map +1 -1
  61. package/dist/lib/commands.js +28 -0
  62. package/docs/app-anatomy.md +9 -7
  63. package/docs/standalone-app-windows.md +12 -8
  64. package/package.json +2 -2
  65. package/src/components/ui/app-frame.md +6 -8
  66. package/src/components/ui/toolbar-controls.md +75 -0
  67. package/src/components/ui/toolbar.md +20 -1
  68. package/src/styles/index.css +66 -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 };
@@ -0,0 +1,47 @@
1
+ import * as React from 'react';
2
+ import type { MenuItems } from '../../lib/host-native-menu.js';
3
+ import { Button } from './button.js';
4
+ import { type IconButtonProps, type IconButtonSize } from './icon-button.js';
5
+ import { Separator } from './separator.js';
6
+ type ToolbarControlAppearance = 'chrome' | 'quiet';
7
+ export interface ToolbarButtonProps extends React.ComponentProps<typeof Button> {
8
+ /**
9
+ * `chrome` uses the raised translucent toolbar surface. `quiet` is useful
10
+ * inside a ToolbarControlGroup, which owns the shared surface.
11
+ */
12
+ appearance?: ToolbarControlAppearance;
13
+ }
14
+ declare function ToolbarButton({ appearance, className, size, variant, ...props }: ToolbarButtonProps): import("react/jsx-runtime").JSX.Element;
15
+ export interface ToolbarIconButtonProps extends Omit<IconButtonProps, 'size'> {
16
+ appearance?: ToolbarControlAppearance;
17
+ size?: IconButtonSize;
18
+ }
19
+ declare function ToolbarIconButton({ appearance, className, size, variant, ...props }: ToolbarIconButtonProps): import("react/jsx-runtime").JSX.Element;
20
+ export interface ToolbarControlGroupProps extends React.ComponentProps<'div'> {
21
+ appearance?: ToolbarControlAppearance;
22
+ }
23
+ declare function ToolbarControlGroup({ appearance, className, ...props }: ToolbarControlGroupProps): import("react/jsx-runtime").JSX.Element;
24
+ declare function ToolbarControlSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): import("react/jsx-runtime").JSX.Element;
25
+ export interface ToolbarBackButtonProps extends Omit<ToolbarIconButtonProps, 'children' | 'label'> {
26
+ label?: string;
27
+ }
28
+ declare function ToolbarBackButton({ label, tooltip, ...props }: ToolbarBackButtonProps): import("react/jsx-runtime").JSX.Element;
29
+ export interface ToolbarSidebarToggleProps extends Omit<ToolbarIconButtonProps, 'aria-pressed' | 'children' | 'label' | 'onClick'> {
30
+ expanded: boolean;
31
+ onExpandedChange: (expanded: boolean) => void;
32
+ showLabel?: string;
33
+ hideLabel?: string;
34
+ }
35
+ declare function ToolbarSidebarToggle({ expanded, hideLabel, onExpandedChange, showLabel, tooltip, ...props }: ToolbarSidebarToggleProps): import("react/jsx-runtime").JSX.Element;
36
+ export interface ToolbarOverflowMenuProps extends Omit<ToolbarIconButtonProps, 'children' | 'label' | 'onClick'> {
37
+ items: MenuItems[];
38
+ label?: string;
39
+ onSelectItem?: (id: string) => void;
40
+ }
41
+ declare function ToolbarOverflowMenu({ items, label, onSelectItem, tooltip, ...props }: ToolbarOverflowMenuProps): import("react/jsx-runtime").JSX.Element;
42
+ export interface ToolbarTitleFieldProps extends Omit<React.ComponentProps<'input'>, 'size'> {
43
+ label?: string;
44
+ }
45
+ declare function ToolbarTitleField({ 'aria-label': ariaLabel, className, label, type, ...props }: ToolbarTitleFieldProps): import("react/jsx-runtime").JSX.Element;
46
+ export { ToolbarBackButton, ToolbarButton, ToolbarControlGroup, ToolbarControlSeparator, ToolbarIconButton, ToolbarOverflowMenu, ToolbarSidebarToggle, ToolbarTitleField, };
47
+ //# sourceMappingURL=toolbar-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbar-controls.d.ts","sourceRoot":"","sources":["../../../src/components/ui/toolbar-controls.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { ChevronLeftIcon, EllipsisIcon, PanelLeftIcon } from 'lucide-react';
4
+ import * as React from 'react';
5
+ import { cn } from '../../lib/utils.js';
6
+ import { Button } from './button.js';
7
+ import { DropdownMenu, DropdownMenuTrigger } from './dropdown-menu.js';
8
+ import { IconButton, } from './icon-button.js';
9
+ import { Separator } from './separator.js';
10
+ const ToolbarControlGroupContext = React.createContext(null);
11
+ function ToolbarButton({ appearance = 'chrome', className, size, variant, ...props }) {
12
+ const group = React.useContext(ToolbarControlGroupContext);
13
+ return (_jsx(Button, { "data-slot": "toolbar-button", size: size ?? (group ? 'sm' : 'lg'), variant: variant ?? (group || appearance === 'quiet' ? 'ghost' : 'toolbar'), className: cn(group && 'shadow-none', className), ...props }));
14
+ }
15
+ function ToolbarIconButton({ appearance = 'chrome', className, size, variant, ...props }) {
16
+ const group = React.useContext(ToolbarControlGroupContext);
17
+ return (_jsx(IconButton, { "data-slot": "toolbar-icon-button", size: size ?? (group ? 'sm' : 'lg'), variant: variant ?? (group || appearance === 'quiet' ? 'ghost' : 'toolbar'), className: cn(group && 'shadow-none', className), ...props }));
18
+ }
19
+ function ToolbarControlGroup({ appearance = 'chrome', className, ...props }) {
20
+ return (_jsx(ToolbarControlGroupContext.Provider, { value: { grouped: true }, children: _jsx("div", { role: "group", "data-slot": "toolbar-control-group", "data-appearance": appearance, className: cn('h-control-lg rounded-control flex shrink-0 items-center', appearance === 'chrome'
21
+ ? 'gap-0.5 border border-[var(--toolbar-control-border)] bg-[var(--toolbar-control-background)] p-1 shadow-[var(--toolbar-control-shadow)]'
22
+ : 'gap-1.5', className), ...props }) }));
23
+ }
24
+ function ToolbarControlSeparator({ className, ...props }) {
25
+ return (_jsx(Separator, { "data-slot": "toolbar-control-separator", orientation: "vertical", className: cn('mx-0.5 h-4 self-center bg-[var(--toolbar-control-border)]', className), ...props }));
26
+ }
27
+ function ToolbarBackButton({ label = 'Back', tooltip = true, ...props }) {
28
+ return (_jsx(ToolbarIconButton, { label: label, tooltip: tooltip, ...props, children: _jsx(ChevronLeftIcon, {}) }));
29
+ }
30
+ function ToolbarSidebarToggle({ expanded, hideLabel = 'Hide sidebar', onExpandedChange, showLabel = 'Show sidebar', tooltip = true, ...props }) {
31
+ const label = expanded ? hideLabel : showLabel;
32
+ return (_jsx(ToolbarIconButton, { "aria-pressed": expanded, "data-state": expanded ? 'on' : 'off', label: label, tooltip: tooltip, onClick: () => onExpandedChange(!expanded), ...props, children: _jsx(PanelLeftIcon, {}) }));
33
+ }
34
+ function ToolbarOverflowMenu({ items, label = 'More actions', onSelectItem, tooltip = true, ...props }) {
35
+ return (_jsx(DropdownMenu, { items: items, onSelectItem: onSelectItem, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(ToolbarIconButton, { label: label, tooltip: tooltip, ...props, children: _jsx(EllipsisIcon, {}) }) }) }));
36
+ }
37
+ function ToolbarTitleField({ 'aria-label': ariaLabel, className, label = 'Document title', type = 'text', ...props }) {
38
+ return (_jsx("input", { "data-slot": "toolbar-title-field", "aria-label": ariaLabel ?? label, type: type, className: cn('text-foreground hover:bg-control-hover focus:bg-control-hover focus-visible:ring-ring h-control-sm rounded-control min-w-0 max-w-[min(24rem,32vw)] bg-transparent px-2 text-[15px] font-medium outline-none transition-colors focus-visible:ring-1', className), ...props }));
39
+ }
40
+ export { ToolbarBackButton, ToolbarButton, ToolbarControlGroup, ToolbarControlSeparator, ToolbarIconButton, ToolbarOverflowMenu, ToolbarSidebarToggle, ToolbarTitleField, };
@@ -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":"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"}
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.29",
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