@castui/cast-ui 4.4.0 → 4.6.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 CHANGED
@@ -209,7 +209,6 @@ npm run build # compile to dist/
209
209
  | Workflow | Trigger | Purpose |
210
210
  |----------|---------|---------|
211
211
  | Chromatic | Every push | Visual regression testing via Storybook snapshots |
212
- | Adoption Tracking | Push to `main` | Registers package version with Zeroheight |
213
212
  | Publish to npm | Push to `main` | Builds and publishes to npm (only when the version changes) |
214
213
 
215
214
  ## License
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Progress — linear progress indicator (determinate + indeterminate).
3
+ *
4
+ * Maps 1:1 to the Figma <Progress> component:
5
+ * intent → neutral | brand | danger (fill colour)
6
+ * size → small | default | large (track thickness)
7
+ * value → 0–100 (determinate fill; omit for indeterminate)
8
+ *
9
+ * The track thickness is the one genuinely new token this component introduces
10
+ * (`progress/{size}/track-height`): it is keyed by the `size` prop and is
11
+ * constant across the three densities — like Badge's dot-size or Toggle's
12
+ * track. The pill radius is constant. Progress therefore reads no
13
+ * density-varying spacing.
14
+ *
15
+ * Colours: the fill binds to the intent system
16
+ * (`colors[intent].bold.default.bg`) so it tracks the host intent and any
17
+ * ThemeProvider colour overrides; the track background is the dedicated
18
+ * `control/progress/track/bg` semantic (cool-grey/200 light, cool-grey/700
19
+ * dark, matching the Toggle off-track), so it follows light/dark colour mode.
20
+ *
21
+ * When `value` is omitted (or null) the bar renders an indeterminate sweep.
22
+ */
23
+ import { type StyleProp, type ViewStyle } from 'react-native';
24
+ import type { IntentName } from '../../tokens';
25
+ export type ProgressSize = 'small' | 'default' | 'large';
26
+ export type ProgressProps = {
27
+ /**
28
+ * Completion percentage (0–100). Omit (or pass null) for an indeterminate
29
+ * animated sweep.
30
+ */
31
+ value?: number | null;
32
+ /** Semantic intent — drives the fill colour. */
33
+ intent?: IntentName;
34
+ /** Size variant — controls track thickness. */
35
+ size?: ProgressSize;
36
+ /** Outer style — use for positioning (margin, width, alignSelf). */
37
+ style?: StyleProp<ViewStyle>;
38
+ /** Accessibility label — describes what is loading. */
39
+ accessibilityLabel?: string;
40
+ };
41
+ export declare function Progress({ value, intent, size, style, accessibilityLabel, }: ProgressProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Progress = Progress;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ /**
6
+ * Progress — linear progress indicator (determinate + indeterminate).
7
+ *
8
+ * Maps 1:1 to the Figma <Progress> component:
9
+ * intent → neutral | brand | danger (fill colour)
10
+ * size → small | default | large (track thickness)
11
+ * value → 0–100 (determinate fill; omit for indeterminate)
12
+ *
13
+ * The track thickness is the one genuinely new token this component introduces
14
+ * (`progress/{size}/track-height`): it is keyed by the `size` prop and is
15
+ * constant across the three densities — like Badge's dot-size or Toggle's
16
+ * track. The pill radius is constant. Progress therefore reads no
17
+ * density-varying spacing.
18
+ *
19
+ * Colours: the fill binds to the intent system
20
+ * (`colors[intent].bold.default.bg`) so it tracks the host intent and any
21
+ * ThemeProvider colour overrides; the track background is the dedicated
22
+ * `control/progress/track/bg` semantic (cool-grey/200 light, cool-grey/700
23
+ * dark, matching the Toggle off-track), so it follows light/dark colour mode.
24
+ *
25
+ * When `value` is omitted (or null) the bar renders an indeterminate sweep.
26
+ */
27
+ const react_1 = require("react");
28
+ const react_native_1 = require("react-native");
29
+ const theme_1 = require("../../theme");
30
+ // ---------------------------------------------------------------------------
31
+ // Constants
32
+ // ---------------------------------------------------------------------------
33
+ /** Fraction of the track the indeterminate sweep bar occupies. */
34
+ const INDETERMINATE_BAR_FRACTION = 0.4;
35
+ const clamp = (n) => Math.max(0, Math.min(100, n));
36
+ // ---------------------------------------------------------------------------
37
+ // Component
38
+ // ---------------------------------------------------------------------------
39
+ function Progress({ value, intent = 'brand', size = 'default', style, accessibilityLabel = 'Loading', }) {
40
+ const { components, colors, scheme } = (0, theme_1.useTheme)();
41
+ const { trackHeight } = components.progress[size];
42
+ const borderRadius = components.progress.borderRadius;
43
+ const fill = colors[intent].bold.default.bg;
44
+ const trackBg = scheme.progress.track;
45
+ const isIndeterminate = value === undefined || value === null;
46
+ const pct = isIndeterminate ? 0 : clamp(value);
47
+ // Track width is needed to drive the indeterminate translateX in px
48
+ // (useNativeDriver can't animate a percentage width).
49
+ const [trackWidth, setTrackWidth] = (0, react_1.useState)(0);
50
+ const onLayout = (e) => setTrackWidth(e.nativeEvent.layout.width);
51
+ const slide = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
52
+ (0, react_1.useEffect)(() => {
53
+ if (!isIndeterminate || trackWidth === 0)
54
+ return;
55
+ slide.setValue(0);
56
+ const loop = react_native_1.Animated.loop(react_native_1.Animated.timing(slide, {
57
+ toValue: 1,
58
+ duration: 1200,
59
+ easing: react_native_1.Easing.inOut(react_native_1.Easing.ease),
60
+ useNativeDriver: true,
61
+ }));
62
+ loop.start();
63
+ return () => loop.stop();
64
+ }, [isIndeterminate, trackWidth, slide]);
65
+ const barWidth = trackWidth * INDETERMINATE_BAR_FRACTION;
66
+ const translateX = slide.interpolate({
67
+ inputRange: [0, 1],
68
+ outputRange: [-barWidth, trackWidth],
69
+ });
70
+ return ((0, jsx_runtime_1.jsx)(react_native_1.View, { onLayout: onLayout, accessibilityRole: "progressbar", accessibilityLabel: accessibilityLabel, accessibilityValue: isIndeterminate ? undefined : { min: 0, max: 100, now: Math.round(pct) }, accessibilityState: isIndeterminate ? { busy: true } : undefined, style: [
71
+ {
72
+ width: '100%',
73
+ height: trackHeight,
74
+ borderRadius,
75
+ backgroundColor: trackBg,
76
+ overflow: 'hidden',
77
+ },
78
+ style,
79
+ ], children: isIndeterminate ? ((0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { style: {
80
+ position: 'absolute',
81
+ top: 0,
82
+ bottom: 0,
83
+ width: barWidth,
84
+ borderRadius,
85
+ backgroundColor: fill,
86
+ transform: [{ translateX }],
87
+ } })) : ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: {
88
+ width: `${pct}%`,
89
+ height: '100%',
90
+ borderRadius,
91
+ backgroundColor: fill,
92
+ } })) }));
93
+ }
@@ -0,0 +1 @@
1
+ export { Progress, type ProgressProps, type ProgressSize } from './Progress';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Progress = void 0;
4
+ var Progress_1 = require("./Progress");
5
+ Object.defineProperty(exports, "Progress", { enumerable: true, get: function () { return Progress_1.Progress; } });
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Tabs — a horizontal, underline-style tab bar for switching between views.
3
+ *
4
+ * Compound component. `<Tabs>` is the container that owns the selected `value`
5
+ * and `onValueChange`; `<Tab>` is an individual tab. They communicate through
6
+ * context, so a consumer writes:
7
+ *
8
+ * <Tabs value={tab} onValueChange={setTab}>
9
+ * <Tab value="overview">Overview</Tab>
10
+ * <Tab value="activity" leadingIcon="bolt">Activity</Tab>
11
+ * <Tab value="settings" disabled>Settings</Tab>
12
+ * </Tabs>
13
+ *
14
+ * Maps 1:1 to the Figma <Tabs> component set:
15
+ * intent → neutral | brand | danger (selected indicator + selected label)
16
+ * size → small | default | large (padding, gap, typography, indicator)
17
+ * Tab state=Selected → the active tab; state=Disabled → disabled
18
+ *
19
+ * Labels render through the shared <Text> component (label scale, medium
20
+ * weight) and optional leading icons through <Icon>, so Tabs inherits the
21
+ * type ramp and the Material Symbols slot architecture rather than restyling
22
+ * text itself. Tabs switch views in place, so each tab is a `tab` role (not a
23
+ * link — there is no <Link> in Cast UI, and a tab is not navigation).
24
+ *
25
+ * Tokens: `gap` / `paddingX` / `paddingY` / `listGap` are density spacing from
26
+ * `components.tabs`; `indicatorHeight` is keyed by `size` and constant across
27
+ * density (like Progress's track-height); `indicatorRadius` is the pill radius.
28
+ * Colours: the selected indicator and selected label bind to the intent system
29
+ * (`colors[intent].bold.default.bg`); unselected labels use
30
+ * `scheme.text.description`, hovered use `scheme.text.primary`, disabled use
31
+ * `scheme.disabled.fg`; the baseline divider is the dedicated
32
+ * `scheme.tabs.track` semantic (cool-grey/200 light, cool-grey/700 dark).
33
+ */
34
+ import React from 'react';
35
+ import { type StyleProp, type ViewStyle } from 'react-native';
36
+ import type { IntentName } from '../../tokens';
37
+ export type TabsSize = 'small' | 'default' | 'large';
38
+ export type TabsProps = {
39
+ /** The currently selected tab's `value`. */
40
+ value?: string;
41
+ /** Called with the next tab's `value` when a tab is pressed. */
42
+ onValueChange?: (value: string) => void;
43
+ /** Semantic intent — drives the selected indicator + selected label colour. */
44
+ intent?: IntentName;
45
+ /** Size variant — controls padding, gap, typography, and indicator height. */
46
+ size?: TabsSize;
47
+ /** `<Tab>` children. */
48
+ children: React.ReactNode;
49
+ /** Outer style — use for positioning (margin, width, alignSelf). */
50
+ style?: StyleProp<ViewStyle>;
51
+ /** Accessibility label for the tab list. */
52
+ accessibilityLabel?: string;
53
+ };
54
+ export type TabProps = {
55
+ /** Unique value identifying this tab — matched against `Tabs.value`. */
56
+ value: string;
57
+ /** The tab label text. */
58
+ children: string;
59
+ /** Icon before the label — Material Symbols name string or a ReactNode. */
60
+ leadingIcon?: string | React.ReactNode;
61
+ /** Disables interaction and applies muted styling. */
62
+ disabled?: boolean;
63
+ /** Outer style — applied to the tab pressable. */
64
+ style?: StyleProp<ViewStyle>;
65
+ /** Accessibility label — falls back to the label text. */
66
+ accessibilityLabel?: string;
67
+ };
68
+ export declare function Tab({ value, children, leadingIcon, disabled, style, accessibilityLabel, }: TabProps): import("react/jsx-runtime").JSX.Element;
69
+ export declare function Tabs({ value, onValueChange, intent, size, children, style, accessibilityLabel, }: TabsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tab = Tab;
4
+ exports.Tabs = Tabs;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * Tabs — a horizontal, underline-style tab bar for switching between views.
8
+ *
9
+ * Compound component. `<Tabs>` is the container that owns the selected `value`
10
+ * and `onValueChange`; `<Tab>` is an individual tab. They communicate through
11
+ * context, so a consumer writes:
12
+ *
13
+ * <Tabs value={tab} onValueChange={setTab}>
14
+ * <Tab value="overview">Overview</Tab>
15
+ * <Tab value="activity" leadingIcon="bolt">Activity</Tab>
16
+ * <Tab value="settings" disabled>Settings</Tab>
17
+ * </Tabs>
18
+ *
19
+ * Maps 1:1 to the Figma <Tabs> component set:
20
+ * intent → neutral | brand | danger (selected indicator + selected label)
21
+ * size → small | default | large (padding, gap, typography, indicator)
22
+ * Tab state=Selected → the active tab; state=Disabled → disabled
23
+ *
24
+ * Labels render through the shared <Text> component (label scale, medium
25
+ * weight) and optional leading icons through <Icon>, so Tabs inherits the
26
+ * type ramp and the Material Symbols slot architecture rather than restyling
27
+ * text itself. Tabs switch views in place, so each tab is a `tab` role (not a
28
+ * link — there is no <Link> in Cast UI, and a tab is not navigation).
29
+ *
30
+ * Tokens: `gap` / `paddingX` / `paddingY` / `listGap` are density spacing from
31
+ * `components.tabs`; `indicatorHeight` is keyed by `size` and constant across
32
+ * density (like Progress's track-height); `indicatorRadius` is the pill radius.
33
+ * Colours: the selected indicator and selected label bind to the intent system
34
+ * (`colors[intent].bold.default.bg`); unselected labels use
35
+ * `scheme.text.description`, hovered use `scheme.text.primary`, disabled use
36
+ * `scheme.disabled.fg`; the baseline divider is the dedicated
37
+ * `scheme.tabs.track` semantic (cool-grey/200 light, cool-grey/700 dark).
38
+ */
39
+ const react_1 = require("react");
40
+ const react_native_1 = require("react-native");
41
+ const theme_1 = require("../../theme");
42
+ const tokens_1 = require("../../tokens");
43
+ const Text_1 = require("../Text");
44
+ const Icon_1 = require("../Icon");
45
+ const TabsCtx = (0, react_1.createContext)(null);
46
+ function useTabsContext(component) {
47
+ const ctx = (0, react_1.useContext)(TabsCtx);
48
+ if (!ctx) {
49
+ throw new Error(`<${component}> must be used within <Tabs>`);
50
+ }
51
+ return ctx;
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // Constants
55
+ // ---------------------------------------------------------------------------
56
+ /** Maps tab size → label typography scale (Text component `type`). */
57
+ const LABEL_TYPE = {
58
+ small: 'label-sm',
59
+ default: 'label-md',
60
+ large: 'label-lg',
61
+ };
62
+ // ---------------------------------------------------------------------------
63
+ // Tab
64
+ // ---------------------------------------------------------------------------
65
+ function Tab({ value, children, leadingIcon, disabled = false, style, accessibilityLabel, }) {
66
+ const { value: selectedValue, onValueChange, size, intent } = useTabsContext('Tab');
67
+ const { components, colors, scheme } = (0, theme_1.useTheme)();
68
+ const [isHovered, setIsHovered] = (0, react_1.useState)(false);
69
+ const sizeTokens = components.tabs[size];
70
+ const { indicatorRadius } = components.tabs;
71
+ const isSelected = selectedValue === value;
72
+ const accent = colors[intent].bold.default.bg;
73
+ // Resolve the label/icon colour from interaction + selection state.
74
+ const fg = disabled
75
+ ? scheme.disabled.fg
76
+ : isSelected
77
+ ? accent
78
+ : isHovered
79
+ ? scheme.text.primary
80
+ : scheme.text.description;
81
+ const indicatorColor = isSelected ? accent : 'transparent';
82
+ const handlePress = (_e) => {
83
+ if (!disabled && !isSelected)
84
+ onValueChange?.(value);
85
+ };
86
+ const resolvedLeading = typeof leadingIcon === 'string' ? ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: leadingIcon, size: size, color: fg })) : (leadingIcon);
87
+ return ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: handlePress, disabled: disabled, onHoverIn: () => setIsHovered(true), onHoverOut: () => setIsHovered(false), accessibilityRole: "tab", accessibilityLabel: accessibilityLabel || children, accessibilityState: { selected: isSelected, disabled }, style: style, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
88
+ flexDirection: 'row',
89
+ alignItems: 'center',
90
+ justifyContent: 'center',
91
+ gap: sizeTokens.gap,
92
+ paddingHorizontal: sizeTokens.paddingX,
93
+ paddingVertical: sizeTokens.paddingY,
94
+ }, children: [resolvedLeading, (0, jsx_runtime_1.jsx)(Text_1.Text, { type: LABEL_TYPE[size], color: fg, selectable: false, children: children }), (0, jsx_runtime_1.jsx)(react_native_1.View, { pointerEvents: "none", style: {
95
+ position: 'absolute',
96
+ left: 0,
97
+ right: 0,
98
+ bottom: -tokens_1.controlTokens.borderWidth,
99
+ height: sizeTokens.indicatorHeight,
100
+ borderRadius: indicatorRadius,
101
+ backgroundColor: indicatorColor,
102
+ } })] }) }));
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Tabs
106
+ // ---------------------------------------------------------------------------
107
+ function Tabs({ value, onValueChange, intent = 'brand', size = 'default', children, style, accessibilityLabel, }) {
108
+ const { components, scheme } = (0, theme_1.useTheme)();
109
+ const { listGap } = components.tabs;
110
+ return ((0, jsx_runtime_1.jsx)(TabsCtx.Provider, { value: { value, onValueChange, size, intent }, children: (0, jsx_runtime_1.jsx)(react_native_1.View, { accessibilityRole: "tablist", accessibilityLabel: accessibilityLabel, style: [
111
+ {
112
+ flexDirection: 'row',
113
+ alignSelf: 'flex-start',
114
+ gap: listGap,
115
+ borderBottomWidth: tokens_1.controlTokens.borderWidth,
116
+ borderBottomColor: scheme.tabs.track,
117
+ },
118
+ style,
119
+ ], children: children }) }));
120
+ }
@@ -0,0 +1 @@
1
+ export { Tabs, Tab, type TabsProps, type TabProps, type TabsSize, } from './Tabs';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tab = exports.Tabs = void 0;
4
+ var Tabs_1 = require("./Tabs");
5
+ Object.defineProperty(exports, "Tabs", { enumerable: true, get: function () { return Tabs_1.Tabs; } });
6
+ Object.defineProperty(exports, "Tab", { enumerable: true, get: function () { return Tabs_1.Tab; } });
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, 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 DeepPartial, } from './theme';
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';
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';
@@ -20,3 +20,5 @@ export { Popover, type PopoverProps, type PopoverSize, type PopoverDirection, }
20
20
  export { Skeleton, type SkeletonProps, type SkeletonShape, } from './components/Skeleton';
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
+ export { Progress, type ProgressProps, type ProgressSize } from './components/Progress';
24
+ export { Tabs, Tab, type TabsProps, type TabProps, type TabsSize, } from './components/Tabs';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Input = exports.Badge = exports.Card = exports.Toggle = exports.Alert = exports.Checkbox = 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.themes = exports.useTheme = exports.ThemeProvider = exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
4
- exports.Text = exports.Tooltip = exports.Skeleton = exports.Popover = exports.Avatar = exports.Divider = exports.Chip = exports.Toast = exports.RadioGroup = exports.Radio = void 0;
3
+ exports.Card = exports.Toggle = exports.Alert = exports.Checkbox = 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.themes = exports.useTheme = exports.ThemeProvider = exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
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;
5
5
  // Cast UI — Cross-platform design system component library
