@castui/cast-ui 4.7.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.
Files changed (72) hide show
  1. package/README.md +6 -0
  2. package/dist/components/Accordion/Accordion.d.ts +80 -0
  3. package/dist/components/Accordion/Accordion.js +157 -0
  4. package/dist/components/Accordion/index.d.ts +1 -0
  5. package/dist/components/Accordion/index.js +6 -0
  6. package/dist/components/AppBar/AppBar.d.ts +47 -0
  7. package/dist/components/AppBar/AppBar.js +47 -0
  8. package/dist/components/AppBar/index.d.ts +1 -0
  9. package/dist/components/AppBar/index.js +5 -0
  10. package/dist/components/Autocomplete/Autocomplete.d.ts +70 -0
  11. package/dist/components/Autocomplete/Autocomplete.js +249 -0
  12. package/dist/components/Autocomplete/index.d.ts +1 -0
  13. package/dist/components/Autocomplete/index.js +5 -0
  14. package/dist/components/Backdrop/Backdrop.d.ts +32 -0
  15. package/dist/components/Backdrop/Backdrop.js +74 -0
  16. package/dist/components/Backdrop/index.d.ts +1 -0
  17. package/dist/components/Backdrop/index.js +5 -0
  18. package/dist/components/BottomSheet/BottomSheet.d.ts +50 -0
  19. package/dist/components/BottomSheet/BottomSheet.js +159 -0
  20. package/dist/components/BottomSheet/index.d.ts +1 -0
  21. package/dist/components/BottomSheet/index.js +6 -0
  22. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +63 -0
  23. package/dist/components/Breadcrumbs/Breadcrumbs.js +143 -0
  24. package/dist/components/Breadcrumbs/index.d.ts +1 -0
  25. package/dist/components/Breadcrumbs/index.js +6 -0
  26. package/dist/components/CodeBlock/CodeBlock.d.ts +42 -0
  27. package/dist/components/CodeBlock/CodeBlock.js +110 -0
  28. package/dist/components/CodeBlock/index.d.ts +1 -0
  29. package/dist/components/CodeBlock/index.js +5 -0
  30. package/dist/components/Drawer/Drawer.d.ts +51 -0
  31. package/dist/components/Drawer/Drawer.js +168 -0
  32. package/dist/components/Drawer/index.d.ts +1 -0
  33. package/dist/components/Drawer/index.js +6 -0
  34. package/dist/components/Link/Link.d.ts +51 -0
  35. package/dist/components/Link/Link.js +73 -0
  36. package/dist/components/Link/index.d.ts +1 -0
  37. package/dist/components/Link/index.js +5 -0
  38. package/dist/components/Menu/Menu.d.ts +91 -0
  39. package/dist/components/Menu/Menu.js +211 -0
  40. package/dist/components/Menu/index.d.ts +1 -0
  41. package/dist/components/Menu/index.js +9 -0
  42. package/dist/components/Slider/Slider.d.ts +47 -0
  43. package/dist/components/Slider/Slider.js +132 -0
  44. package/dist/components/Slider/index.d.ts +1 -0
  45. package/dist/components/Slider/index.js +5 -0
  46. package/dist/components/SpeedDial/SpeedDial.d.ts +72 -0
  47. package/dist/components/SpeedDial/SpeedDial.js +189 -0
  48. package/dist/components/SpeedDial/index.d.ts +1 -0
  49. package/dist/components/SpeedDial/index.js +6 -0
  50. package/dist/components/Table/Table.d.ts +74 -0
  51. package/dist/components/Table/Table.js +176 -0
  52. package/dist/components/Table/index.d.ts +1 -0
  53. package/dist/components/Table/index.js +9 -0
  54. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +69 -0
  55. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.js +158 -0
  56. package/dist/components/ToggleButtonGroup/index.d.ts +1 -0
  57. package/dist/components/ToggleButtonGroup/index.js +6 -0
  58. package/dist/index.d.ts +16 -2
  59. package/dist/index.js +49 -2
  60. package/dist/theme/ThemeContext.d.ts +8 -1
  61. package/dist/theme/ThemeContext.js +7 -4
  62. package/dist/theme/applyCastTheme.d.ts +75 -0
  63. package/dist/theme/applyCastTheme.js +95 -0
  64. package/dist/theme/index.d.ts +2 -1
  65. package/dist/theme/index.js +3 -1
  66. package/dist/theme/themes.js +177 -0
  67. package/dist/theme/types.d.ts +177 -0
  68. package/dist/tokens/colors.d.ts +44 -0
  69. package/dist/tokens/colors.js +47 -1
  70. package/dist/tokens/index.d.ts +1 -1
  71. package/dist/tokens/index.js +4 -1
  72. package/package.json +2 -1
