@castui/cast-ui 4.6.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/components/Accordion/Accordion.d.ts +80 -0
- package/dist/components/Accordion/Accordion.js +157 -0
- package/dist/components/Accordion/index.d.ts +1 -0
- package/dist/components/Accordion/index.js +6 -0
- package/dist/components/AppBar/AppBar.d.ts +47 -0
- package/dist/components/AppBar/AppBar.js +47 -0
- package/dist/components/AppBar/index.d.ts +1 -0
- package/dist/components/AppBar/index.js +5 -0
- package/dist/components/Autocomplete/Autocomplete.d.ts +70 -0
- package/dist/components/Autocomplete/Autocomplete.js +249 -0
- package/dist/components/Autocomplete/index.d.ts +1 -0
- package/dist/components/Autocomplete/index.js +5 -0
- package/dist/components/Backdrop/Backdrop.d.ts +32 -0
- package/dist/components/Backdrop/Backdrop.js +74 -0
- package/dist/components/Backdrop/index.d.ts +1 -0
- package/dist/components/Backdrop/index.js +5 -0
- package/dist/components/BottomSheet/BottomSheet.d.ts +50 -0
- package/dist/components/BottomSheet/BottomSheet.js +159 -0
- package/dist/components/BottomSheet/index.d.ts +1 -0
- package/dist/components/BottomSheet/index.js +6 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +63 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.js +143 -0
- package/dist/components/Breadcrumbs/index.d.ts +1 -0
- package/dist/components/Breadcrumbs/index.js +6 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +42 -0
- package/dist/components/CodeBlock/CodeBlock.js +110 -0
- package/dist/components/CodeBlock/index.d.ts +1 -0
- package/dist/components/CodeBlock/index.js +5 -0
- package/dist/components/Drawer/Drawer.d.ts +51 -0
- package/dist/components/Drawer/Drawer.js +168 -0
- package/dist/components/Drawer/index.d.ts +1 -0
- package/dist/components/Drawer/index.js +6 -0
- package/dist/components/Link/Link.d.ts +51 -0
- package/dist/components/Link/Link.js +73 -0
- package/dist/components/Link/index.d.ts +1 -0
- package/dist/components/Link/index.js +5 -0
- package/dist/components/Menu/Menu.d.ts +91 -0
- package/dist/components/Menu/Menu.js +211 -0
- package/dist/components/Menu/index.d.ts +1 -0
- package/dist/components/Menu/index.js +9 -0
- package/dist/components/Slider/Slider.d.ts +47 -0
- package/dist/components/Slider/Slider.js +132 -0
- package/dist/components/Slider/index.d.ts +1 -0
- package/dist/components/Slider/index.js +5 -0
- package/dist/components/SpeedDial/SpeedDial.d.ts +72 -0
- package/dist/components/SpeedDial/SpeedDial.js +189 -0
- package/dist/components/SpeedDial/index.d.ts +1 -0
- package/dist/components/SpeedDial/index.js +6 -0
- package/dist/components/Spinner/Spinner.d.ts +42 -0
- package/dist/components/Spinner/Spinner.js +77 -0
- package/dist/components/Spinner/index.d.ts +1 -0
- package/dist/components/Spinner/index.js +5 -0
- package/dist/components/Table/Table.d.ts +74 -0
- package/dist/components/Table/Table.js +176 -0
- package/dist/components/Table/index.d.ts +1 -0
- package/dist/components/Table/index.js +9 -0
- package/dist/components/Tabs/Tabs.d.ts +1 -1
- package/dist/components/Tabs/Tabs.js +5 -2
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +69 -0
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.js +158 -0
- package/dist/components/ToggleButtonGroup/index.d.ts +1 -0
- package/dist/components/ToggleButtonGroup/index.js +6 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +51 -2
- package/dist/theme/ThemeContext.d.ts +8 -1
- package/dist/theme/ThemeContext.js +7 -4
- package/dist/theme/applyCastTheme.d.ts +75 -0
- package/dist/theme/applyCastTheme.js +95 -0
- package/dist/theme/index.d.ts +2 -1
- package/dist/theme/index.js +3 -1
- package/dist/theme/themes.js +192 -0
- package/dist/theme/types.d.ts +192 -0
- package/dist/tokens/colors.d.ts +48 -0
- package/dist/tokens/colors.js +49 -1
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +4 -1
- package/package.json +2 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TableCell = exports.TableRow = exports.TableBody = exports.TableHead = exports.Table = void 0;
|
|
4
|
+
var Table_1 = require("./Table");
|
|
5
|
+
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return Table_1.Table; } });
|
|
6
|
+
Object.defineProperty(exports, "TableHead", { enumerable: true, get: function () { return Table_1.TableHead; } });
|
|
7
|
+
Object.defineProperty(exports, "TableBody", { enumerable: true, get: function () { return Table_1.TableBody; } });
|
|
8
|
+
Object.defineProperty(exports, "TableRow", { enumerable: true, get: function () { return Table_1.TableRow; } });
|
|
9
|
+
Object.defineProperty(exports, "TableCell", { enumerable: true, get: function () { return Table_1.TableCell; } });
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* `components.tabs`; `indicatorHeight` is keyed by `size` and constant across
|
|
27
27
|
* density (like Progress's track-height); `indicatorRadius` is the pill radius.
|
|
28
28
|
* Colours: the selected indicator and selected label bind to the intent system
|
|
29
|
-
* (`colors[intent].
|
|
29
|
+
* (`colors[intent].default.default.fg`); unselected labels use
|
|
30
30
|
* `scheme.text.description`, hovered use `scheme.text.primary`, disabled use
|
|
31
31
|
* `scheme.disabled.fg`; the baseline divider is the dedicated
|
|
32
32
|
* `scheme.tabs.track` semantic (cool-grey/200 light, cool-grey/700 dark).
|
|
@@ -31,7 +31,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
31
31
|
* `components.tabs`; `indicatorHeight` is keyed by `size` and constant across
|
|
32
32
|
* density (like Progress's track-height); `indicatorRadius` is the pill radius.
|
|
33
33
|
* Colours: the selected indicator and selected label bind to the intent system
|
|
34
|
-
* (`colors[intent].
|
|
34
|
+
* (`colors[intent].default.default.fg`); unselected labels use
|
|
35
35
|
* `scheme.text.description`, hovered use `scheme.text.primary`, disabled use
|
|
36
36
|
* `scheme.disabled.fg`; the baseline divider is the dedicated
|
|
37
37
|
* `scheme.tabs.track` semantic (cool-grey/200 light, cool-grey/700 dark).
|
|
@@ -69,7 +69,10 @@ function Tab({ value, children, leadingIcon, disabled = false, style, accessibil
|
|
|
69
69
|
const sizeTokens = components.tabs[size];
|
|
70
70
|
const { indicatorRadius } = components.tabs;
|
|
71
71
|
const isSelected = selectedValue === value;
|
|
72
|
-
|
|
72
|
+
// Selected label + indicator track the intent *fg* (text/line colour), mirroring
|
|
73
|
+
// the Figma binding intent/{intent}/default/default/fg — same hex as bold/bg in
|
|
74
|
+
// light, but correctly the text colour (not the solid fill) in dark mode.
|
|
75
|
+
const accent = colors[intent].default.default.fg;
|
|
73
76
|
// Resolve the label/icon colour from interaction + selection state.
|
|
74
77
|
const fg = disabled
|
|
75
78
|
? scheme.disabled.fg
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToggleButtonGroup — a segmented row of buttons for picking one or more values.
|
|
3
|
+
*
|
|
4
|
+
* Compound component. <ToggleButtonGroup> owns the selection and lays the
|
|
5
|
+
* buttons out joined in a row; <ToggleButton> is one segment.
|
|
6
|
+
*
|
|
7
|
+
* <ToggleButtonGroup value={align} onValueChange={setAlign}>
|
|
8
|
+
* <ToggleButton value="left" leadingIcon="format_align_left">Left</ToggleButton>
|
|
9
|
+
* <ToggleButton value="center" leadingIcon="format_align_center">Center</ToggleButton>
|
|
10
|
+
* <ToggleButton value="right" leadingIcon="format_align_right">Right</ToggleButton>
|
|
11
|
+
* </ToggleButtonGroup>
|
|
12
|
+
*
|
|
13
|
+
* Maps 1:1 to the Figma <Toggle Button Group> component:
|
|
14
|
+
* intent → neutral | brand | danger (selected fill)
|
|
15
|
+
* size → small | default | large (padding, gap, typography)
|
|
16
|
+
* exclusive → single-select (string | null) vs multi-select (string[])
|
|
17
|
+
* ToggleButton state → default | hover | selected | disabled
|
|
18
|
+
*
|
|
19
|
+
* A toggle button is its own component, not the Button set, so it has dedicated
|
|
20
|
+
* tokens (toggle-button-group/*). Selected segments fill with the intent bold
|
|
21
|
+
* colour; unselected segments are transparent with neutral text and a neutral
|
|
22
|
+
* hover. The group draws one neutral border with dividers between segments.
|
|
23
|
+
* Spacing varies by density; typography by the size prop. Fonts are
|
|
24
|
+
* consumer-loaded.
|
|
25
|
+
*/
|
|
26
|
+
import React from 'react';
|
|
27
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
28
|
+
import type { IntentName } from '../../tokens';
|
|
29
|
+
export type ToggleButtonGroupSize = 'small' | 'default' | 'large';
|
|
30
|
+
export type ToggleButtonGroupProps = {
|
|
31
|
+
/** Single-select (true, default) or multi-select (false). */
|
|
32
|
+
exclusive?: boolean;
|
|
33
|
+
/** Selected value (exclusive mode). null = nothing selected. */
|
|
34
|
+
value?: string | null;
|
|
35
|
+
/** Selection handler (exclusive mode). */
|
|
36
|
+
onValueChange?: (value: string | null) => void;
|
|
37
|
+
/** Selected values (multi mode). */
|
|
38
|
+
values?: string[];
|
|
39
|
+
/** Selection handler (multi mode). */
|
|
40
|
+
onValuesChange?: (values: string[]) => void;
|
|
41
|
+
/** Semantic intent — drives the selected fill colour. */
|
|
42
|
+
intent?: IntentName;
|
|
43
|
+
/** Size variant — padding, gap, and typography. */
|
|
44
|
+
size?: ToggleButtonGroupSize;
|
|
45
|
+
/** Disables every segment. */
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
/** `<ToggleButton>` children. */
|
|
48
|
+
children: React.ReactNode;
|
|
49
|
+
/** Outer style. */
|
|
50
|
+
style?: StyleProp<ViewStyle>;
|
|
51
|
+
/** Accessibility label for the group. */
|
|
52
|
+
accessibilityLabel?: string;
|
|
53
|
+
};
|
|
54
|
+
export type ToggleButtonProps = {
|
|
55
|
+
/** Unique value identifying this segment. */
|
|
56
|
+
value: string;
|
|
57
|
+
/** The segment label. */
|
|
58
|
+
children?: string;
|
|
59
|
+
/** Icon before the label — Material Symbols name string or a ReactNode. */
|
|
60
|
+
leadingIcon?: string | React.ReactNode;
|
|
61
|
+
/** Disables this segment. */
|
|
62
|
+
disabled?: boolean;
|
|
63
|
+
/** Accessibility label — falls back to the label text. */
|
|
64
|
+
accessibilityLabel?: string;
|
|
65
|
+
/** Internal: set by <ToggleButtonGroup> on the first segment. */
|
|
66
|
+
__first?: boolean;
|
|
67
|
+
};
|
|
68
|
+
export declare function ToggleButton({ value, children, leadingIcon, disabled, accessibilityLabel, __first, }: ToggleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
export declare function ToggleButtonGroup({ exclusive, value, onValueChange, values, onValuesChange, intent, size, disabled, children, style, accessibilityLabel, }: ToggleButtonGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ToggleButton = ToggleButton;
|
|
37
|
+
exports.ToggleButtonGroup = ToggleButtonGroup;
|
|
38
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
39
|
+
/**
|
|
40
|
+
* ToggleButtonGroup — a segmented row of buttons for picking one or more values.
|
|
41
|
+
*
|
|
42
|
+
* Compound component. <ToggleButtonGroup> owns the selection and lays the
|
|
43
|
+
* buttons out joined in a row; <ToggleButton> is one segment.
|
|
44
|
+
*
|
|
45
|
+
* <ToggleButtonGroup value={align} onValueChange={setAlign}>
|
|
46
|
+
* <ToggleButton value="left" leadingIcon="format_align_left">Left</ToggleButton>
|
|
47
|
+
* <ToggleButton value="center" leadingIcon="format_align_center">Center</ToggleButton>
|
|
48
|
+
* <ToggleButton value="right" leadingIcon="format_align_right">Right</ToggleButton>
|
|
49
|
+
* </ToggleButtonGroup>
|
|
50
|
+
*
|
|
51
|
+
* Maps 1:1 to the Figma <Toggle Button Group> component:
|
|
52
|
+
* intent → neutral | brand | danger (selected fill)
|
|
53
|
+
* size → small | default | large (padding, gap, typography)
|
|
54
|
+
* exclusive → single-select (string | null) vs multi-select (string[])
|
|
55
|
+
* ToggleButton state → default | hover | selected | disabled
|
|
56
|
+
*
|
|
57
|
+
* A toggle button is its own component, not the Button set, so it has dedicated
|
|
58
|
+
* tokens (toggle-button-group/*). Selected segments fill with the intent bold
|
|
59
|
+
* colour; unselected segments are transparent with neutral text and a neutral
|
|
60
|
+
* hover. The group draws one neutral border with dividers between segments.
|
|
61
|
+
* Spacing varies by density; typography by the size prop. Fonts are
|
|
62
|
+
* consumer-loaded.
|
|
63
|
+
*/
|
|
64
|
+
const react_1 = __importStar(require("react"));
|
|
65
|
+
const react_native_1 = require("react-native");
|
|
66
|
+
const theme_1 = require("../../theme");
|
|
67
|
+
const tokens_1 = require("../../tokens");
|
|
68
|
+
const Text_1 = require("../Text");
|
|
69
|
+
const Icon_1 = require("../Icon");
|
|
70
|
+
const ToggleButtonGroupCtx = (0, react_1.createContext)(null);
|
|
71
|
+
function useToggleButtonGroupContext() {
|
|
72
|
+
const ctx = (0, react_1.useContext)(ToggleButtonGroupCtx);
|
|
73
|
+
if (!ctx)
|
|
74
|
+
throw new Error('<ToggleButton> must be used within <ToggleButtonGroup>');
|
|
75
|
+
return ctx;
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Constants
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/** Maps size → label typography scale (Text component `type`). */
|
|
81
|
+
const LABEL_TYPE = {
|
|
82
|
+
small: 'label-sm',
|
|
83
|
+
default: 'label-md',
|
|
84
|
+
large: 'label-lg',
|
|
85
|
+
};
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// ToggleButton
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
function ToggleButton({ value, children, leadingIcon, disabled = false, accessibilityLabel, __first = false, }) {
|
|
90
|
+
const { intent, size, groupDisabled, isSelected, onItemPress } = useToggleButtonGroupContext();
|
|
91
|
+
const { components, colors, scheme } = (0, theme_1.useTheme)();
|
|
92
|
+
const sizeTokens = components.toggleButtonGroup[size];
|
|
93
|
+
const [isHovered, setIsHovered] = (0, react_1.useState)(false);
|
|
94
|
+
const isDisabled = disabled || groupDisabled;
|
|
95
|
+
const selected = isSelected(value);
|
|
96
|
+
// Selected segments fill with the intent bold colour; unselected are
|
|
97
|
+
// transparent with neutral text and a neutral hover.
|
|
98
|
+
const colorset = isDisabled
|
|
99
|
+
? { bg: scheme.disabled.bg, fg: scheme.disabled.fg }
|
|
100
|
+
: selected
|
|
101
|
+
? isHovered
|
|
102
|
+
? { bg: colors[intent].bold.hover.bg, fg: colors[intent].bold.hover.fg }
|
|
103
|
+
: { bg: colors[intent].bold.default.bg, fg: colors[intent].bold.default.fg }
|
|
104
|
+
: isHovered
|
|
105
|
+
? { bg: colors.neutral.subtle.hover.bg, fg: colors.neutral.subtle.hover.fg }
|
|
106
|
+
: { bg: 'transparent', fg: colors.neutral.default.default.fg };
|
|
107
|
+
const resolvedLeading = typeof leadingIcon === 'string' ? ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: leadingIcon, size: size, color: colorset.fg })) : (leadingIcon);
|
|
108
|
+
return ((0, jsx_runtime_1.jsxs)(react_native_1.Pressable, { onPress: () => {
|
|
109
|
+
if (!isDisabled)
|
|
110
|
+
onItemPress(value);
|
|
111
|
+
}, disabled: isDisabled, onHoverIn: () => setIsHovered(true), onHoverOut: () => setIsHovered(false), accessibilityRole: "button", accessibilityLabel: accessibilityLabel || children || value, accessibilityState: { selected, disabled: isDisabled }, style: {
|
|
112
|
+
flexDirection: 'row',
|
|
113
|
+
alignItems: 'center',
|
|
114
|
+
justifyContent: 'center',
|
|
115
|
+
gap: sizeTokens.gap,
|
|
116
|
+
paddingHorizontal: sizeTokens.paddingX,
|
|
117
|
+
paddingVertical: sizeTokens.paddingY,
|
|
118
|
+
backgroundColor: colorset.bg,
|
|
119
|
+
borderLeftWidth: __first ? 0 : tokens_1.controlTokens.borderWidth,
|
|
120
|
+
borderLeftColor: colors.neutral.default.default.border,
|
|
121
|
+
}, children: [resolvedLeading, children ? ((0, jsx_runtime_1.jsx)(Text_1.Text, { type: LABEL_TYPE[size], color: colorset.fg, selectable: false, children: children })) : null] }));
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// ToggleButtonGroup
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
function ToggleButtonGroup({ exclusive = true, value, onValueChange, values, onValuesChange, intent = 'brand', size = 'default', disabled = false, children, style, accessibilityLabel, }) {
|
|
127
|
+
const { components, colors } = (0, theme_1.useTheme)();
|
|
128
|
+
const radius = components.toggleButtonGroup.borderRadius;
|
|
129
|
+
const isSelected = (v) => exclusive ? value === v : (values ?? []).includes(v);
|
|
130
|
+
const onItemPress = (v) => {
|
|
131
|
+
if (exclusive) {
|
|
132
|
+
onValueChange?.(value === v ? null : v);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const current = values ?? [];
|
|
136
|
+
const next = current.includes(v)
|
|
137
|
+
? current.filter((x) => x !== v)
|
|
138
|
+
: [...current, v];
|
|
139
|
+
onValuesChange?.(next);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const items = react_1.default.Children.toArray(children).filter(Boolean);
|
|
143
|
+
const rendered = items.map((child, i) => react_1.default.cloneElement(child, {
|
|
144
|
+
key: `tb-${i}`,
|
|
145
|
+
__first: i === 0,
|
|
146
|
+
}));
|
|
147
|
+
return ((0, jsx_runtime_1.jsx)(ToggleButtonGroupCtx.Provider, { value: { intent, size, groupDisabled: disabled, isSelected, onItemPress }, children: (0, jsx_runtime_1.jsx)(react_native_1.View, { accessibilityRole: "radiogroup", accessibilityLabel: accessibilityLabel, style: [
|
|
148
|
+
{
|
|
149
|
+
flexDirection: 'row',
|
|
150
|
+
alignSelf: 'flex-start',
|
|
151
|
+
borderWidth: tokens_1.controlTokens.borderWidth,
|
|
152
|
+
borderColor: colors.neutral.default.default.border,
|
|
153
|
+
borderRadius: radius,
|
|
154
|
+
overflow: 'hidden',
|
|
155
|
+
},
|
|
156
|
+
style,
|
|
157
|
+
], children: rendered }) }));
|
|
158
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ToggleButtonGroup, ToggleButton, type ToggleButtonGroupProps, type ToggleButtonProps, type ToggleButtonGroupSize, } from './ToggleButtonGroup';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToggleButton = exports.ToggleButtonGroup = void 0;
|
|
4
|
+
var ToggleButtonGroup_1 = require("./ToggleButtonGroup");
|
|
5
|
+
Object.defineProperty(exports, "ToggleButtonGroup", { enumerable: true, get: function () { return ToggleButtonGroup_1.ToggleButtonGroup; } });
|
|
6
|
+
Object.defineProperty(exports, "ToggleButton", { enumerable: true, get: function () { return ToggleButtonGroup_1.ToggleButton; } });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, fontFamily, fontWeight, label, title, body, heading, display, caption, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, type LabelSize, iconSize, type IconSize, } from './tokens';
|
|
2
|
-
export { ThemeProvider, useTheme, themes, type Theme, type ThemeProviderProps, type DensityTheme, type ComponentTokens, type ButtonSizeTokens, type ButtonThemeTokens, type DialogSizeTokens, type DialogThemeTokens, type InputSizeTokens, type InputThemeTokens, type SelectContentTokens, type SelectOptionTokens, type SelectGroupTokens, type SelectSeparatorTokens, type SelectThemeTokens, type ListItemTokens, type ListSubheaderTokens, type ListThemeTokens, type CheckboxSizeTokens, type CheckboxThemeTokens, type AlertSizeTokens, type AlertThemeTokens, type ToggleSizeTokens, type ToggleThemeTokens, type CardSizeTokens, type CardThemeTokens, type BadgeSizeTokens, type BadgeThemeTokens, type RadioSizeTokens, type RadioThemeTokens, type ToastSizeTokens, type ToastThemeTokens, type ChipSizeTokens, type ChipThemeTokens, type AvatarSizeTokens, type AvatarThemeTokens, type PopoverSizeTokens, type PopoverThemeTokens, type TooltipSizeTokens, type TooltipThemeTokens, type ProgressSizeTokens, type ProgressThemeTokens, type TabsSizeTokens, type TabsThemeTokens, type DeepPartial, } from './theme';
|
|
1
|
+
export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, menuColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, sliderColors, tableColors, fontFamily, fontWeight, label, title, body, heading, display, caption, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, type LabelSize, iconSize, type IconSize, } from './tokens';
|
|
2
|
+
export { ThemeProvider, useTheme, themes, applyCastTheme, type Theme, type ThemeProviderProps, type CastThemeFile, type CastThemeProps, type DensityTheme, type ComponentTokens, type ButtonSizeTokens, type ButtonThemeTokens, type DialogSizeTokens, type DialogThemeTokens, type InputSizeTokens, type InputThemeTokens, type SelectContentTokens, type SelectOptionTokens, type SelectGroupTokens, type SelectSeparatorTokens, type SelectThemeTokens, type ListItemTokens, type ListSubheaderTokens, type ListThemeTokens, type CheckboxSizeTokens, type CheckboxThemeTokens, type AlertSizeTokens, type AlertThemeTokens, type ToggleSizeTokens, type ToggleThemeTokens, type CardSizeTokens, type CardThemeTokens, type BadgeSizeTokens, type BadgeThemeTokens, type RadioSizeTokens, type RadioThemeTokens, type ToastSizeTokens, type ToastThemeTokens, type ChipSizeTokens, type ChipThemeTokens, type AvatarSizeTokens, type AvatarThemeTokens, type PopoverSizeTokens, type PopoverThemeTokens, type TooltipSizeTokens, type TooltipThemeTokens, type ProgressSizeTokens, type ProgressThemeTokens, type TabsSizeTokens, type TabsThemeTokens, type SpinnerSizeTokens, type SpinnerThemeTokens, type BottomSheetThemeTokens, type LinkSizeTokens, type LinkThemeTokens, type BreadcrumbsSizeTokens, type BreadcrumbsThemeTokens, type CodeBlockSizeTokens, type CodeBlockThemeTokens, type DrawerThemeTokens, type MenuItemTokens, type MenuGroupTokens, type MenuThemeTokens, type ToggleButtonGroupSizeTokens, type ToggleButtonGroupThemeTokens, type AppBarSizeTokens, type AppBarThemeTokens, type SliderSizeTokens, type SliderThemeTokens, type SpeedDialSizeTokens, type SpeedDialThemeTokens, type TableSizeTokens, type TableThemeTokens, type DeepPartial, } from './theme';
|
|
3
3
|
export { Button, type ButtonProps, type ButtonSize } from './components/Button';
|
|
4
4
|
export { Icon, type IconProps } from './components/Icon';
|
|
5
5
|
export { Dialog, DialogContent, type DialogProps, type DialogContentProps, type DialogAction, type DialogSize, } from './components/Dialog';
|
|
@@ -21,4 +21,19 @@ export { Skeleton, type SkeletonProps, type SkeletonShape, } from './components/
|
|
|
21
21
|
export { Tooltip, type TooltipProps, type TooltipSize, type TooltipDirection, } from './components/Tooltip';
|
|
22
22
|
export { Text, type TextProps, type TextType } from './components/Text';
|
|
23
23
|
export { Progress, type ProgressProps, type ProgressSize } from './components/Progress';
|
|
24
|
+
export { Spinner, type SpinnerProps, type SpinnerSize } from './components/Spinner';
|
|
25
|
+
export { BottomSheet, BottomSheetContent, type BottomSheetProps, type BottomSheetContentProps, } from './components/BottomSheet';
|
|
24
26
|
export { Tabs, Tab, type TabsProps, type TabProps, type TabsSize, } from './components/Tabs';
|
|
27
|
+
export { Accordion, AccordionItem, type AccordionProps, type AccordionItemProps, type AccordionSize, type AccordionType, } from './components/Accordion';
|
|
28
|
+
export { Link, type LinkProps, type LinkSize, type LinkUnderline, } from './components/Link';
|
|
29
|
+
export { Backdrop, type BackdropProps } from './components/Backdrop';
|
|
30
|
+
export { Breadcrumbs, Breadcrumb, type BreadcrumbsProps, type BreadcrumbProps, type BreadcrumbsSize, } from './components/Breadcrumbs';
|
|
31
|
+
export { CodeBlock, type CodeBlockProps, type CodeBlockSize, } from './components/CodeBlock';
|
|
32
|
+
export { Drawer, DrawerContent, type DrawerProps, type DrawerContentProps, type DrawerAnchor, } from './components/Drawer';
|
|
33
|
+
export { Menu, MenuItem, MenuDivider, MenuLabel, MenuContent, type MenuProps, type MenuItemProps, type MenuLabelProps, type MenuContentProps, type MenuSize, type MenuPlacement, } from './components/Menu';
|
|
34
|
+
export { ToggleButtonGroup, ToggleButton, type ToggleButtonGroupProps, type ToggleButtonProps, type ToggleButtonGroupSize, } from './components/ToggleButtonGroup';
|
|
35
|
+
export { AppBar, type AppBarProps, type AppBarSize, type AppBarAlign, } from './components/AppBar';
|
|
36
|
+
export { Slider, type SliderProps, type SliderSize } from './components/Slider';
|
|
37
|
+
export { SpeedDial, SpeedDialAction, type SpeedDialProps, type SpeedDialActionProps, type SpeedDialSize, type SpeedDialDirection, } from './components/SpeedDial';
|
|
38
|
+
export { Table, TableHead, TableBody, TableRow, TableCell, type TableProps, type TableSectionProps, type TableRowProps, type TableCellProps, type TableSize, type TableCellAlign, } from './components/Table';
|
|
39
|
+
export { Autocomplete, type AutocompleteProps, type AutocompleteOption, type AutocompleteSize, } from './components/Autocomplete';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.Tab = exports.Tabs = exports.Progress = exports.Text = exports.Tooltip = exports.Skeleton = exports.Popover = exports.Avatar = exports.Divider = exports.Chip = exports.Toast = exports.RadioGroup = exports.Radio = exports.Input = exports.Badge = void 0;
|
|
3
|
+
exports.ListDivider = exports.ListSubheader = exports.ListItem = exports.List = exports.SelectDropdown = exports.SelectTag = exports.SelectSeparator = exports.SelectGroup = exports.SelectOption = exports.Select = exports.DialogContent = exports.Dialog = exports.Icon = exports.Button = exports.applyCastTheme = exports.themes = exports.useTheme = exports.ThemeProvider = exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.tableColors = exports.sliderColors = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.menuColors = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
|
|
4
|
+
exports.Autocomplete = exports.TableCell = exports.TableRow = exports.TableBody = exports.TableHead = exports.Table = exports.SpeedDialAction = exports.SpeedDial = exports.Slider = exports.AppBar = exports.ToggleButton = exports.ToggleButtonGroup = exports.MenuContent = exports.MenuLabel = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.DrawerContent = exports.Drawer = exports.CodeBlock = exports.Breadcrumb = exports.Breadcrumbs = exports.Backdrop = exports.Link = exports.AccordionItem = exports.Accordion = exports.Tab = exports.Tabs = exports.BottomSheetContent = exports.BottomSheet = exports.Spinner = exports.Progress = exports.Text = exports.Tooltip = exports.Skeleton = exports.Popover = exports.Avatar = exports.Divider = exports.Chip = exports.Toast = exports.RadioGroup = exports.Radio = exports.Input = exports.Badge = exports.Card = exports.Toggle = exports.Alert = exports.Checkbox = void 0;
|
|
5
5
|
// Cast UI — Cross-platform design system component library
|
|
6
6
|
//
|
|
7
7
|
// Tokens
|
|
@@ -16,6 +16,7 @@ Object.defineProperty(exports, "surfaceTokens", { enumerable: true, get: functio
|
|
|
16
16
|
Object.defineProperty(exports, "textTokens", { enumerable: true, get: function () { return tokens_1.textTokens; } });
|
|
17
17
|
Object.defineProperty(exports, "overlayTokens", { enumerable: true, get: function () { return tokens_1.overlayTokens; } });
|
|
18
18
|
Object.defineProperty(exports, "selectColors", { enumerable: true, get: function () { return tokens_1.selectColors; } });
|
|
19
|
+
Object.defineProperty(exports, "menuColors", { enumerable: true, get: function () { return tokens_1.menuColors; } });
|
|
19
20
|
Object.defineProperty(exports, "tagTokens", { enumerable: true, get: function () { return tokens_1.tagTokens; } });
|
|
20
21
|
Object.defineProperty(exports, "errorTokens", { enumerable: true, get: function () { return tokens_1.errorTokens; } });
|
|
21
22
|
Object.defineProperty(exports, "listColors", { enumerable: true, get: function () { return tokens_1.listColors; } });
|
|
@@ -26,6 +27,8 @@ Object.defineProperty(exports, "tabsColors", { enumerable: true, get: function (
|
|
|
26
27
|
Object.defineProperty(exports, "radioColors", { enumerable: true, get: function () { return tokens_1.radioColors; } });
|
|
27
28
|
Object.defineProperty(exports, "avatarColors", { enumerable: true, get: function () { return tokens_1.avatarColors; } });
|
|
28
29
|
Object.defineProperty(exports, "skeletonColors", { enumerable: true, get: function () { return tokens_1.skeletonColors; } });
|
|
30
|
+
Object.defineProperty(exports, "sliderColors", { enumerable: true, get: function () { return tokens_1.sliderColors; } });
|
|
31
|
+
Object.defineProperty(exports, "tableColors", { enumerable: true, get: function () { return tokens_1.tableColors; } });
|
|
29
32
|
Object.defineProperty(exports, "fontFamily", { enumerable: true, get: function () { return tokens_1.fontFamily; } });
|
|
30
33
|
Object.defineProperty(exports, "fontWeight", { enumerable: true, get: function () { return tokens_1.fontWeight; } });
|
|
31
34
|
Object.defineProperty(exports, "label", { enumerable: true, get: function () { return tokens_1.label; } });
|
|
@@ -40,6 +43,7 @@ var theme_1 = require("./theme");
|
|
|
40
43
|
Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return theme_1.ThemeProvider; } });
|
|
41
44
|
Object.defineProperty(exports, "useTheme", { enumerable: true, get: function () { return theme_1.useTheme; } });
|
|
42
45
|
Object.defineProperty(exports, "themes", { enumerable: true, get: function () { return theme_1.themes; } });
|
|
46
|
+
Object.defineProperty(exports, "applyCastTheme", { enumerable: true, get: function () { return theme_1.applyCastTheme; } });
|
|
43
47
|
// Components
|
|
44
48
|
var Button_1 = require("./components/Button");
|
|
45
49
|
Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return Button_1.Button; } });
|
|
@@ -93,6 +97,51 @@ var Text_1 = require("./components/Text");
|
|
|
93
97
|
Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return Text_1.Text; } });
|
|
94
98
|
var Progress_1 = require("./components/Progress");
|
|
95
99
|
Object.defineProperty(exports, "Progress", { enumerable: true, get: function () { return Progress_1.Progress; } });
|
|
100
|
+
var Spinner_1 = require("./components/Spinner");
|
|
101
|
+
Object.defineProperty(exports, "Spinner", { enumerable: true, get: function () { return Spinner_1.Spinner; } });
|
|
102
|
+
var BottomSheet_1 = require("./components/BottomSheet");
|
|
103
|
+
Object.defineProperty(exports, "BottomSheet", { enumerable: true, get: function () { return BottomSheet_1.BottomSheet; } });
|
|
104
|
+
Object.defineProperty(exports, "BottomSheetContent", { enumerable: true, get: function () { return BottomSheet_1.BottomSheetContent; } });
|
|
96
105
|
var Tabs_1 = require("./components/Tabs");
|
|
97
106
|
Object.defineProperty(exports, "Tabs", { enumerable: true, get: function () { return Tabs_1.Tabs; } });
|
|
98
107
|
Object.defineProperty(exports, "Tab", { enumerable: true, get: function () { return Tabs_1.Tab; } });
|
|
108
|
+
var Accordion_1 = require("./components/Accordion");
|
|
109
|
+
Object.defineProperty(exports, "Accordion", { enumerable: true, get: function () { return Accordion_1.Accordion; } });
|
|
110
|
+
Object.defineProperty(exports, "AccordionItem", { enumerable: true, get: function () { return Accordion_1.AccordionItem; } });
|
|
111
|
+
// --- Batch: MUI-aligned components ---
|
|
112
|
+
var Link_1 = require("./components/Link");
|
|
113
|
+
Object.defineProperty(exports, "Link", { enumerable: true, get: function () { return Link_1.Link; } });
|
|
114
|
+
var Backdrop_1 = require("./components/Backdrop");
|
|
115
|
+
Object.defineProperty(exports, "Backdrop", { enumerable: true, get: function () { return Backdrop_1.Backdrop; } });
|
|
116
|
+
var Breadcrumbs_1 = require("./components/Breadcrumbs");
|
|
117
|
+
Object.defineProperty(exports, "Breadcrumbs", { enumerable: true, get: function () { return Breadcrumbs_1.Breadcrumbs; } });
|
|
118
|
+
Object.defineProperty(exports, "Breadcrumb", { enumerable: true, get: function () { return Breadcrumbs_1.Breadcrumb; } });
|
|
119
|
+
var CodeBlock_1 = require("./components/CodeBlock");
|
|
120
|
+
Object.defineProperty(exports, "CodeBlock", { enumerable: true, get: function () { return CodeBlock_1.CodeBlock; } });
|
|
121
|
+
var Drawer_1 = require("./components/Drawer");
|
|
122
|
+
Object.defineProperty(exports, "Drawer", { enumerable: true, get: function () { return Drawer_1.Drawer; } });
|
|
123
|
+
Object.defineProperty(exports, "DrawerContent", { enumerable: true, get: function () { return Drawer_1.DrawerContent; } });
|
|
124
|
+
var Menu_1 = require("./components/Menu");
|
|
125
|
+
Object.defineProperty(exports, "Menu", { enumerable: true, get: function () { return Menu_1.Menu; } });
|
|
126
|
+
Object.defineProperty(exports, "MenuItem", { enumerable: true, get: function () { return Menu_1.MenuItem; } });
|
|
127
|
+
Object.defineProperty(exports, "MenuDivider", { enumerable: true, get: function () { return Menu_1.MenuDivider; } });
|
|
128
|
+
Object.defineProperty(exports, "MenuLabel", { enumerable: true, get: function () { return Menu_1.MenuLabel; } });
|
|
129
|
+
Object.defineProperty(exports, "MenuContent", { enumerable: true, get: function () { return Menu_1.MenuContent; } });
|
|
130
|
+
var ToggleButtonGroup_1 = require("./components/ToggleButtonGroup");
|
|
131
|
+
Object.defineProperty(exports, "ToggleButtonGroup", { enumerable: true, get: function () { return ToggleButtonGroup_1.ToggleButtonGroup; } });
|
|
132
|
+
Object.defineProperty(exports, "ToggleButton", { enumerable: true, get: function () { return ToggleButtonGroup_1.ToggleButton; } });
|
|
133
|
+
var AppBar_1 = require("./components/AppBar");
|
|
134
|
+
Object.defineProperty(exports, "AppBar", { enumerable: true, get: function () { return AppBar_1.AppBar; } });
|
|
135
|
+
var Slider_1 = require("./components/Slider");
|
|
136
|
+
Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return Slider_1.Slider; } });
|
|
137
|
+
var SpeedDial_1 = require("./components/SpeedDial");
|
|
138
|
+
Object.defineProperty(exports, "SpeedDial", { enumerable: true, get: function () { return SpeedDial_1.SpeedDial; } });
|
|
139
|
+
Object.defineProperty(exports, "SpeedDialAction", { enumerable: true, get: function () { return SpeedDial_1.SpeedDialAction; } });
|
|
140
|
+
var Table_1 = require("./components/Table");
|
|
141
|
+
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return Table_1.Table; } });
|
|
142
|
+
Object.defineProperty(exports, "TableHead", { enumerable: true, get: function () { return Table_1.TableHead; } });
|
|
143
|
+
Object.defineProperty(exports, "TableBody", { enumerable: true, get: function () { return Table_1.TableBody; } });
|
|
144
|
+
Object.defineProperty(exports, "TableRow", { enumerable: true, get: function () { return Table_1.TableRow; } });
|
|
145
|
+
Object.defineProperty(exports, "TableCell", { enumerable: true, get: function () { return Table_1.TableCell; } });
|
|
146
|
+
var Autocomplete_1 = require("./components/Autocomplete");
|
|
147
|
+
Object.defineProperty(exports, "Autocomplete", { enumerable: true, get: function () { return Autocomplete_1.Autocomplete; } });
|
|
@@ -64,9 +64,16 @@ export type ThemeProviderProps = {
|
|
|
64
64
|
* stays default.
|
|
65
65
|
*/
|
|
66
66
|
colors?: Partial<Record<IntentName, DeepPartial<IntentColorMap[IntentName]>>>;
|
|
67
|
+
/**
|
|
68
|
+
* Partial overrides for the rest of the colour scheme — surface, text,
|
|
69
|
+
* focusRing, overlay, etc. Deep-merged into the active scheme after `colors`.
|
|
70
|
+
* Forward-compatible: pass whatever sections a cast-theme file provides.
|
|
71
|
+
* Usually you don't set this by hand — `applyCastTheme` builds it for you.
|
|
72
|
+
*/
|
|
73
|
+
scheme?: DeepPartial<ColorScheme>;
|
|
67
74
|
children: React.ReactNode;
|
|
68
75
|
};
|
|
69
|
-
export declare function ThemeProvider({ density, colorMode, colors, children, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
76
|
+
export declare function ThemeProvider({ density, colorMode, colors, scheme: schemeOverride, children, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
70
77
|
/**
|
|
71
78
|
* Access the current theme — density tokens, intent colours, and component tokens.
|
|
72
79
|
* Must be called within a ThemeProvider; falls back to the "default" density if not.
|
|
@@ -79,24 +79,27 @@ const defaultTheme = {
|
|
|
79
79
|
disabledColors: colors_1.colorSchemes.light.disabled,
|
|
80
80
|
};
|
|
81
81
|
const ThemeContext = (0, react_1.createContext)(defaultTheme);
|
|
82
|
-
function ThemeProvider({ density = 'default', colorMode = 'light', colors, children, }) {
|
|
82
|
+
function ThemeProvider({ density = 'default', colorMode = 'light', colors, scheme: schemeOverride, children, }) {
|
|
83
83
|
const theme = (0, react_1.useMemo)(() => {
|
|
84
84
|
const baseScheme = colors_1.colorSchemes[colorMode];
|
|
85
85
|
const resolvedIntents = colors
|
|
86
86
|
? deepMerge(baseScheme.intents, colors)
|
|
87
87
|
: baseScheme.intents;
|
|
88
|
-
|
|
88
|
+
let scheme = colors || schemeOverride
|
|
89
89
|
? { ...baseScheme, intents: resolvedIntents }
|
|
90
90
|
: baseScheme;
|
|
91
|
+
if (schemeOverride) {
|
|
92
|
+
scheme = deepMerge(scheme, schemeOverride);
|
|
93
|
+
}
|
|
91
94
|
return {
|
|
92
95
|
density,
|
|
93
96
|
components: themes_1.themes[density],
|
|
94
97
|
colorMode,
|
|
95
98
|
scheme,
|
|
96
|
-
colors:
|
|
99
|
+
colors: scheme.intents,
|
|
97
100
|
disabledColors: scheme.disabled,
|
|
98
101
|
};
|
|
99
|
-
}, [density, colorMode, colors]);
|
|
102
|
+
}, [density, colorMode, colors, schemeOverride]);
|
|
100
103
|
return ((0, jsx_runtime_1.jsx)(ThemeContext.Provider, { value: theme, children: children }));
|
|
101
104
|
}
|
|
102
105
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* applyCastTheme — turn a cast-sync `cast-theme.json` object into props for
|
|
3
|
+
* `ThemeProvider`.
|
|
4
|
+
*
|
|
5
|
+
* The cast-sync Figma plugin exports a theme file with the colour intents
|
|
6
|
+
* keyed by mode (`colors.light` / `colors.dark`) plus reference sections
|
|
7
|
+
* (`text`, `typography`, `shadows`). This helper does the wiring the consumer
|
|
8
|
+
* used to do by hand:
|
|
9
|
+
*
|
|
10
|
+
* - **Mode pairing.** You pass the whole theme plus the mode you're
|
|
11
|
+
* rendering; it pulls the matching intent block. No more pairing
|
|
12
|
+
* `colors.light` with `colorMode="light"` yourself and risking a desync.
|
|
13
|
+
* - **Scheme overrides.** The non-intent colour sections the file carries
|
|
14
|
+
* (`text`, `surface`, `focusRing`) are mapped into the `scheme` override
|
|
15
|
+
* prop, so they actually land instead of sitting inert. Forward-compatible:
|
|
16
|
+
* new sections flow through here with no change at the call site.
|
|
17
|
+
*
|
|
18
|
+
* The plugin stays a pure exporter — all interpretation lives here, in one
|
|
19
|
+
* tested place, so old theme files keep working as cast-ui evolves.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* import theme from './cast-theme.json';
|
|
24
|
+
* import { ThemeProvider, applyCastTheme } from '@castui/cast-ui';
|
|
25
|
+
*
|
|
26
|
+
* const [mode, setMode] = useState<'light' | 'dark'>('light');
|
|
27
|
+
*
|
|
28
|
+
* <ThemeProvider {...applyCastTheme(theme, mode)}>
|
|
29
|
+
* <App />
|
|
30
|
+
* </ThemeProvider>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import type { ThemeProviderProps } from './ThemeContext';
|
|
34
|
+
import type { ColorMode, IntentName } from '../tokens/colors';
|
|
35
|
+
/** intent → prominence → state → { bg, fg, border } */
|
|
36
|
+
type FileIntentMap = Partial<Record<IntentName, Record<string, Record<string, Record<string, string>>>>>;
|
|
37
|
+
/**
|
|
38
|
+
* The shape of a cast-sync `cast-theme.json`. Every section is optional so a
|
|
39
|
+
* partial or future-versioned file never throws — unknown keys are ignored.
|
|
40
|
+
*/
|
|
41
|
+
export type CastThemeFile = {
|
|
42
|
+
name?: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
generatedAt?: string;
|
|
45
|
+
/** Theme-file format version emitted by the plugin (currently 3). */
|
|
46
|
+
version?: number;
|
|
47
|
+
/** Optional explicit schema version for consumer validation. */
|
|
48
|
+
schemaVersion?: number;
|
|
49
|
+
colors?: Partial<Record<ColorMode, FileIntentMap>>;
|
|
50
|
+
text?: Partial<Record<ColorMode, Record<string, string>>>;
|
|
51
|
+
surface?: Partial<Record<ColorMode, {
|
|
52
|
+
base?: string;
|
|
53
|
+
subtle?: string;
|
|
54
|
+
overlay?: {
|
|
55
|
+
bg?: string;
|
|
56
|
+
border?: string;
|
|
57
|
+
};
|
|
58
|
+
}>>;
|
|
59
|
+
focusRing?: Partial<Record<ColorMode, {
|
|
60
|
+
color?: string;
|
|
61
|
+
}>>;
|
|
62
|
+
typography?: Record<string, unknown>;
|
|
63
|
+
shadows?: Record<string, unknown>;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
};
|
|
66
|
+
/** The subset of ThemeProvider props this helper produces. */
|
|
67
|
+
export type CastThemeProps = Pick<ThemeProviderProps, 'colorMode' | 'colors' | 'scheme'>;
|
|
68
|
+
/**
|
|
69
|
+
* Build ThemeProvider props from a cast-theme file for a given colour mode.
|
|
70
|
+
*
|
|
71
|
+
* @param theme The parsed `cast-theme.json` object.
|
|
72
|
+
* @param mode The colour mode to render — defaults to `'light'`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function applyCastTheme(theme: CastThemeFile, mode?: ColorMode): CastThemeProps;
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* applyCastTheme — turn a cast-sync `cast-theme.json` object into props for
|
|
4
|
+
* `ThemeProvider`.
|
|
5
|
+
*
|
|
6
|
+
* The cast-sync Figma plugin exports a theme file with the colour intents
|
|
7
|
+
* keyed by mode (`colors.light` / `colors.dark`) plus reference sections
|
|
8
|
+
* (`text`, `typography`, `shadows`). This helper does the wiring the consumer
|
|
9
|
+
* used to do by hand:
|
|
10
|
+
*
|
|
11
|
+
* - **Mode pairing.** You pass the whole theme plus the mode you're
|
|
12
|
+
* rendering; it pulls the matching intent block. No more pairing
|
|
13
|
+
* `colors.light` with `colorMode="light"` yourself and risking a desync.
|
|
14
|
+
* - **Scheme overrides.** The non-intent colour sections the file carries
|
|
15
|
+
* (`text`, `surface`, `focusRing`) are mapped into the `scheme` override
|
|
16
|
+
* prop, so they actually land instead of sitting inert. Forward-compatible:
|
|
17
|
+
* new sections flow through here with no change at the call site.
|
|
18
|
+
*
|
|
19
|
+
* The plugin stays a pure exporter — all interpretation lives here, in one
|
|
20
|
+
* tested place, so old theme files keep working as cast-ui evolves.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* import theme from './cast-theme.json';
|
|
25
|
+
* import { ThemeProvider, applyCastTheme } from '@castui/cast-ui';
|
|
26
|
+
*
|
|
27
|
+
* const [mode, setMode] = useState<'light' | 'dark'>('light');
|
|
28
|
+
*
|
|
29
|
+
* <ThemeProvider {...applyCastTheme(theme, mode)}>
|
|
30
|
+
* <App />
|
|
31
|
+
* </ThemeProvider>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.applyCastTheme = applyCastTheme;
|
|
36
|
+
/** Map the file's `text` block onto the scheme's `text` slots (matching keys only). */
|
|
37
|
+
function mapText(fileText) {
|
|
38
|
+
if (!fileText)
|
|
39
|
+
return undefined;
|
|
40
|
+
const out = {};
|
|
41
|
+
// Only keys the runtime scheme actually has. `muted` has no scheme slot, so
|
|
42
|
+
// it's intentionally dropped rather than guessed.
|
|
43
|
+
if (typeof fileText.primary === 'string')
|
|
44
|
+
out.primary = fileText.primary;
|
|
45
|
+
if (typeof fileText.description === 'string')
|
|
46
|
+
out.description = fileText.description;
|
|
47
|
+
if (typeof fileText.placeholder === 'string')
|
|
48
|
+
out.placeholder = fileText.placeholder;
|
|
49
|
+
// `muted` has no runtime scheme slot, so it is intentionally dropped.
|
|
50
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
51
|
+
}
|
|
52
|
+
/** Map the file's `surface` block onto the scheme's surface colours. */
|
|
53
|
+
function mapSurface(fileSurface) {
|
|
54
|
+
if (!fileSurface)
|
|
55
|
+
return undefined;
|
|
56
|
+
const out = {};
|
|
57
|
+
if (typeof fileSurface.base === 'string')
|
|
58
|
+
out.base = fileSurface.base;
|
|
59
|
+
if (typeof fileSurface.subtle === 'string')
|
|
60
|
+
out.subtle = fileSurface.subtle;
|
|
61
|
+
if (fileSurface.overlay) {
|
|
62
|
+
const overlay = {};
|
|
63
|
+
if (typeof fileSurface.overlay.bg === 'string')
|
|
64
|
+
overlay.bg = fileSurface.overlay.bg;
|
|
65
|
+
if (typeof fileSurface.overlay.border === 'string')
|
|
66
|
+
overlay.border = fileSurface.overlay.border;
|
|
67
|
+
if (Object.keys(overlay).length > 0)
|
|
68
|
+
out.overlay = overlay;
|
|
69
|
+
}
|
|
70
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Build ThemeProvider props from a cast-theme file for a given colour mode.
|
|
74
|
+
*
|
|
75
|
+
* @param theme The parsed `cast-theme.json` object.
|
|
76
|
+
* @param mode The colour mode to render — defaults to `'light'`.
|
|
77
|
+
*/
|
|
78
|
+
function applyCastTheme(theme, mode = 'light') {
|
|
79
|
+
const intents = theme?.colors?.[mode];
|
|
80
|
+
const schemeOverride = {};
|
|
81
|
+
const text = mapText(theme?.text?.[mode]);
|
|
82
|
+
if (text)
|
|
83
|
+
schemeOverride.text = text;
|
|
84
|
+
const surface = mapSurface(theme?.surface?.[mode]);
|
|
85
|
+
if (surface)
|
|
86
|
+
schemeOverride.surface = surface;
|
|
87
|
+
const ring = theme?.focusRing?.[mode];
|
|
88
|
+
if (ring && typeof ring.color === 'string')
|
|
89
|
+
schemeOverride.focusRing = { color: ring.color };
|
|
90
|
+
return {
|
|
91
|
+
colorMode: mode,
|
|
92
|
+
colors: intents,
|
|
93
|
+
scheme: Object.keys(schemeOverride).length > 0 ? schemeOverride : undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|