6
6
  //
7
7
  // Tokens
@@ -21,6 +21,8 @@ Object.defineProperty(exports, "errorTokens", { enumerable: true, get: function
21
21
  Object.defineProperty(exports, "listColors", { enumerable: true, get: function () { return tokens_1.listColors; } });
22
22
  Object.defineProperty(exports, "checkboxColors", { enumerable: true, get: function () { return tokens_1.checkboxColors; } });
23
23
  Object.defineProperty(exports, "toggleColors", { enumerable: true, get: function () { return tokens_1.toggleColors; } });
24
+ Object.defineProperty(exports, "progressColors", { enumerable: true, get: function () { return tokens_1.progressColors; } });
25
+ Object.defineProperty(exports, "tabsColors", { enumerable: true, get: function () { return tokens_1.tabsColors; } });
24
26
  Object.defineProperty(exports, "radioColors", { enumerable: true, get: function () { return tokens_1.radioColors; } });
25
27
  Object.defineProperty(exports, "avatarColors", { enumerable: true, get: function () { return tokens_1.avatarColors; } });
26
28
  Object.defineProperty(exports, "skeletonColors", { enumerable: true, get: function () { return tokens_1.skeletonColors; } });
@@ -89,3 +91,8 @@ var Tooltip_1 = require("./components/Tooltip");
89
91
  Object.defineProperty(exports, "Tooltip", { enumerable: true, get: function () { return Tooltip_1.Tooltip; } });
90
92
  var Text_1 = require("./components/Text");
91
93
  Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return Text_1.Text; } });