package/README.md CHANGED
@@ -2,6 +2,12 @@
2
2
  <img src="https://raw.githubusercontent.com/Connagh/cast-ui/main/logo.png" alt="Cast UI" width="300" />
3
3
  </p>
4
4
 
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@castui/cast-ui"><img src="https://img.shields.io/npm/v/@castui/cast-ui.svg" alt="npm version" /></a>
7
+ <a href="https://www.npmjs.com/package/@castui/cast-ui"><img src="https://img.shields.io/npm/dm/@castui/cast-ui.svg" alt="npm downloads" /></a>
8
+ <a href="https://github.com/Connagh/cast-ui/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@castui/cast-ui.svg" alt="license" /></a>
9
+ </p>
10
+
5
11
  A cross-platform component library for React Native. One set of components
6
12
  that works on iOS, Android, and the web.
7
13
 
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Accordion — a stack of expandable sections, flush/divided style.
3
+ *
4
+ * Compound component. `<Accordion>` owns which items are open and how they
5
+ * coordinate; `<AccordionItem>` is one section with a header and collapsible
6
+ * content. They communicate through context, so a consumer writes:
7
+ *
8
+ * <Accordion type="single" defaultValue="shipping">
9
+ * <AccordionItem value="shipping" title="Shipping">
10
+ * Free delivery on orders over £50.
11
+ * </AccordionItem>
12
+ * <AccordionItem value="returns" title="Returns" leadingIcon="undo">
13
+ * Return any item within 30 days.
14
+ * </AccordionItem>
15
+ * <AccordionItem value="legacy" title="Archived" disabled>
16
+ * Hidden content.
17
+ * </AccordionItem>
18
+ * </Accordion>
19
+ *
20
+ * Maps 1:1 to the Figma <Accordion> component:
21
+ * type → single | multiple (single opens one section at a time)
22
+ * size → small | default | large (header padding, gap, typography)
23
+ * AccordionItem state=open → expanded; state=disabled → disabled;
24
+ * state=hover → runtime onHoverIn (not a prop)
25
+ *
26
+ * Accordion is neutral only. The header label uses scheme.text.primary (disabled
27
+ * uses scheme.disabled.fg). The chevron (chevron_right, rotated 90deg when open)
28
+ * and the optional leadingIcon render through <Icon> at the named size keyed by
29
+ * the `size` prop and take the same colour as the label. The header hover and
30
+ * press backgrounds reuse the neutral subtle intent. The divider between items is
31
+ * the overlay border colour (like <Divider>) at the control border width.
32
+ *
33
+ * Tokens: `gap` / `paddingX` / `paddingY` are density spacing from
34
+ * `components.accordion[size]`. No new colour tokens.
35
+ */
36
+ import React from 'react';
37
+ import { type StyleProp, type ViewStyle } from 'react-native';
38
+ export type AccordionSize = 'small' | 'default' | 'large';
39
+ export type AccordionType = 'single' | 'multiple';
40
+ export type AccordionProps = {
41
+ /** 'single' opens one section at a time; 'multiple' opens any number. */
42
+ type?: AccordionType;
43
+ /**
44
+ * Controlled open value(s). A string for `type="single"`, a string array for
45
+ * `type="multiple"`. Provide with `onValueChange` for a controlled accordion.
46
+ */
47
+ value?: string | string[];
48
+ /** Uncontrolled initial open value(s). Same shape rules as `value`. */
49
+ defaultValue?: string | string[];
50
+ /** Called with the next open value(s) when a section toggles. */
51
+ onValueChange?: (value: string | string[]) => void;
52
+ /** Size variant — header padding, gap, and typography. */
53
+ size?: AccordionSize;
54
+ /** For `type="single"`, allow closing the open section. Defaults to true. */
55
+ collapsible?: boolean;
56
+ /** `<AccordionItem>` children. */
57
+ children: React.ReactNode;
58
+ /** Outer style — use for positioning (margin, width, alignSelf). */
59
+ style?: StyleProp<ViewStyle>;
60
+ /** Accessibility label for the group. */
61
+ accessibilityLabel?: string;
62
+ };
63
+ export type AccordionItemProps = {
64
+ /** Unique value identifying this section. */
65
+ value: string;
66
+ /** The header label text. */
67
+ title: string;
68
+ /** Icon before the title — Material Symbols name string or a ReactNode. */
69
+ leadingIcon?: string | React.ReactNode;
70
+ /** Disables interaction and applies muted styling. */
71
+ disabled?: boolean;
72
+ /** The collapsible content. A string is wrapped in <Text> automatically. */
73
+ children: React.ReactNode;
74
+ /** Outer style — applied to the item container. */
75
+ style?: StyleProp<ViewStyle>;
76
+ /** Accessibility label — falls back to the title text. */
77
+ accessibilityLabel?: string;
78
+ };
79
+ export declare function AccordionItem({ value, title, leadingIcon, disabled, children, style, accessibilityLabel, }: AccordionItemProps): import("react/jsx-runtime").JSX.Element;
80
+ export declare function Accordion({ type, value, defaultValue, onValueChange, size, collapsible, children, style, accessibilityLabel, }: AccordionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AccordionItem = AccordionItem;
4
+ exports.Accordion = Accordion;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * Accordion — a stack of expandable sections, flush/divided style.
8
+ *
9
+ * Compound component. `<Accordion>` owns which items are open and how they
10
+ * coordinate; `<AccordionItem>` is one section with a header and collapsible
11
+ * content. They communicate through context, so a consumer writes:
12
+ *
13
+ * <Accordion type="single" defaultValue="shipping">
14
+ * <AccordionItem value="shipping" title="Shipping">
15
+ * Free delivery on orders over £50.
16
+ * </AccordionItem>
17
+ * <AccordionItem value="returns" title="Returns" leadingIcon="undo">
18
+ * Return any item within 30 days.
19
+ * </AccordionItem>
20
+ * <AccordionItem value="legacy" title="Archived" disabled>
21
+ * Hidden content.
22
+ * </AccordionItem>
23
+ * </Accordion>
24
+ *
25
+ * Maps 1:1 to the Figma <Accordion> component:
26
+ * type → single | multiple (single opens one section at a time)
27
+ * size → small | default | large (header padding, gap, typography)
28
+ * AccordionItem state=open → expanded; state=disabled → disabled;
29
+ * state=hover → runtime onHoverIn (not a prop)
30
+ *
31
+ * Accordion is neutral only. The header label uses scheme.text.primary (disabled
32
+ * uses scheme.disabled.fg). The chevron (chevron_right, rotated 90deg when open)
33
+ * and the optional leadingIcon render through <Icon> at the named size keyed by
34
+ * the `size` prop and take the same colour as the label. The header hover and
35
+ * press backgrounds reuse the neutral subtle intent. The divider between items is
36
+ * the overlay border colour (like <Divider>) at the control border width.
37
+ *
38
+ * Tokens: `gap` / `paddingX` / `paddingY` are density spacing from
39
+ * `components.accordion[size]`. No new colour tokens.
40
+ */
41
+ const react_1 = require("react");
42
+ const react_native_1 = require("react-native");
43
+ const theme_1 = require("../../theme");
44
+ const tokens_1 = require("../../tokens");
45
+ const Text_1 = require("../Text");
46
+ const Icon_1 = require("../Icon");
47
+ const AccordionCtx = (0, react_1.createContext)(null);
48
+ function useAccordionContext(component) {
49
+ const ctx = (0, react_1.useContext)(AccordionCtx);
50
+ if (!ctx) {
51
+ throw new Error(`<${component}> must be used within <Accordion>`);
52
+ }
53
+ return ctx;
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Constants
57
+ // ---------------------------------------------------------------------------
58
+ /** Header label typography scale (medium weight title). */
59
+ const HEADER_TYPE = {
60
+ small: 'title-sm',
61
+ default: 'title-md',
62
+ large: 'title-lg',
63
+ };
64
+ /** Content body typography scale. */
65
+ const CONTENT_TYPE = {
66
+ small: 'body-sm',
67
+ default: 'body-md',
68
+ large: 'body-lg',
69
+ };
70
+ /** Normalise a value/defaultValue prop into an array of open values. */
71
+ function toOpenArray(v, type) {
72
+ if (v === undefined || v === null)
73
+ return [];
74
+ const arr = Array.isArray(v) ? v : [v];
75
+ const cleaned = arr.filter((x) => x !== '');
76
+ return type === 'single' ? cleaned.slice(0, 1) : cleaned;
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // AccordionItem
80
+ // ---------------------------------------------------------------------------
81
+ function AccordionItem({ value, title, leadingIcon, disabled = false, children, style, accessibilityLabel, }) {
82
+ const { openValues, toggle, size } = useAccordionContext('AccordionItem');
83
+ const { components, colors, scheme } = (0, theme_1.useTheme)();
84
+ const [isHovered, setIsHovered] = (0, react_1.useState)(false);
85
+ const sizeTokens = components.accordion[size];
86
+ const isOpen = openValues.includes(value);
87
+ // Chevron rotation: chevron_right (0deg) rotates to point down (90deg) when open.
88
+ const spin = (0, react_1.useRef)(new react_native_1.Animated.Value(isOpen ? 1 : 0)).current;
89
+ (0, react_1.useEffect)(() => {
90
+ react_native_1.Animated.timing(spin, {
91
+ toValue: isOpen ? 1 : 0,
92
+ duration: 160,
93
+ easing: react_native_1.Easing.inOut(react_native_1.Easing.ease),
94
+ useNativeDriver: true,
95
+ }).start();
96
+ }, [isOpen, spin]);
97
+ const rotate = spin.interpolate({
98
+ inputRange: [0, 1],
99
+ outputRange: ['0deg', '90deg'],
100
+ });
101
+ const labelFg = disabled ? scheme.disabled.fg : scheme.text.primary;
102
+ const resolvedLeading = typeof leadingIcon === 'string' ? ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: leadingIcon, size: size, color: labelFg })) : (leadingIcon ?? null);
103
+ const content = typeof children === 'string' ? ((0, jsx_runtime_1.jsx)(Text_1.Text, { type: CONTENT_TYPE[size], color: scheme.text.description, children: children })) : (children);
104
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
105
+ {
106
+ borderBottomWidth: tokens_1.controlTokens.borderWidth,
107
+ borderBottomColor: scheme.surface.overlay.border,
108
+ },
109
+ style,
110
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => {
111
+ if (!disabled)
112
+ toggle(value);
113
+ }, disabled: disabled, onHoverIn: () => setIsHovered(true), onHoverOut: () => setIsHovered(false), accessibilityRole: "button", accessibilityLabel: accessibilityLabel || title, accessibilityState: { expanded: isOpen, disabled }, children: ({ pressed }) => {
114
+ const headerBg = disabled
115
+ ? 'transparent'
116
+ : pressed
117
+ ? colors.neutral.subtle.active.bg
118
+ : isHovered
119
+ ? colors.neutral.subtle.hover.bg
120
+ : 'transparent';
121
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
122
+ flexDirection: 'row',
123
+ alignItems: 'center',
124
+ gap: sizeTokens.gap,
125
+ paddingHorizontal: sizeTokens.paddingX,
126
+ paddingVertical: sizeTokens.paddingY,
127
+ backgroundColor: headerBg,
128
+ }, children: [resolvedLeading, (0, jsx_runtime_1.jsx)(Text_1.Text, { type: HEADER_TYPE[size], color: labelFg, selectable: false, style: { flex: 1 }, children: title }), (0, jsx_runtime_1.jsx)(react_native_1.Animated.View, { pointerEvents: "none", style: { transform: [{ rotate }] }, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron_right", size: size, color: labelFg }) })] }));
129
+ } }), isOpen ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: {
130
+ paddingHorizontal: sizeTokens.paddingX,
131
+ paddingBottom: sizeTokens.paddingY,
132
+ }, children: content })) : null] }));
133
+ }
134
+ // ---------------------------------------------------------------------------
135
+ // Accordion
136
+ // ---------------------------------------------------------------------------
137
+ function Accordion({ type = 'single', value, defaultValue, onValueChange, size = 'default', collapsible = true, children, style, accessibilityLabel, }) {
138
+ const isControlled = value !== undefined;
139
+ const [internal, setInternal] = (0, react_1.useState)(() => toOpenArray(defaultValue, type));
140
+ const openValues = toOpenArray(isControlled ? value : internal, type);
141
+ const toggle = (item) => {
142
+ let next;
143
+ if (type === 'multiple') {
144
+ next = openValues.includes(item)
145
+ ? openValues.filter((x) => x !== item)
146
+ : [...openValues, item];
147
+ }
148
+ else {
149
+ const isOpen = openValues.includes(item);
150
+ next = isOpen ? (collapsible ? [] : openValues) : [item];
151
+ }
152
+ if (!isControlled)
153
+ setInternal(next);
154
+ onValueChange?.(type === 'multiple' ? next : (next[0] ?? ''));
155
+ };
156
+ return ((0, jsx_runtime_1.jsx)(AccordionCtx.Provider, { value: { openValues, toggle, size }, children: (0, jsx_runtime_1.jsx)(react_native_1.View, { accessibilityRole: "none", accessibilityLabel: accessibilityLabel, style: [{ alignSelf: 'stretch' }, style], children: children }) }));
157
+ }
@@ -0,0 +1 @@
1
+ export { Accordion, AccordionItem, type AccordionProps, type AccordionItemProps, type AccordionSize, type AccordionType, } from './Accordion';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AccordionItem = exports.Accordion = void 0;
4
+ var Accordion_1 = require("./Accordion");
5
+ Object.defineProperty(exports, "Accordion", { enumerable: true, get: function () { return Accordion_1.Accordion; } });
6
+ Object.defineProperty(exports, "AccordionItem", { enumerable: true, get: function () { return Accordion_1.AccordionItem; } });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * AppBar — a top bar with a leading control, a title, and trailing actions.
3
+ *
4
+ * Maps 1:1 to the Figma <App Bar> component:
5
+ * intent → neutral | brand | danger
6
+ * prominence → default | bold | subtle
7
+ * size → small | default | large (padding, gap, title scale)
8
+ * align → start | center (title alignment)
9
+ *
10
+ * Colour comes from the intent system, like Button. prominence picks the
11
+ * surface: bold is a filled bar (intent bg, white text), default is a plain bar
12
+ * with a bottom divider, subtle is transparent. The title and the leadingIcon
13
+ * inherit the bar foreground; trailing actions are a free slot, so colour them
14
+ * to match on a bold bar. The bar hugs its content height from the padding, so
15
+ * there is no fixed height token. Spacing varies by density; the title scale by
16
+ * size. Fonts are consumer-loaded.
17
+ */
18
+ import React from 'react';
19
+ import { type StyleProp, type ViewStyle, type GestureResponderEvent } from 'react-native';
20
+ import type { IntentName, ProminenceName } from '../../tokens';
21
+ export type AppBarSize = 'small' | 'default' | 'large';
22
+ export type AppBarAlign = 'start' | 'center';
23
+ export type AppBarProps = {
24
+ /** The bar title. */
25
+ title: string;
26
+ /** Standard leading control icon (menu / back). Auto-coloured + pressable. */
27
+ leadingIcon?: string;
28
+ /** Press handler for the leading icon. */
29
+ onLeadingPress?: (e: GestureResponderEvent) => void;
30
+ /** Custom leading slot. Wins over leadingIcon. */
31
+ leading?: React.ReactNode;
32
+ /** Trailing actions slot. */
33
+ trailing?: React.ReactNode;
34
+ /** Semantic intent. */
35
+ intent?: IntentName;
36
+ /** Visual weight — bold (filled), default (divider), subtle (transparent). */
37
+ prominence?: ProminenceName;
38
+ /** Size variant — padding, gap, and title scale. */
39
+ size?: AppBarSize;
40
+ /** Title alignment. Defaults to start. */
41
+ align?: AppBarAlign;
42
+ /** Outer style. */
43
+ style?: StyleProp<ViewStyle>;
44
+ /** Accessibility label — falls back to the title. */
45
+ accessibilityLabel?: string;
46
+ };
47
+ export declare function AppBar({ title, leadingIcon, onLeadingPress, leading, trailing, intent, prominence, size, align, style, accessibilityLabel, }: AppBarProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppBar = AppBar;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_native_1 = require("react-native");
6
+ const theme_1 = require("../../theme");
7
+ const tokens_1 = require("../../tokens");
8
+ const Text_1 = require("../Text");
9
+ const Icon_1 = require("../Icon");
10
+ // ---------------------------------------------------------------------------
11
+ // Constants
12
+ // ---------------------------------------------------------------------------
13
+ /** Maps size → title typography scale (Text component `type`). */
14
+ const TITLE_TYPE = {
15
+ small: 'title-sm',
16
+ default: 'title-md',
17
+ large: 'title-lg',
18
+ };
19
+ /** Maps size → named Icon scale for the leading control. */
20
+ const ICON_SIZE = {
21
+ small: 'default',
22
+ default: 'large',
23
+ large: 'large',
24
+ };
25
+ // ---------------------------------------------------------------------------
26
+ // Component
27
+ // ---------------------------------------------------------------------------
28
+ function AppBar({ title, leadingIcon, onLeadingPress, leading, trailing, intent = 'neutral', prominence = 'default', size = 'default', align = 'start', style, accessibilityLabel, }) {
29
+ const { components, colors } = (0, theme_1.useTheme)();
30
+ const tokens = components.appBar[size];
31
+ const barColors = colors[intent][prominence].default;
32
+ const resolvedLeading = leading ??
33
+ (leadingIcon ? ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: onLeadingPress, accessibilityRole: "button", accessibilityLabel: "Navigation", hitSlop: 8, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: leadingIcon, size: ICON_SIZE[size], color: barColors.fg }) })) : null);
34
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { accessibilityRole: "header", accessibilityLabel: accessibilityLabel || title, style: [
35
+ {
36
+ flexDirection: 'row',
37
+ alignItems: 'center',
38
+ gap: tokens.gap,
39
+ paddingHorizontal: tokens.paddingX,
40
+ paddingVertical: tokens.paddingY,
41
+ backgroundColor: barColors.bg,
42
+ borderBottomWidth: tokens_1.controlTokens.borderWidth,
43
+ borderBottomColor: barColors.border,
44
+ },
45
+ style,
46
+ ], children: [resolvedLeading, (0, jsx_runtime_1.jsx)(Text_1.Text, { type: TITLE_TYPE[size], color: barColors.fg, numberOfLines: 1, selectable: false, style: { flex: 1, textAlign: align === 'center' ? 'center' : 'left' }, children: title }), trailing ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: { flexDirection: 'row', alignItems: 'center', gap: tokens.gap }, children: trailing })) : null] }));
47
+ }
@@ -0,0 +1 @@
1
+ export { AppBar, type AppBarProps, type AppBarSize, type AppBarAlign } from './AppBar';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppBar = void 0;
4
+ var AppBar_1 = require("./AppBar");
5
+ Object.defineProperty(exports, "AppBar", { enumerable: true, get: function () { return AppBar_1.AppBar; } });
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Autocomplete — a text field that filters a list of options as you type.
3
+ *
4
+ * Maps 1:1 to the Figma <Autocomplete> component:
5
+ * size → small | default | large
6
+ * state → default | hover | focus | error | disabled
7
+ * option state → default | hover | selected | disabled
8
+ *
9
+ * Autocomplete is the Select combobox specialised for client-side filtering. Its
10
+ * field is an Input, so it reuses the input tokens; its options are
11
+ * value-selection rows, so it reuses the select tokens and the
12
+ * scheme.select.option colours. It introduces no new tokens. Type to filter the
13
+ * options by label, press one to select it, or clear the field.
14
+ *
15
+ * value is controlled with value/onValueChange (null = nothing selected) or
16
+ * uncontrolled with defaultValue. Pass a filterOptions function to change how
17
+ * matching works. Fonts are consumer-loaded.
18
+ */
19
+ import React from 'react';
20
+ import { type StyleProp, type ViewStyle } from 'react-native';
21
+ export type AutocompleteSize = 'small' | 'default' | 'large';
22
+ export type AutocompleteOption = {
23
+ /** Unique value. */
24
+ value: string;
25
+ /** Display label — also what the filter matches against. */
26
+ label: string;
27
+ /** Supporting text below the label. */
28
+ description?: string;
29
+ /** Leading icon — Material Symbols name or a ReactNode. */
30
+ icon?: string | React.ReactNode;
31
+ /** Disables this option. */
32
+ disabled?: boolean;
33
+ };
34
+ export type AutocompleteProps = {
35
+ /** The options to choose from. */
36
+ options: AutocompleteOption[];
37
+ /** Selected value (controlled). null = nothing selected. */
38
+ value?: string | null;
39
+ /** Initial value (uncontrolled). */
40
+ defaultValue?: string | null;
41
+ /** Selection change handler. */
42
+ onValueChange?: (value: string | null) => void;
43
+ /** Called with the input text as it changes. */
44
+ onInputChange?: (text: string) => void;
45
+ /** Field label above the input. */
46
+ label?: string;
47
+ /** Helper or error text below the input. */
48
+ helperText?: string;
49
+ /** Placeholder when empty. */
50
+ placeholder?: string;
51
+ /** Leading icon in the field. */
52
+ leadingIcon?: string | React.ReactNode;
53
+ /** Size variant. */
54
+ size?: AutocompleteSize;
55
+ /** Disables the field. */
56
+ disabled?: boolean;
57
+ /** Error state — danger border + red helper text. */
58
+ error?: boolean;
59
+ /** Show a clear button when there is input. Defaults to true. */
60
+ clearable?: boolean;
61
+ /** Text shown when no option matches. Defaults to "No options". */
62
+ noOptionsText?: string;
63
+ /** Override the default case-insensitive label filter. */
64
+ filterOptions?: (options: AutocompleteOption[], query: string) => AutocompleteOption[];
65
+ /** Style override for the outer container. */
66
+ style?: StyleProp<ViewStyle>;
67
+ /** Accessibility label — falls back to the label prop. */
68
+ accessibilityLabel?: string;
69
+ };
70
+ export declare function Autocomplete({ options, value: controlledValue, defaultValue, onValueChange, onInputChange, label: fieldLabel, helperText, placeholder, leadingIcon, size, disabled, error, clearable, noOptionsText, filterOptions, style, accessibilityLabel, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;