@moldable-ai/ui 0.2.29 → 0.2.32
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.
- package/dist/catalog/component-catalog.d.ts +9 -2
- package/dist/catalog/component-catalog.d.ts.map +1 -1
- package/dist/catalog/component-catalog.js +11 -7
- package/dist/catalog/core-control-stories.d.ts.map +1 -1
- package/dist/catalog/core-control-stories.js +1 -1
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
- package/dist/catalog/core-foundation-stories.js +5 -5
- package/dist/components/app-error-boundary.d.ts +1 -1
- package/dist/components/chat/chat-image-lightbox.d.ts +8 -0
- package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -1
- package/dist/components/chat/chat-image-lightbox.js +24 -2
- package/dist/components/chat/chat-input.d.ts +3 -2
- package/dist/components/chat/chat-input.d.ts.map +1 -1
- package/dist/components/chat/chat-input.js +3 -3
- package/dist/components/chat/chat-message.d.ts.map +1 -1
- package/dist/components/chat/chat-message.js +3 -1
- package/dist/components/chat/chat-panel.d.ts +3 -1
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +53 -39
- package/dist/components/chat/conversation-history.d.ts +4 -2
- package/dist/components/chat/conversation-history.d.ts.map +1 -1
- package/dist/components/chat/conversation-history.js +20 -15
- package/dist/components/ui/alert.d.ts +1 -1
- package/dist/components/ui/app-frame.d.ts +20 -1
- package/dist/components/ui/app-frame.d.ts.map +1 -1
- package/dist/components/ui/app-frame.js +37 -7
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/button.d.ts +5 -3
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +39 -11
- package/dist/components/ui/card.d.ts +12 -2
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +3 -2
- package/dist/components/ui/checkbox.d.ts +4 -1
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox.js +4 -4
- package/dist/components/ui/context-menu.d.ts.map +1 -1
- package/dist/components/ui/context-menu.js +7 -6
- package/dist/components/ui/date-field.d.ts +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +1 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +9 -8
- package/dist/components/ui/icon-button.d.ts +1 -1
- package/dist/components/ui/icon-button.d.ts.map +1 -1
- package/dist/components/ui/icon-button.js +1 -0
- package/dist/components/ui/input.d.ts +6 -2
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/input.js +2 -2
- package/dist/components/ui/material.d.ts +8 -3
- package/dist/components/ui/material.d.ts.map +1 -1
- package/dist/components/ui/material.js +2 -2
- package/dist/components/ui/menu-items.d.ts +2 -1
- package/dist/components/ui/menu-items.d.ts.map +1 -1
- package/dist/components/ui/menu-items.js +3 -2
- package/dist/components/ui/message-scroller-controller.d.ts +15 -17
- package/dist/components/ui/message-scroller-controller.d.ts.map +1 -1
- package/dist/components/ui/message-scroller-controller.js +106 -91
- package/dist/components/ui/message-scroller-primitive.d.ts +2 -0
- package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -1
- package/dist/components/ui/message-scroller-primitive.js +2 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -1
- package/dist/components/ui/message-scroller.js +2 -2
- package/dist/components/ui/number-input.d.ts +1 -1
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/search-field.d.ts +4 -2
- package/dist/components/ui/search-field.d.ts.map +1 -1
- package/dist/components/ui/search-field.js +16 -6
- package/dist/components/ui/segmented-control.d.ts +3 -1
- package/dist/components/ui/segmented-control.d.ts.map +1 -1
- package/dist/components/ui/segmented-control.js +23 -17
- package/dist/components/ui/select.js +2 -2
- package/dist/components/ui/sidebar.d.ts +10 -4
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/sidebar.js +74 -17
- package/dist/components/ui/status.d.ts +1 -1
- package/dist/components/ui/status.js +1 -1
- package/dist/components/ui/switch.d.ts +3 -1
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/switch.js +3 -2
- package/dist/components/ui/toolbar-controls.d.ts +13 -3
- package/dist/components/ui/toolbar-controls.d.ts.map +1 -1
- package/dist/components/ui/toolbar-controls.js +35 -10
- package/dist/components/ui/toolbar.d.ts +5 -4
- package/dist/components/ui/toolbar.d.ts.map +1 -1
- package/dist/components/ui/toolbar.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/frame-lifecycle.d.ts +1 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +7 -0
- package/dist/lib/theme.d.ts +39 -5
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +105 -17
- package/dist/tokens/contracts.d.ts +79 -0
- package/dist/tokens/contracts.d.ts.map +1 -0
- package/dist/tokens/contracts.js +57 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +1 -0
- package/docs/README.md +2 -0
- package/docs/adaptive-materials.md +14 -9
- package/docs/design-tokens.md +10 -6
- package/docs/foundations.md +3 -3
- package/docs/macos-design-audit.md +144 -0
- package/docs/native-integration.md +4 -4
- package/docs/platform-architecture.md +189 -0
- package/docs/standalone-app-windows.md +37 -0
- package/docs/visual-regression.md +6 -8
- package/package.json +13 -1
- package/src/components/ui/accordion.md +46 -0
- package/src/components/ui/alert.md +12 -4
- package/src/components/ui/app-frame.md +8 -5
- package/src/components/ui/aspect-ratio.md +37 -0
- package/src/components/ui/avatar.md +48 -0
- package/src/components/ui/breadcrumb.md +52 -0
- package/src/components/ui/button-group.md +43 -0
- package/src/components/ui/button.md +21 -4
- package/src/components/ui/calendar.md +42 -0
- package/src/components/ui/card.md +43 -0
- package/src/components/ui/carousel.md +47 -0
- package/src/components/ui/chart.md +52 -0
- package/src/components/ui/checkbox.md +36 -0
- package/src/components/ui/collapsible.md +2 -3
- package/src/components/ui/color-well.md +14 -4
- package/src/components/ui/combobox.md +3 -3
- package/src/components/ui/confirm-dialog.md +5 -4
- package/src/components/ui/context-menu.md +3 -2
- package/src/components/ui/date-field.md +6 -1
- package/src/components/ui/date-picker.md +6 -3
- package/src/components/ui/dialog.md +14 -12
- package/src/components/ui/drawer.md +58 -0
- package/src/components/ui/dropdown-menu.md +16 -14
- package/src/components/ui/error-boundary-view.md +1 -1
- package/src/components/ui/field.md +2 -1
- package/src/components/ui/form.md +71 -0
- package/src/components/ui/grid.md +4 -3
- package/src/components/ui/icon-button.md +4 -1
- package/src/components/ui/input-group.md +49 -0
- package/src/components/ui/input-otp.md +56 -0
- package/src/components/ui/input.md +40 -0
- package/src/components/ui/inspector.md +47 -7
- package/src/components/ui/item.md +5 -3
- package/src/components/ui/kbd.md +30 -0
- package/src/components/ui/label.md +29 -0
- package/src/components/ui/list.md +2 -2
- package/src/components/ui/material.md +25 -12
- package/src/components/ui/menu-items.md +62 -0
- package/src/components/ui/menubar.md +58 -0
- package/src/components/ui/message-scroller-primitive.md +70 -0
- package/src/components/ui/message-scroller.md +89 -0
- package/src/components/ui/navigation-button-group.md +4 -3
- package/src/components/ui/navigation-menu.md +52 -0
- package/src/components/ui/number-input.md +8 -0
- package/src/components/ui/pagination.md +51 -0
- package/src/components/ui/panel.md +6 -0
- package/src/components/ui/popover.md +10 -7
- package/src/components/ui/progress.md +31 -0
- package/src/components/ui/radio-group.md +36 -0
- package/src/components/ui/resizable.md +2 -1
- package/src/components/ui/scroll-area.md +3 -1
- package/src/components/ui/search-field.md +6 -1
- package/src/components/ui/segmented-control.md +6 -1
- package/src/components/ui/separator.md +35 -0
- package/src/components/ui/sidebar.md +29 -6
- package/src/components/ui/skeleton.md +36 -0
- package/src/components/ui/slider.md +58 -0
- package/src/components/ui/spinner.md +41 -0
- package/src/components/ui/split-view.md +8 -4
- package/src/components/ui/switch.md +44 -0
- package/src/components/ui/table.md +7 -7
- package/src/components/ui/tabs.md +3 -1
- package/src/components/ui/textarea.md +41 -0
- package/src/components/ui/toggle-group.md +2 -2
- package/src/components/ui/toggle.md +9 -9
- package/src/components/ui/toolbar-controls.md +24 -12
- package/src/components/ui/toolbar.md +6 -6
- package/src/styles/index.css +298 -117
- package/src/tokens/contracts.ts +131 -0
- package/src/tokens/index.css +6 -0
- package/src/tokens/index.ts +23 -0
- package/src/tokens/macos-26/README.md +37 -0
- package/src/tokens/macos-26/aliases.css +53 -0
- package/src/tokens/macos-26/compatibility.css +7 -0
- package/src/tokens/macos-26/index.css +3 -0
- package/src/tokens/macos-26/source/provenance.generated.json +28 -0
- package/src/tokens/macos-26/source/sidebar.generated.css +29 -0
- package/src/tokens/macos-26/source.css +7 -0
- package/src/tokens/macos-26/web-adaptations.json +25 -0
- package/src/tokens/macos-26/web-adaptations.md +15 -0
- package/src/tokens/macos-27/accessibility.css +11 -0
- package/src/tokens/macos-27/aliases.css +304 -0
- package/src/tokens/macos-27/compatibility.css +212 -0
- package/src/tokens/macos-27/index.css +15 -0
- package/src/tokens/macos-27/recipes.css +23 -0
- package/src/tokens/macos-27/source/chrome.generated.css +338 -0
- package/src/tokens/macos-27/source/colors.generated.css +140 -0
- package/src/tokens/macos-27/source/context.generated.css +18 -0
- package/src/tokens/macos-27/source/controls.generated.css +764 -0
- package/src/tokens/macos-27/source/effects.generated.css +68 -0
- package/src/tokens/macos-27/source/kit.generated.css +50 -0
- package/src/tokens/macos-27/source/overlays-status.generated.css +931 -0
- package/src/tokens/macos-27/source/paint-styles.generated.css +81 -0
- package/src/tokens/macos-27/source/provenance.generated.json +62 -0
- package/src/tokens/macos-27/source/sizes.generated.css +385 -0
- package/src/tokens/macos-27/source/source.generated.json +554 -0
- package/src/tokens/macos-27/source/text-styles.generated.css +116 -0
- package/src/tokens/macos-27/source.css +17 -0
- package/src/tokens/macos-27/web-adaptations.css +98 -0
- package/src/tokens/macos-27/web-adaptations.json +163 -0
- package/src/tokens/macos-27/web-adaptations.md +117 -0
- package/src/tokens/moldable/brand.css +165 -0
- package/src/tokens/moldable/index.css +1 -0
- package/src/tokens/platform-contract.test.ts +294 -0
|
@@ -3,8 +3,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { cn } from '../../lib/utils.js';
|
|
4
4
|
import { Separator } from './separator.js';
|
|
5
5
|
import { Text } from './text.js';
|
|
6
|
-
import { cva } from 'class-variance-authority';
|
|
7
6
|
import { handleWindowTitlebarDoubleClick, handleWindowTitlebarMouseDown, } from './window-titlebar.js';
|
|
7
|
+
import { cva } from 'class-variance-authority';
|
|
8
8
|
const toolbarVariants = cva('z-20 flex min-h-toolbar w-full shrink-0 items-center gap-control-gap px-control-inline', {
|
|
9
9
|
variants: {
|
|
10
10
|
variant: {
|
|
@@ -18,7 +18,7 @@ const toolbarVariants = cva('z-20 flex min-h-toolbar w-full shrink-0 items-cente
|
|
|
18
18
|
none: '',
|
|
19
19
|
},
|
|
20
20
|
density: {
|
|
21
|
-
compact: 'py-
|
|
21
|
+
compact: 'py-2',
|
|
22
22
|
default: 'py-1.5',
|
|
23
23
|
comfortable: 'py-2',
|
|
24
24
|
},
|
|
@@ -68,7 +68,7 @@ function ToolbarContent({ className, ...props }) {
|
|
|
68
68
|
return (_jsx("div", { "data-slot": "toolbar-content", className: cn('flex min-w-0 flex-1 flex-col', className), ...props }));
|
|
69
69
|
}
|
|
70
70
|
function ToolbarTitle({ className, ...props }) {
|
|
71
|
-
return (_jsx(Text, { as: "h2", variant: "strong", truncate: true, "data-slot": "toolbar-title", className: cn('text-[
|
|
71
|
+
return (_jsx(Text, { as: "h2", variant: "strong", truncate: true, "data-slot": "toolbar-title", className: cn('text-[13px] font-bold leading-[15px]', className), ...props }));
|
|
72
72
|
}
|
|
73
73
|
function ToolbarDescription({ className, ...props }) {
|
|
74
74
|
return (_jsx(Text, { as: "p", variant: "small", color: "secondary", truncate: true, "data-slot": "toolbar-description", className: className, ...props }));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { cn } from './lib/utils.js';
|
|
2
|
-
export { ThemeProvider, useTheme, themeScript, type Theme } from './lib/theme.js';
|
|
2
|
+
export { ThemeProvider, useTheme, themeScript, type Theme, type ThemeProviderProps, } from './lib/theme.js';
|
|
3
|
+
export * from './tokens/index.js';
|
|
3
4
|
export { WorkspaceProvider, useWorkspace, WORKSPACE_HEADER, } from './lib/workspace.js';
|
|
4
5
|
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
6
|
export * from './lib/native-capabilities/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAGhC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Export utilities
|
|
2
2
|
export { cn } from './lib/utils.js';
|
|
3
3
|
// Export theme
|
|
4
|
-
export { ThemeProvider, useTheme, themeScript } from './lib/theme.js';
|
|
4
|
+
export { ThemeProvider, useTheme, themeScript, } from './lib/theme.js';
|
|
5
|
+
// Export design-system contracts
|
|
6
|
+
export * from './tokens/index.js';
|
|
5
7
|
// Export workspace
|
|
6
8
|
export { WorkspaceProvider, useWorkspace, WORKSPACE_HEADER, } from './lib/workspace.js';
|
|
7
9
|
// Export commands
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-lifecycle.d.ts","sourceRoot":"","sources":["../../src/lib/frame-lifecycle.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"frame-lifecycle.d.ts","sourceRoot":"","sources":["../../src/lib/frame-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -156,6 +156,13 @@ export function applyMoldableHostContext(message) {
|
|
|
156
156
|
delete root.dataset.moldableNativeMaterialSidebar;
|
|
157
157
|
clearSidebarMaterialRegion();
|
|
158
158
|
}
|
|
159
|
+
if (message.displayMode === 'window' &&
|
|
160
|
+
message.nativeMaterial?.background === true) {
|
|
161
|
+
root.dataset.moldableNativeMaterialBackground = 'available';
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
delete root.dataset.moldableNativeMaterialBackground;
|
|
165
|
+
}
|
|
159
166
|
const insets = message.safeInsets;
|
|
160
167
|
if (insets) {
|
|
161
168
|
applyBoundedLength('--window-safe-area-top', insets.top);
|
package/dist/lib/theme.d.ts
CHANGED
|
@@ -1,15 +1,49 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import type { ControlSize, MaterialContext, ResolvedUIAppearance, UIAppearance, UIPlatform, UIPlatformPack, UIPlatformVersion, UIPreferences, UISidebarStyle, UITheme } from '../tokens/contracts.js';
|
|
3
|
+
/** @deprecated Use UIAppearance. */
|
|
4
|
+
export type Theme = UIAppearance;
|
|
5
|
+
/** @deprecated Use ResolvedUIAppearance. */
|
|
6
|
+
type ResolvedTheme = ResolvedUIAppearance;
|
|
4
7
|
interface ThemeContextValue {
|
|
8
|
+
uiTheme: UITheme;
|
|
9
|
+
setUITheme: (theme: UITheme) => void;
|
|
10
|
+
platform: UIPlatform;
|
|
11
|
+
platformVersion: UIPlatformVersion;
|
|
12
|
+
platformPack: UIPlatformPack;
|
|
13
|
+
setPlatformPack: (platform: UIPlatform, version: UIPlatformVersion) => void;
|
|
14
|
+
sidebarStyle: UISidebarStyle;
|
|
15
|
+
setSidebarStyle: (style: UISidebarStyle) => void;
|
|
16
|
+
appearance: UIAppearance;
|
|
17
|
+
resolvedAppearance: ResolvedUIAppearance;
|
|
18
|
+
setAppearance: (appearance: UIAppearance) => void;
|
|
19
|
+
controlSize: ControlSize;
|
|
20
|
+
setControlSize: (controlSize: ControlSize) => void;
|
|
21
|
+
materialContext: MaterialContext;
|
|
22
|
+
setMaterialContext: (materialContext: MaterialContext) => void;
|
|
23
|
+
preferences: UIPreferences;
|
|
24
|
+
/** @deprecated Use appearance. */
|
|
5
25
|
theme: Theme;
|
|
26
|
+
/** @deprecated Use resolvedAppearance. */
|
|
6
27
|
resolvedTheme: ResolvedTheme;
|
|
28
|
+
/** @deprecated Use setAppearance. */
|
|
7
29
|
setTheme: (theme: Theme) => void;
|
|
8
30
|
}
|
|
9
|
-
export
|
|
31
|
+
export interface ThemeProviderProps {
|
|
10
32
|
children: ReactNode;
|
|
11
|
-
|
|
33
|
+
platform?: UIPlatform;
|
|
34
|
+
platformVersion?: UIPlatformVersion;
|
|
35
|
+
uiTheme?: UITheme;
|
|
36
|
+
sidebarStyle?: UISidebarStyle;
|
|
37
|
+
appearance?: UIAppearance;
|
|
38
|
+
controlSize?: ControlSize;
|
|
39
|
+
materialContext?: MaterialContext;
|
|
40
|
+
preferences?: UIPreferences;
|
|
41
|
+
storageKey?: string | false;
|
|
42
|
+
}
|
|
43
|
+
export declare function ThemeProvider({ children, platform, platformVersion, uiTheme: uiThemeProp, sidebarStyle: sidebarStyleProp, appearance: appearanceProp, controlSize: controlSizeProp, materialContext: materialContextProp, preferences, storageKey, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
12
44
|
export declare function useTheme(): ThemeContextValue;
|
|
45
|
+
/** Internal-friendly optional access for components that also work standalone. */
|
|
46
|
+
export declare function useOptionalTheme(): ThemeContextValue | null;
|
|
13
47
|
/**
|
|
14
48
|
* Inline script to prevent theme flash on page load.
|
|
15
49
|
* Add this to your <head> in layout.tsx:
|
|
@@ -20,6 +54,6 @@ export declare function useTheme(): ThemeContextValue;
|
|
|
20
54
|
* </head>
|
|
21
55
|
* ```
|
|
22
56
|
*/
|
|
23
|
-
export declare const themeScript = "\n(function() {\n var params = new URLSearchParams(window.location.search);\n var theme = params.get('theme');\n if (!theme) {\n theme = localStorage.getItem('moldable-theme');\n }\n if (theme === 'system' || !theme) {\n theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n document.documentElement.classList.add(theme);\n})();\n";
|
|
57
|
+
export declare const themeScript = "\n(function() {\n var params = new URLSearchParams(window.location.search);\n var theme = params.get('theme');\n if (!theme) {\n theme = localStorage.getItem('moldable-theme');\n }\n if (theme === 'system' || !theme) {\n theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n document.documentElement.classList.add(theme);\n document.documentElement.dataset.uiTheme = 'moldable';\n document.documentElement.dataset.uiPlatform = 'macos';\n document.documentElement.dataset.uiPlatformVersion = '27';\n document.documentElement.dataset.uiPlatformPack = 'macos-27';\n document.documentElement.dataset.uiSidebarStyle = 'edge-to-edge';\n document.documentElement.dataset.uiAppearance = theme;\n document.documentElement.dataset.controlSize = 'medium';\n document.documentElement.dataset.materialContext = 'content';\n})();\n";
|
|
24
58
|
export {};
|
|
25
59
|
//# sourceMappingURL=theme.d.ts.map
|
package/dist/lib/theme.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/lib/theme.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/lib/theme.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAA;AAEd,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,OAAO,EACR,MAAM,qBAAqB,CAAA;AAG5B,oCAAoC;AACpC,MAAM,MAAM,KAAK,GAAG,YAAY,CAAA;AAChC,4CAA4C;AAC5C,KAAK,aAAa,GAAG,oBAAoB,CAAA;AAEzC,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,UAAU,CAAA;IACpB,eAAe,EAAE,iBAAiB,CAAA;IAClC,YAAY,EAAE,cAAc,CAAA;IAC5B,eAAe,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAC3E,YAAY,EAAE,cAAc,CAAA;IAC5B,eAAe,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;IAChD,UAAU,EAAE,YAAY,CAAA;IACxB,kBAAkB,EAAE,oBAAoB,CAAA;IACxC,aAAa,EAAE,CAAC,UAAU,EAAE,YAAY,KAAK,IAAI,CAAA;IACjD,WAAW,EAAE,WAAW,CAAA;IACxB,cAAc,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAClD,eAAe,EAAE,eAAe,CAAA;IAChC,kBAAkB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,IAAI,CAAA;IAC9D,WAAW,EAAE,aAAa,CAAA;IAC1B,kCAAkC;IAClC,KAAK,EAAE,KAAK,CAAA;IACZ,0CAA0C;IAC1C,aAAa,EAAE,aAAa,CAAA;IAC5B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAA;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB,eAAe,CAAC,EAAE,iBAAiB,CAAA;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,cAAc,CAAA;IAC7B,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,WAAW,CAAC,EAAE,aAAa,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAC5B;AA2CD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAkB,EAClB,eAAsB,EACtB,OAAO,EAAE,WAAwB,EACjC,YAAY,EAAE,gBAAgB,EAC9B,UAAU,EAAE,cAAc,EAC1B,WAAW,EAAE,eAA0B,EACvC,eAAe,EAAE,mBAA+B,EAChD,WAAgB,EAChB,UAAwB,GACzB,EAAE,kBAAkB,2CA+IpB;AAED,wBAAgB,QAAQ,sBAMvB;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,6BAE/B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,i3BAoBvB,CAAA"}
|
package/dist/lib/theme.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { createContext, useCallback, useContext, useEffect, useState, } from 'react';
|
|
4
4
|
import { TooltipProvider } from '../components/ui/tooltip.js';
|
|
5
|
+
import { resolvePlatformPack } from '../tokens/contracts.js';
|
|
5
6
|
const ThemeContext = createContext(null);
|
|
6
7
|
const STORAGE_KEY = 'moldable-theme';
|
|
7
8
|
function getSystemTheme() {
|
|
@@ -22,14 +23,16 @@ function getUrlTheme() {
|
|
|
22
23
|
}
|
|
23
24
|
return null;
|
|
24
25
|
}
|
|
25
|
-
function getStoredTheme() {
|
|
26
|
+
function getStoredTheme(storageKey = STORAGE_KEY) {
|
|
26
27
|
if (typeof window === 'undefined')
|
|
27
28
|
return 'system';
|
|
28
29
|
// URL parameter takes precedence (for iframe embedding)
|
|
29
30
|
const urlTheme = getUrlTheme();
|
|
30
31
|
if (urlTheme)
|
|
31
32
|
return urlTheme;
|
|
32
|
-
|
|
33
|
+
if (!storageKey)
|
|
34
|
+
return 'system';
|
|
35
|
+
const stored = localStorage.getItem(storageKey);
|
|
33
36
|
if (stored === 'light' || stored === 'dark' || stored === 'system') {
|
|
34
37
|
return stored;
|
|
35
38
|
}
|
|
@@ -41,36 +44,109 @@ function resolveTheme(theme) {
|
|
|
41
44
|
}
|
|
42
45
|
return theme;
|
|
43
46
|
}
|
|
44
|
-
export function ThemeProvider({ children }) {
|
|
45
|
-
const [
|
|
46
|
-
const [
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
export function ThemeProvider({ children, platform = 'macos', platformVersion = '27', uiTheme: uiThemeProp = 'moldable', sidebarStyle: sidebarStyleProp, appearance: appearanceProp, controlSize: controlSizeProp = 'medium', materialContext: materialContextProp = 'content', preferences = {}, storageKey = STORAGE_KEY, }) {
|
|
48
|
+
const [platformSelection, setPlatformSelection] = useState(platform);
|
|
49
|
+
const [platformVersionSelection, setPlatformVersionSelection] = useState(platformVersion);
|
|
50
|
+
const platformPack = resolvePlatformPack(platformSelection, platformVersionSelection);
|
|
51
|
+
const [uiTheme, setUIThemeState] = useState(uiThemeProp);
|
|
52
|
+
const [sidebarStyle, setSidebarStyle] = useState(() => sidebarStyleProp ?? 'edge-to-edge');
|
|
53
|
+
const [appearance, setAppearanceState] = useState(() => appearanceProp ?? getStoredTheme(storageKey));
|
|
54
|
+
const [resolvedAppearance, setResolvedAppearance] = useState(() => resolveTheme(appearance));
|
|
55
|
+
const [controlSize, setControlSize] = useState(controlSizeProp);
|
|
56
|
+
const [materialContext, setMaterialContext] = useState(materialContextProp);
|
|
57
|
+
const setAppearance = useCallback((newAppearance) => {
|
|
58
|
+
setAppearanceState(newAppearance);
|
|
59
|
+
if (storageKey && typeof window !== 'undefined') {
|
|
60
|
+
localStorage.setItem(storageKey, newAppearance);
|
|
61
|
+
}
|
|
62
|
+
}, [storageKey]);
|
|
63
|
+
const setPlatformPack = useCallback((nextPlatform, nextVersion) => {
|
|
64
|
+
setPlatformSelection(nextPlatform);
|
|
65
|
+
setPlatformVersionSelection(nextVersion);
|
|
50
66
|
}, []);
|
|
51
|
-
|
|
67
|
+
const setUITheme = useCallback((nextTheme) => {
|
|
68
|
+
setUIThemeState(nextTheme);
|
|
69
|
+
if (sidebarStyleProp === undefined) {
|
|
70
|
+
setSidebarStyle('edge-to-edge');
|
|
71
|
+
}
|
|
72
|
+
}, [sidebarStyleProp]);
|
|
73
|
+
useEffect(() => setPlatformSelection(platform), [platform]);
|
|
74
|
+
useEffect(() => setPlatformVersionSelection(platformVersion), [platformVersion]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
setUIThemeState(uiThemeProp);
|
|
77
|
+
setSidebarStyle(sidebarStyleProp ?? 'edge-to-edge');
|
|
78
|
+
}, [sidebarStyleProp, uiThemeProp]);
|
|
52
79
|
useEffect(() => {
|
|
53
|
-
|
|
54
|
-
|
|
80
|
+
if (appearanceProp)
|
|
81
|
+
setAppearanceState(appearanceProp);
|
|
82
|
+
}, [appearanceProp]);
|
|
83
|
+
useEffect(() => setControlSize(controlSizeProp), [controlSizeProp]);
|
|
84
|
+
useEffect(() => setMaterialContext(materialContextProp), [materialContextProp]);
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const resolved = resolveTheme(appearance);
|
|
87
|
+
setResolvedAppearance(resolved);
|
|
55
88
|
const root = document.documentElement;
|
|
56
89
|
root.classList.remove('light', 'dark');
|
|
57
90
|
root.classList.add(resolved);
|
|
58
|
-
|
|
59
|
-
|
|
91
|
+
root.dataset.uiTheme = uiTheme;
|
|
92
|
+
root.dataset.uiPlatform = platformPack.platform;
|
|
93
|
+
root.dataset.uiPlatformVersion = platformPack.version;
|
|
94
|
+
root.dataset.uiPlatformPack = platformPack.id;
|
|
95
|
+
root.dataset.uiSidebarStyle = sidebarStyle;
|
|
96
|
+
root.dataset.uiAppearance = resolved;
|
|
97
|
+
root.dataset.controlSize = controlSize;
|
|
98
|
+
root.dataset.materialContext = materialContext;
|
|
99
|
+
root.dataset.contrast = preferences.contrast ?? 'system';
|
|
100
|
+
root.dataset.transparency = preferences.transparency ?? 'system';
|
|
101
|
+
root.dataset.motion = preferences.motion ?? 'system';
|
|
102
|
+
}, [
|
|
103
|
+
appearance,
|
|
104
|
+
controlSize,
|
|
105
|
+
materialContext,
|
|
106
|
+
preferences.contrast,
|
|
107
|
+
preferences.motion,
|
|
108
|
+
preferences.transparency,
|
|
109
|
+
platformPack.id,
|
|
110
|
+
platformPack.platform,
|
|
111
|
+
platformPack.version,
|
|
112
|
+
sidebarStyle,
|
|
113
|
+
uiTheme,
|
|
114
|
+
]);
|
|
60
115
|
useEffect(() => {
|
|
61
|
-
if (
|
|
116
|
+
if (appearance !== 'system')
|
|
62
117
|
return;
|
|
63
118
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
64
119
|
const handleChange = () => {
|
|
65
120
|
const resolved = getSystemTheme();
|
|
66
|
-
|
|
121
|
+
setResolvedAppearance(resolved);
|
|
67
122
|
document.documentElement.classList.remove('light', 'dark');
|
|
68
123
|
document.documentElement.classList.add(resolved);
|
|
124
|
+
document.documentElement.dataset.uiAppearance = resolved;
|
|
69
125
|
};
|
|
70
126
|
mediaQuery.addEventListener('change', handleChange);
|
|
71
127
|
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
72
|
-
}, [
|
|
73
|
-
return (_jsx(ThemeContext.Provider, { value: {
|
|
128
|
+
}, [appearance]);
|
|
129
|
+
return (_jsx(ThemeContext.Provider, { value: {
|
|
130
|
+
uiTheme,
|
|
131
|
+
setUITheme,
|
|
132
|
+
platform: platformPack.platform,
|
|
133
|
+
platformVersion: platformPack.version,
|
|
134
|
+
platformPack,
|
|
135
|
+
setPlatformPack,
|
|
136
|
+
sidebarStyle,
|
|
137
|
+
setSidebarStyle,
|
|
138
|
+
appearance,
|
|
139
|
+
resolvedAppearance,
|
|
140
|
+
setAppearance,
|
|
141
|
+
controlSize,
|
|
142
|
+
setControlSize,
|
|
143
|
+
materialContext,
|
|
144
|
+
setMaterialContext,
|
|
145
|
+
preferences,
|
|
146
|
+
theme: appearance,
|
|
147
|
+
resolvedTheme: resolvedAppearance,
|
|
148
|
+
setTheme: setAppearance,
|
|
149
|
+
}, children: _jsx(TooltipProvider, { children: children }) }));
|
|
74
150
|
}
|
|
75
151
|
export function useTheme() {
|
|
76
152
|
const context = useContext(ThemeContext);
|
|
@@ -79,6 +155,10 @@ export function useTheme() {
|
|
|
79
155
|
}
|
|
80
156
|
return context;
|
|
81
157
|
}
|
|
158
|
+
/** Internal-friendly optional access for components that also work standalone. */
|
|
159
|
+
export function useOptionalTheme() {
|
|
160
|
+
return useContext(ThemeContext);
|
|
161
|
+
}
|
|
82
162
|
/**
|
|
83
163
|
* Inline script to prevent theme flash on page load.
|
|
84
164
|
* Add this to your <head> in layout.tsx:
|
|
@@ -100,5 +180,13 @@ export const themeScript = `
|
|
|
100
180
|
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
101
181
|
}
|
|
102
182
|
document.documentElement.classList.add(theme);
|
|
183
|
+
document.documentElement.dataset.uiTheme = 'moldable';
|
|
184
|
+
document.documentElement.dataset.uiPlatform = 'macos';
|
|
185
|
+
document.documentElement.dataset.uiPlatformVersion = '27';
|
|
186
|
+
document.documentElement.dataset.uiPlatformPack = 'macos-27';
|
|
187
|
+
document.documentElement.dataset.uiSidebarStyle = 'edge-to-edge';
|
|
188
|
+
document.documentElement.dataset.uiAppearance = theme;
|
|
189
|
+
document.documentElement.dataset.controlSize = 'medium';
|
|
190
|
+
document.documentElement.dataset.materialContext = 'content';
|
|
103
191
|
})();
|
|
104
192
|
`;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type UITheme = 'platform' | 'moldable';
|
|
2
|
+
export type UIPlatform = 'macos' | 'windows' | 'web';
|
|
3
|
+
export type UIPlatformVersion = string;
|
|
4
|
+
/**
|
|
5
|
+
* A component recipe can intentionally come from a different versioned
|
|
6
|
+
* platform source than the application's base platform pack.
|
|
7
|
+
*
|
|
8
|
+
* Public names describe the anatomy an app is choosing. The registry below
|
|
9
|
+
* records which immutable platform source defines each recipe.
|
|
10
|
+
*/
|
|
11
|
+
export type UISidebarStyle = 'platform' | 'floating' | 'edge-to-edge';
|
|
12
|
+
export type PlatformPackId = `${UIPlatform}-${string}`;
|
|
13
|
+
export interface UIPlatformPack {
|
|
14
|
+
id: PlatformPackId;
|
|
15
|
+
platform: UIPlatform;
|
|
16
|
+
version: UIPlatformVersion;
|
|
17
|
+
capabilities: {
|
|
18
|
+
nativeMaterials: boolean;
|
|
19
|
+
nativeWindowChrome: boolean;
|
|
20
|
+
overlayScrollbars: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export type UIAppearance = 'light' | 'dark' | 'system';
|
|
24
|
+
export type ResolvedUIAppearance = Exclude<UIAppearance, 'system'>;
|
|
25
|
+
export type ControlSize = 'mini' | 'small' | 'medium' | 'large' | 'xl';
|
|
26
|
+
export type LayoutDensity = 'compact' | 'regular' | 'comfortable';
|
|
27
|
+
export type MaterialThickness = 'ultra-thick' | 'thick' | 'medium' | 'thin' | 'ultra-thin';
|
|
28
|
+
export type MaterialContext = 'content' | 'over-glass';
|
|
29
|
+
export type ContrastPreference = 'system' | 'standard' | 'increased';
|
|
30
|
+
export type TransparencyPreference = 'system' | 'standard' | 'reduced';
|
|
31
|
+
export type MotionPreference = 'system' | 'standard' | 'reduced';
|
|
32
|
+
export interface UIPreferences {
|
|
33
|
+
contrast?: ContrastPreference;
|
|
34
|
+
transparency?: TransparencyPreference;
|
|
35
|
+
motion?: MotionPreference;
|
|
36
|
+
}
|
|
37
|
+
export declare const CONTROL_SIZES: readonly ["mini", "small", "medium", "large", "xl"];
|
|
38
|
+
export declare const MATERIAL_THICKNESSES: readonly ["ultra-thick", "thick", "medium", "thin", "ultra-thin"];
|
|
39
|
+
export declare const SIDEBAR_STYLES: {
|
|
40
|
+
readonly platform: {
|
|
41
|
+
readonly id: "platform";
|
|
42
|
+
readonly sourcePlatform: null;
|
|
43
|
+
readonly sourceVersion: null;
|
|
44
|
+
};
|
|
45
|
+
readonly floating: {
|
|
46
|
+
readonly id: "floating";
|
|
47
|
+
readonly sourcePlatform: "macos";
|
|
48
|
+
readonly sourceVersion: "26";
|
|
49
|
+
};
|
|
50
|
+
readonly 'edge-to-edge': {
|
|
51
|
+
readonly id: "edge-to-edge";
|
|
52
|
+
readonly sourcePlatform: "macos";
|
|
53
|
+
readonly sourceVersion: "27";
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export declare const PLATFORM_PACKS: {
|
|
57
|
+
readonly 'macos-27': {
|
|
58
|
+
readonly id: "macos-27";
|
|
59
|
+
readonly platform: "macos";
|
|
60
|
+
readonly version: "27";
|
|
61
|
+
readonly capabilities: {
|
|
62
|
+
readonly nativeMaterials: true;
|
|
63
|
+
readonly nativeWindowChrome: true;
|
|
64
|
+
readonly overlayScrollbars: true;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
readonly 'web-default': {
|
|
68
|
+
readonly id: "web-default";
|
|
69
|
+
readonly platform: "web";
|
|
70
|
+
readonly version: "default";
|
|
71
|
+
readonly capabilities: {
|
|
72
|
+
readonly nativeMaterials: false;
|
|
73
|
+
readonly nativeWindowChrome: false;
|
|
74
|
+
readonly overlayScrollbars: false;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export declare function resolvePlatformPack(platform: UIPlatform, version: UIPlatformVersion): UIPlatformPack;
|
|
79
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/tokens/contracts.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,UAAU,CAAA;AAE7C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,CAAA;AAEpD,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAEtC;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,cAAc,CAAA;AAErE,MAAM,MAAM,cAAc,GAAG,GAAG,UAAU,IAAI,MAAM,EAAE,CAAA;AAEtD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,cAAc,CAAA;IAClB,QAAQ,EAAE,UAAU,CAAA;IACpB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,YAAY,EAAE;QACZ,eAAe,EAAE,OAAO,CAAA;QACxB,kBAAkB,EAAE,OAAO,CAAA;QAC3B,iBAAiB,EAAE,OAAO,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEtD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;AAElE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;AAEtE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;AAEjE,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,OAAO,GACP,QAAQ,GACR,MAAM,GACN,YAAY,CAAA;AAEhB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,YAAY,CAAA;AAEtD,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAA;AAEpE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;AAEtE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,YAAY,CAAC,EAAE,sBAAsB,CAAA;IACrC,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAC1B;AAED,eAAO,MAAM,aAAa,qDAMiB,CAAA;AAE3C,eAAO,MAAM,oBAAoB,mEAMgB,CAAA;AAEjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;CAuB1B,CAAA;AAED,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;CAqBwB,CAAA;AAEnD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,iBAAiB,GACzB,cAAc,CAMhB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const CONTROL_SIZES = [
|
|
2
|
+
'mini',
|
|
3
|
+
'small',
|
|
4
|
+
'medium',
|
|
5
|
+
'large',
|
|
6
|
+
'xl',
|
|
7
|
+
];
|
|
8
|
+
export const MATERIAL_THICKNESSES = [
|
|
9
|
+
'ultra-thick',
|
|
10
|
+
'thick',
|
|
11
|
+
'medium',
|
|
12
|
+
'thin',
|
|
13
|
+
'ultra-thin',
|
|
14
|
+
];
|
|
15
|
+
export const SIDEBAR_STYLES = {
|
|
16
|
+
platform: {
|
|
17
|
+
id: 'platform',
|
|
18
|
+
sourcePlatform: null,
|
|
19
|
+
sourceVersion: null,
|
|
20
|
+
},
|
|
21
|
+
floating: {
|
|
22
|
+
id: 'floating',
|
|
23
|
+
sourcePlatform: 'macos',
|
|
24
|
+
sourceVersion: '26',
|
|
25
|
+
},
|
|
26
|
+
'edge-to-edge': {
|
|
27
|
+
id: 'edge-to-edge',
|
|
28
|
+
sourcePlatform: 'macos',
|
|
29
|
+
sourceVersion: '27',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export const PLATFORM_PACKS = {
|
|
33
|
+
'macos-27': {
|
|
34
|
+
id: 'macos-27',
|
|
35
|
+
platform: 'macos',
|
|
36
|
+
version: '27',
|
|
37
|
+
capabilities: {
|
|
38
|
+
nativeMaterials: true,
|
|
39
|
+
nativeWindowChrome: true,
|
|
40
|
+
overlayScrollbars: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
'web-default': {
|
|
44
|
+
id: 'web-default',
|
|
45
|
+
platform: 'web',
|
|
46
|
+
version: 'default',
|
|
47
|
+
capabilities: {
|
|
48
|
+
nativeMaterials: false,
|
|
49
|
+
nativeWindowChrome: false,
|
|
50
|
+
overlayScrollbars: false,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
export function resolvePlatformPack(platform, version) {
|
|
55
|
+
const exact = Object.values(PLATFORM_PACKS).find((pack) => pack.platform === platform && pack.version === version);
|
|
56
|
+
return exact ?? PLATFORM_PACKS['web-default'];
|
|
57
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { CONTROL_SIZES, MATERIAL_THICKNESSES, PLATFORM_PACKS, SIDEBAR_STYLES, resolvePlatformPack, type ContrastPreference, type ControlSize, type LayoutDensity, type MaterialContext, type MaterialThickness, type MotionPreference, type PlatformPackId, type ResolvedUIAppearance, type TransparencyPreference, type UIAppearance, type UIPlatform, type UIPlatformPack, type UIPlatformVersion, type UIPreferences, type UISidebarStyle, type UITheme, } from './contracts.js';
|
|
2
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,OAAO,GACb,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CONTROL_SIZES, MATERIAL_THICKNESSES, PLATFORM_PACKS, SIDEBAR_STYLES, resolvePlatformPack, } from './contracts.js';
|
package/docs/README.md
CHANGED
|
@@ -8,6 +8,8 @@ feels at home on macOS without imitating private platform implementation.
|
|
|
8
8
|
|
|
9
9
|
- [Foundations](./foundations.md)
|
|
10
10
|
- [Design tokens](./design-tokens.md)
|
|
11
|
+
- [Platform architecture](./platform-architecture.md)
|
|
12
|
+
- [macOS design audit](./macos-design-audit.md)
|
|
11
13
|
- [Adaptive materials](./adaptive-materials.md)
|
|
12
14
|
- [App anatomy](./app-anatomy.md)
|
|
13
15
|
- [Standalone app windows](./standalone-app-windows.md)
|
|
@@ -6,14 +6,15 @@ not replace content surfaces.
|
|
|
6
6
|
|
|
7
7
|
## Roles
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Choose `ultra-thick`, `thick`, `medium`, `thin`, or `ultra-thin` according to
|
|
10
|
+
the surface hierarchy. Medium material is the normal choice for window chrome,
|
|
11
|
+
grouped controls, menus, and temporary control overlays.
|
|
12
12
|
|
|
13
|
-
Use
|
|
13
|
+
Use ultra-thin material only for compact controls floating over photos, maps,
|
|
14
14
|
video, or another richly colored canvas. Check the control against the
|
|
15
15
|
lightest, darkest, and busiest content it can cover. If contrast is not stable,
|
|
16
|
-
use `regular
|
|
16
|
+
use medium. The `regular` and `clear` names remain compatibility aliases for
|
|
17
|
+
`medium` and `ultra-thin`, respectively.
|
|
17
18
|
|
|
18
19
|
Documents, calendars, tables, forms, cards, sheets, inspectors, and primary
|
|
19
20
|
working canvases remain opaque. Do not stack translucent content cards to
|
|
@@ -24,7 +25,7 @@ create hierarchy.
|
|
|
24
25
|
`Material` applies one adaptive surface:
|
|
25
26
|
|
|
26
27
|
```tsx
|
|
27
|
-
<Material asChild variant="
|
|
28
|
+
<Material asChild variant="ultra-thin" shape="circle" interactive>
|
|
28
29
|
<IconButton label="Center map" variant="ghost">
|
|
29
30
|
<Locate />
|
|
30
31
|
</IconButton>
|
|
@@ -34,7 +35,7 @@ create hierarchy.
|
|
|
34
35
|
`MaterialGroup` applies one sampled layer to a related cluster:
|
|
35
36
|
|
|
36
37
|
```tsx
|
|
37
|
-
<MaterialGroup variant="
|
|
38
|
+
<MaterialGroup variant="medium" shape="capsule" spacing="compact">
|
|
38
39
|
<IconButton label="Previous" variant="ghost">
|
|
39
40
|
<ChevronLeft />
|
|
40
41
|
</IconButton>
|
|
@@ -75,5 +76,9 @@ sampled layers and avoid nesting them.
|
|
|
75
76
|
CSS material samples content inside the app renderer. It cannot sample the
|
|
76
77
|
desktop behind a native window. Native behind-window material, window
|
|
77
78
|
transparency, active-window appearance, and energy policy remain host-owned
|
|
78
|
-
capabilities. Apps should use the same
|
|
79
|
-
adapter renders them.
|
|
79
|
+
capabilities. Apps should use the same thickness roles regardless of which
|
|
80
|
+
adapter renders them. Apps opt into native regions per window through
|
|
81
|
+
`moldable.json`; renderer-owned background and sidebar surfaces additionally
|
|
82
|
+
opt in through `AppFrame`. Full-window background material uses a frosted,
|
|
83
|
+
tinted host surface rather than uncovered transparency. Content that needs a
|
|
84
|
+
stable reading surface can remain opaque above it.
|
package/docs/design-tokens.md
CHANGED
|
@@ -114,8 +114,9 @@ disabled, and invalid states. Disabled wins over pointer states. Focus remains
|
|
|
114
114
|
visible when combined with selected or invalid. Selection is durable state;
|
|
115
115
|
hover is not a substitute for it.
|
|
116
116
|
|
|
117
|
-
Focus rings use the
|
|
118
|
-
plain `focus:` ring utilities or
|
|
117
|
+
Focus rings use the shared `--ring` token and the width defined by each
|
|
118
|
+
component recipe. Never use plain `focus:` ring utilities or invent a
|
|
119
|
+
component-local focus color.
|
|
119
120
|
|
|
120
121
|
Do not use state-layer colors as arbitrary fills. Prefer the shared component
|
|
121
122
|
when one exists.
|
|
@@ -141,11 +142,14 @@ stay theme-aware and do not inherit Moldable's legacy brand orange. Apps may
|
|
|
141
142
|
override the complete series palette at a theme boundary, but chart
|
|
142
143
|
components and stories should never embed raw series colors.
|
|
143
144
|
|
|
144
|
-
Adaptive material has
|
|
145
|
-
|
|
145
|
+
Adaptive material has five standard thickness variants: `ultra-thick`,
|
|
146
|
+
`thick`, `medium`, `thin`, and `ultra-thin`. Each includes fill, fallback,
|
|
147
|
+
border, highlight, blur, and saturation tokens. `regular` remains a
|
|
148
|
+
compatibility alias for `medium`, and `clear` remains a compatibility alias
|
|
149
|
+
for `ultra-thin`.
|
|
146
150
|
|
|
147
|
-
-
|
|
148
|
-
-
|
|
151
|
+
- Medium material supports normal toolbar and control chrome.
|
|
152
|
+
- Ultra-thin material supports compact controls over media or a richly
|
|
149
153
|
colored canvas.
|
|
150
154
|
- `shadow-panel`, `shadow-overlay`, `shadow-dialog`, and `shadow-window`
|
|
151
155
|
provide elevation independently from translucency.
|
package/docs/foundations.md
CHANGED
|
@@ -22,9 +22,9 @@ Status color communicates status only; it is not decoration.
|
|
|
22
22
|
- Preserve usable pointer targets even when the visible control is small.
|
|
23
23
|
- Prefer separators, background shifts, and whitespace over nested cards.
|
|
24
24
|
- Working panes own scrolling. The window shell should not accidentally scroll.
|
|
25
|
-
- Set `data-density="compact"
|
|
26
|
-
|
|
27
|
-
inventing per-screen heights.
|
|
25
|
+
- Set `data-density="compact"` or `"comfortable"` at a composition boundary;
|
|
26
|
+
omit it for regular/default density. Components should consume density
|
|
27
|
+
tokens rather than inventing per-screen heights.
|
|
28
28
|
|
|
29
29
|
## Surfaces
|
|
30
30
|
|