94
+ var Progress_1 = require("./components/Progress");
95
+ Object.defineProperty(exports, "Progress", { enumerable: true, get: function () { return Progress_1.Progress; } });
96
+ var Tabs_1 = require("./components/Tabs");
97
+ Object.defineProperty(exports, "Tabs", { enumerable: true, get: function () { return Tabs_1.Tabs; } });
98
+ Object.defineProperty(exports, "Tab", { enumerable: true, get: function () { return Tabs_1.Tab; } });
@@ -1,3 +1,3 @@
1
1
  export { ThemeProvider, useTheme, type ThemeProviderProps, type Theme } from './ThemeContext';
2
2
  export { themes } from './themes';
3
- export type { DensityTheme, ComponentTokens, ButtonSizeTokens, ButtonThemeTokens, DialogSizeTokens, DialogThemeTokens, InputSizeTokens, InputThemeTokens, SelectContentTokens, SelectOptionTokens, SelectGroupTokens, SelectSeparatorTokens, SelectThemeTokens, ListItemTokens, ListSubheaderTokens, ListThemeTokens, CheckboxSizeTokens, CheckboxThemeTokens, AlertSizeTokens, AlertThemeTokens, ToggleSizeTokens, ToggleThemeTokens, CardSizeTokens, CardThemeTokens, BadgeSizeTokens, BadgeThemeTokens, RadioSizeTokens, RadioThemeTokens, ToastSizeTokens, ToastThemeTokens, ChipSizeTokens, ChipThemeTokens, AvatarSizeTokens, AvatarThemeTokens, PopoverSizeTokens, PopoverThemeTokens, TooltipSizeTokens, TooltipThemeTokens, DeepPartial, } from './types';
3
+ export type { DensityTheme, ComponentTokens, ButtonSizeTokens, ButtonThemeTokens, DialogSizeTokens, DialogThemeTokens, InputSizeTokens, InputThemeTokens, SelectContentTokens, SelectOptionTokens, SelectGroupTokens, SelectSeparatorTokens, SelectThemeTokens, ListItemTokens, ListSubheaderTokens, ListThemeTokens, CheckboxSizeTokens, CheckboxThemeTokens, AlertSizeTokens, AlertThemeTokens, ToggleSizeTokens, ToggleThemeTokens, CardSizeTokens, CardThemeTokens, BadgeSizeTokens, BadgeThemeTokens, RadioSizeTokens, RadioThemeTokens, ToastSizeTokens, ToastThemeTokens, ChipSizeTokens, ChipThemeTokens, AvatarSizeTokens, AvatarThemeTokens, PopoverSizeTokens, PopoverThemeTokens, TooltipSizeTokens, TooltipThemeTokens, ProgressSizeTokens, ProgressThemeTokens, TabsSizeTokens, TabsThemeTokens, DeepPartial, } from './types';
@@ -106,6 +106,18 @@ exports.themes = {
106
106
  small: { paddingX: 4, paddingY: 1 },
107
107
  default: { paddingX: 6, paddingY: 2 },
108
108
  },
109
+ progress: {
110
+ borderRadius: 9999,
111
+ small: { trackHeight: 4 },
112
+ default: { trackHeight: 8 },
113
+ large: { trackHeight: 12 },
114
+ },
115
+ tabs: {
116
+ listGap: 8, indicatorRadius: 9999,
117
+ small: { gap: 4, paddingX: 8, paddingY: 4, indicatorHeight: 2 },
118
+ default: { gap: 6, paddingX: 10, paddingY: 6, indicatorHeight: 2 },
119
+ large: { gap: 8, paddingX: 12, paddingY: 8, indicatorHeight: 4 },
120
+ },
109
121
  },
110
122
  default: {
111
123
  dialog: {
@@ -200,6 +212,18 @@ exports.themes = {
200
212
  small: { paddingX: 6, paddingY: 2 },
201
213
  default: { paddingX: 8, paddingY: 4 },
202
214
  },
215
+ progress: {
216
+ borderRadius: 9999,
217
+ small: { trackHeight: 4 },
218
+ default: { trackHeight: 8 },
219
+ large: { trackHeight: 12 },
220
+ },
221
+ tabs: {
222
+ listGap: 16, indicatorRadius: 9999,
223
+ small: { gap: 6, paddingX: 10, paddingY: 6, indicatorHeight: 2 },
224
+ default: { gap: 8, paddingX: 12, paddingY: 8, indicatorHeight: 2 },
225
+ large: { gap: 8, paddingX: 16, paddingY: 10, indicatorHeight: 4 },
226
+ },
203
227
  },
204
228
  comfortable: {
205
229
  dialog: {
@@ -294,5 +318,17 @@ exports.themes = {
294
318
  small: { paddingX: 8, paddingY: 4 },
295
319
  default: { paddingX: 10, paddingY: 6 },
296
320
  },
321
+ progress: {
322
+ borderRadius: 9999,
323
+ small: { trackHeight: 4 },
324
+ default: { trackHeight: 8 },
325
+ large: { trackHeight: 12 },
326
+ },
327
+ tabs: {
328
+ listGap: 24, indicatorRadius: 9999,
329
+ small: { gap: 8, paddingX: 12, paddingY: 8, indicatorHeight: 2 },
330
+ default: { gap: 8, paddingX: 16, paddingY: 10, indicatorHeight: 2 },
331
+ large: { gap: 12, paddingX: 20, paddingY: 12, indicatorHeight: 4 },
332
+ },
297
333
  },
298
334
  };
@@ -242,6 +242,38 @@ export type TooltipThemeTokens = {
242
242
  small: TooltipSizeTokens;
243
243
  default: TooltipSizeTokens;
244
244
  };
245
+ /** Progress track thickness for one size variant (constant across density,
246
+ * keyed by the `size` prop like Badge dot-size / Toggle track). */
247
+ export type ProgressSizeTokens = {
248
+ trackHeight: number;
249
+ };
250
+ /** Progress tokens — track thickness varies by the `size` prop; the pill
251
+ * radius is constant. No density-varying spacing. */
252
+ export type ProgressThemeTokens = {
253
+ borderRadius: number;
254
+ small: ProgressSizeTokens;
255
+ default: ProgressSizeTokens;
256
+ large: ProgressSizeTokens;
257
+ };
258
+ /** Spacing/sizing tokens for a single tab size variant. `gap`, `paddingX`,
259
+ * and `paddingY` vary by density; `indicatorHeight` is keyed by the `size`
260
+ * prop and constant across density (like Toggle's track / Progress's
261
+ * track-height — bound to a primitive `size/*`). */
262
+ export type TabsSizeTokens = {
263
+ gap: number;
264
+ paddingX: number;
265
+ paddingY: number;
266
+ indicatorHeight: number;
267
+ };
268
+ /** Tabs tokens — per-size tab spacing + the gap between tabs (`listGap`,
269
+ * density-varying) and the pill `indicatorRadius` (constant). */
270
+ export type TabsThemeTokens = {
271
+ listGap: number;
272
+ indicatorRadius: number;
273
+ small: TabsSizeTokens;
274
+ default: TabsSizeTokens;
275
+ large: TabsSizeTokens;
276
+ };
245
277
  /**
246
278
  * Component-level tokens that vary by density theme.
247
279
  * Extended as new components are added to the library.
@@ -263,6 +295,8 @@ export type ComponentTokens = {
263
295
  avatar: AvatarThemeTokens;
264
296
  popover: PopoverThemeTokens;
265
297
  tooltip: TooltipThemeTokens;
298
+ progress: ProgressThemeTokens;
299
+ tabs: TabsThemeTokens;
266
300
  };
267
301
  /** Utility type for partial overrides at any depth */
268
302
  export type DeepPartial<T> = {
@@ -188,6 +188,18 @@ export type ColorScheme = {
188
188
  disabled: string;
189
189
  };
190
190
  };
191
+ /** Progress colours — track background (the fill uses the intent system) */
192
+ progress: {
193
+ track: string;
194
+ };
195
+ /**
196
+ * Tabs colours — the baseline divider under the tab strip. The selected
197
+ * indicator + selected label colour come from the intent system; the
198
+ * unselected / hover label colours come from text.description / text.primary.
199
+ */
200
+ tabs: {
201
+ track: string;
202
+ };
191
203
  /** Avatar colours — initials/icon fallback surface + foreground */
192
204
  avatar: {
193
205
  bg: string;
@@ -348,6 +360,14 @@ export declare const toggleColors: {
348
360
  disabled: string;
349
361
  };
350
362
  };
363
+ /** Progress colours — track background (fill comes from the intent system) */
364
+ export declare const progressColors: {
365
+ track: string;
366
+ };
367
+ /** Tabs colours — baseline track (indicator/label colours come from intents/text) */
368
+ export declare const tabsColors: {
369
+ track: string;
370
+ };
351
371
  /** Avatar colours — initials/icon fallback surface + foreground */
352
372
  export declare const avatarColors: {
353
373
  bg: string;
@@ -15,7 +15,7 @@
15
15
  * the light-scheme values, kept for backwards compatibility.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.listColors = exports.skeletonColors = exports.avatarColors = exports.toggleColors = exports.radioColors = exports.checkboxColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
18
+ exports.listColors = exports.skeletonColors = exports.avatarColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.radioColors = exports.checkboxColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
19
19
  // ---------------------------------------------------------------------------
20
20
  // Light scheme — semantic-light mode
21
21
  // ---------------------------------------------------------------------------
@@ -139,6 +139,8 @@ exports.lightColors = {
139
139
  thumb: '#FFFFFF',
140
140
  label: { default: '#374151', disabled: '#9CA3AF' },
141
141
  },
142
+ progress: { track: '#E5E7EB' }, // control/progress/track/bg → cool-grey/200
143
+ tabs: { track: '#E5E7EB' }, // control/tabs/track/bg → cool-grey/200
142
144
  avatar: { bg: '#F3F4F6', fg: '#374151' },
143
145
  skeleton: { bg: '#F3F4F6', highlight: '#E5E7EB' },
144
146
  list: {
@@ -280,6 +282,8 @@ exports.darkColors = {
280
282
  thumb: '#FFFFFF',
281
283
  label: { default: '#E5E7EB', disabled: '#6B7280' },
282
284
  },
285
+ progress: { track: '#374151' }, // control/progress/track/bg → cool-grey/700
286
+ tabs: { track: '#374151' }, // control/tabs/track/bg → cool-grey/700
283
287
  avatar: { bg: '#374151', fg: '#E5E7EB' },
284
288
  skeleton: { bg: '#1F2937', highlight: '#374151' },
285
289
  list: {
@@ -338,6 +342,10 @@ exports.checkboxColors = exports.lightColors.checkbox;
338
342
  exports.radioColors = exports.lightColors.radio;
339
343
  /** Toggle colours — track (on/off/disabled) + thumb + label */
340
344
  exports.toggleColors = exports.lightColors.toggle;
345
+ /** Progress colours — track background (fill comes from the intent system) */
346
+ exports.progressColors = exports.lightColors.progress;
347
+ /** Tabs colours — baseline track (indicator/label colours come from intents/text) */
348
+ exports.tabsColors = exports.lightColors.tabs;
341
349
  /** Avatar colours — initials/icon fallback surface + foreground */
342
350
  exports.avatarColors = exports.lightColors.avatar;
343
351
  /** Skeleton colours — placeholder surface for loading states */
@@ -1,3 +1,3 @@
1
- export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, radioColors, avatarColors, skeletonColors, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, } from './colors';
1
+ export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, } from './colors';
2
2
  export { fontFamily, fontWeight, label, title, body, heading, display, caption, type LabelSize, } from './typography';
3
3
  export { iconSize, type IconSize } from './icon';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
3
+ exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
4
4
  var colors_1 = require("./colors");
5
5
  Object.defineProperty(exports, "lightColors", { enumerable: true, get: function () { return colors_1.lightColors; } });
6
6
  Object.defineProperty(exports, "darkColors", { enumerable: true, get: function () { return colors_1.darkColors; } });
@@ -17,6 +17,8 @@ Object.defineProperty(exports, "errorTokens", { enumerable: true, get: function
17
17
  Object.defineProperty(exports, "listColors", { enumerable: true, get: function () { return colors_1.listColors; } });
18
18
  Object.defineProperty(exports, "checkboxColors", { enumerable: true, get: function () { return colors_1.checkboxColors; } });
19
19
  Object.defineProperty(exports, "toggleColors", { enumerable: true, get: function () { return colors_1.toggleColors; } });
20
+ Object.defineProperty(exports, "progressColors", { enumerable: true, get: function () { return colors_1.progressColors; } });
21
+ Object.defineProperty(exports, "tabsColors", { enumerable: true, get: function () { return colors_1.tabsColors; } });
20
22
  Object.defineProperty(exports, "radioColors", { enumerable: true, get: function () { return colors_1.radioColors; } });
21
23
  Object.defineProperty(exports, "avatarColors", { enumerable: true, get: function () { return colors_1.avatarColors; } });
22
24
  Object.defineProperty(exports, "skeletonColors", { enumerable: true, get: function () { return colors_1.skeletonColors; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@castui/cast-ui",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "A cross-platform design system for React Native (iOS, Android, Web) with multi-theme support.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,8 +22,7 @@
22
22
  "build-storybook": "STORYBOOK_DISABLE_TELEMETRY=1 storybook build",
23
23
  "build": "tsc --project tsconfig.build.json",
24
24
  "prepublishOnly": "npm run build",
25
- "test": "npm run build && node scripts/smoke-test.js",
26
- "zh:track-package": "zh-adoption track-package"
25
+ "test": "npm run build && node scripts/smoke-test.js"
27
26
  },
28
27
  "repository": {
29
28
  "type": "git",
@@ -67,5 +66,8 @@
67
66
  "react-native-web": "^0.21.2",
68
67
  "storybook": "^10.2.8",
69
68
  "typescript": "^5.9.3"
69
+ },
70
+ "overrides": {
71
+ "esbuild": ">=0.28.1"
70
72
  }
71
73
  }