@newtonedev/components 0.1.12 → 0.1.13

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 (149) hide show
  1. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts +3 -2
  2. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts.map +1 -1
  3. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts +1 -1
  4. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts.map +1 -1
  5. package/dist/composites/actions/Button/Button.styles.d.ts +1 -1
  6. package/dist/composites/actions/Button/Button.styles.d.ts.map +1 -1
  7. package/dist/composites/form-controls/Select/Select.d.ts.map +1 -1
  8. package/dist/composites/form-controls/Select/Select.styles.d.ts +2 -2
  9. package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -1
  10. package/dist/composites/form-controls/Select/SelectOption.d.ts.map +1 -1
  11. package/dist/composites/form-controls/TextInput/TextInput.d.ts.map +1 -1
  12. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts +2 -2
  13. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -1
  14. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts +2 -2
  15. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -1
  16. package/dist/composites/layout/AppShell/AppShell.styles.d.ts +2 -2
  17. package/dist/composites/layout/AppShell/AppShell.styles.d.ts.map +1 -1
  18. package/dist/composites/layout/Card/Card.styles.d.ts +2 -2
  19. package/dist/composites/layout/Card/Card.styles.d.ts.map +1 -1
  20. package/dist/composites/layout/Card/Card.types.d.ts +1 -1
  21. package/dist/composites/layout/Card/Card.types.d.ts.map +1 -1
  22. package/dist/composites/layout/Navbar/Navbar.styles.d.ts +3 -2
  23. package/dist/composites/layout/Navbar/Navbar.styles.d.ts.map +1 -1
  24. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts +3 -2
  25. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts.map +1 -1
  26. package/dist/composites/overlays/Popover/Popover.styles.d.ts +2 -2
  27. package/dist/composites/overlays/Popover/Popover.styles.d.ts.map +1 -1
  28. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts +1 -1
  29. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts.map +1 -1
  30. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts +2 -2
  31. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -1
  32. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.types.d.ts +2 -0
  33. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.types.d.ts.map +1 -1
  34. package/dist/composites/range-inputs/HueSlider/HueSlider.d.ts +3 -4
  35. package/dist/composites/range-inputs/HueSlider/HueSlider.d.ts.map +1 -1
  36. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts +4 -4
  37. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -1
  38. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts +2 -2
  39. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -1
  40. package/dist/index.cjs +1232 -1823
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.ts +12 -24
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +1084 -1737
  45. package/dist/index.js.map +1 -1
  46. package/dist/primitives/Frame/Frame.d.ts.map +1 -1
  47. package/dist/primitives/Frame/Frame.styles.d.ts +3 -2
  48. package/dist/primitives/Frame/Frame.styles.d.ts.map +1 -1
  49. package/dist/primitives/Frame/Frame.types.d.ts +1 -1
  50. package/dist/primitives/Frame/Frame.types.d.ts.map +1 -1
  51. package/dist/primitives/Frame/Frame.utils.d.ts +1 -1
  52. package/dist/primitives/Frame/Frame.utils.d.ts.map +1 -1
  53. package/dist/primitives/Icon/Icon.d.ts.map +1 -1
  54. package/dist/primitives/Text/Text.d.ts +1 -1
  55. package/dist/primitives/Text/Text.d.ts.map +1 -1
  56. package/dist/primitives/Text/Text.types.d.ts +1 -1
  57. package/dist/primitives/Text/Text.types.d.ts.map +1 -1
  58. package/dist/primitives/Wrapper/Wrapper.styles.d.ts +1 -1
  59. package/dist/primitives/Wrapper/Wrapper.styles.d.ts.map +1 -1
  60. package/package.json +3 -2
  61. package/src/_COMPONENT_TEMPLATE/ComponentName.styles.ts +4 -4
  62. package/src/_COMPONENT_TEMPLATE/ComponentName.tsx +2 -2
  63. package/src/_COMPONENT_TEMPLATE/ComponentName.types.ts +1 -1
  64. package/src/composites/actions/Button/Button.styles.ts +37 -36
  65. package/src/composites/actions/Button/Button.tsx +1 -1
  66. package/src/composites/form-controls/Select/Select.styles.ts +8 -8
  67. package/src/composites/form-controls/Select/Select.tsx +4 -5
  68. package/src/composites/form-controls/Select/SelectOption.tsx +7 -8
  69. package/src/composites/form-controls/TextInput/TextInput.styles.ts +7 -8
  70. package/src/composites/form-controls/TextInput/TextInput.tsx +3 -4
  71. package/src/composites/form-controls/Toggle/Toggle.styles.ts +6 -6
  72. package/src/composites/form-controls/Toggle/Toggle.tsx +2 -2
  73. package/src/composites/layout/AppShell/AppShell.styles.ts +3 -4
  74. package/src/composites/layout/AppShell/AppShell.tsx +2 -2
  75. package/src/composites/layout/Card/Card.styles.ts +4 -5
  76. package/src/composites/layout/Card/Card.tsx +2 -2
  77. package/src/composites/layout/Card/Card.types.ts +1 -1
  78. package/src/composites/layout/Navbar/Navbar.styles.ts +5 -5
  79. package/src/composites/layout/Navbar/Navbar.tsx +2 -2
  80. package/src/composites/layout/Sidebar/Sidebar.styles.ts +5 -5
  81. package/src/composites/layout/Sidebar/Sidebar.tsx +2 -2
  82. package/src/composites/overlays/Popover/Popover.styles.ts +4 -4
  83. package/src/composites/overlays/Popover/Popover.tsx +2 -2
  84. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.ts +5 -6
  85. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.tsx +6 -3
  86. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.types.ts +2 -0
  87. package/src/composites/range-inputs/HueSlider/HueSlider.styles.ts +14 -21
  88. package/src/composites/range-inputs/HueSlider/HueSlider.tsx +8 -9
  89. package/src/composites/range-inputs/Slider/Slider.styles.ts +9 -10
  90. package/src/composites/range-inputs/Slider/Slider.tsx +2 -2
  91. package/src/index.ts +73 -60
  92. package/src/primitives/Frame/Frame.styles.ts +8 -7
  93. package/src/primitives/Frame/Frame.tsx +9 -9
  94. package/src/primitives/Frame/Frame.types.ts +1 -1
  95. package/src/primitives/Frame/Frame.utils.ts +1 -1
  96. package/src/primitives/Icon/Icon.tsx +2 -3
  97. package/src/primitives/Text/Text.spans.ts +1 -1
  98. package/src/primitives/Text/Text.tsx +16 -16
  99. package/src/primitives/Text/Text.types.ts +1 -1
  100. package/src/primitives/Wrapper/Wrapper.styles.ts +1 -1
  101. package/src/primitives/Wrapper/Wrapper.tsx +1 -1
  102. package/dist/fonts/GoogleFontLoader.d.ts +0 -20
  103. package/dist/fonts/GoogleFontLoader.d.ts.map +0 -1
  104. package/dist/fonts/IconFontLoader.d.ts +0 -13
  105. package/dist/fonts/IconFontLoader.d.ts.map +0 -1
  106. package/dist/fonts/SelfHostedFontLoader.d.ts +0 -14
  107. package/dist/fonts/SelfHostedFontLoader.d.ts.map +0 -1
  108. package/dist/fonts/buildGoogleFontsUrl.d.ts +0 -2
  109. package/dist/fonts/buildGoogleFontsUrl.d.ts.map +0 -1
  110. package/dist/fonts/measureFont.d.ts +0 -19
  111. package/dist/fonts/measureFont.d.ts.map +0 -1
  112. package/dist/fonts/reportQueue.d.ts +0 -7
  113. package/dist/fonts/reportQueue.d.ts.map +0 -1
  114. package/dist/fonts/useLocalCalibration.d.ts +0 -19
  115. package/dist/fonts/useLocalCalibration.d.ts.map +0 -1
  116. package/dist/fonts/useTypographyCalibrations.d.ts +0 -11
  117. package/dist/fonts/useTypographyCalibrations.d.ts.map +0 -1
  118. package/dist/theme/FrameContext.d.ts +0 -26
  119. package/dist/theme/FrameContext.d.ts.map +0 -1
  120. package/dist/theme/NewtoneProvider.d.ts +0 -40
  121. package/dist/theme/NewtoneProvider.d.ts.map +0 -1
  122. package/dist/theme/defaults.d.ts +0 -8
  123. package/dist/theme/defaults.d.ts.map +0 -1
  124. package/dist/theme/types.d.ts +0 -156
  125. package/dist/theme/types.d.ts.map +0 -1
  126. package/dist/theme/useBreakpoint.d.ts +0 -9
  127. package/dist/theme/useBreakpoint.d.ts.map +0 -1
  128. package/dist/tokens/computeTokens.d.ts +0 -151
  129. package/dist/tokens/computeTokens.d.ts.map +0 -1
  130. package/dist/tokens/types.d.ts +0 -162
  131. package/dist/tokens/types.d.ts.map +0 -1
  132. package/dist/tokens/useTokens.d.ts +0 -26
  133. package/dist/tokens/useTokens.d.ts.map +0 -1
  134. package/src/fonts/GoogleFontLoader.tsx +0 -80
  135. package/src/fonts/IconFontLoader.tsx +0 -51
  136. package/src/fonts/SelfHostedFontLoader.tsx +0 -44
  137. package/src/fonts/buildGoogleFontsUrl.ts +0 -2
  138. package/src/fonts/measureFont.ts +0 -55
  139. package/src/fonts/reportQueue.ts +0 -54
  140. package/src/fonts/useLocalCalibration.ts +0 -97
  141. package/src/fonts/useTypographyCalibrations.ts +0 -15
  142. package/src/theme/FrameContext.tsx +0 -31
  143. package/src/theme/NewtoneProvider.tsx +0 -84
  144. package/src/theme/defaults.ts +0 -71
  145. package/src/theme/types.ts +0 -191
  146. package/src/theme/useBreakpoint.ts +0 -14
  147. package/src/tokens/computeTokens.ts +0 -516
  148. package/src/tokens/types.ts +0 -146
  149. package/src/tokens/useTokens.ts +0 -62
package/dist/index.js CHANGED
@@ -1,825 +1,505 @@
1
- import React14, { createContext, useState, useMemo, useEffect, useContext, useCallback, useRef } from 'react';
2
- import { srgbToHex, getColor, DEFAULT_NEUTRAL_SATURATION, DEFAULT_NEUTRAL_HUE, DEFAULT_ACCENT_SATURATION, DEFAULT_ACCENT_HUE, DEFAULT_SUCCESS_SATURATION, DEFAULT_SUCCESS_HUE, DEFAULT_WARNING_SATURATION, DEFAULT_WARNING_HUE, DEFAULT_ERROR_SATURATION, DEFAULT_ERROR_HUE } from 'newtone';
3
- import { SEMANTIC_WEIGHT_MAP, ROLE_DEFAULT_WEIGHTS, BREAKPOINT_ROLE_SCALE, scaleRoleStep, resolveResponsiveSize, estimateLineWidths, REFERENCE_LINE_HEIGHT_RATIO, buildFontFeatureSettings, getBreakpointForWidth, fontConfigToFamily, DEFAULT_ROLE_SCALES, DEFAULT_LINE_HEIGHTS, DEFAULT_FONT_SIZES, DEFAULT_FONT_SLOTS, buildGoogleFontsUrl } from '@newtonedev/fonts';
4
- export { DEFAULT_FONT_SIZES, DEFAULT_LINE_HEIGHTS, DEFAULT_ROLE_SCALES, buildGoogleFontsUrl } from '@newtonedev/fonts';
5
- import { Text, View, useWindowDimensions, Pressable, TextInput as TextInput$1, ScrollView, PanResponder, Animated, StyleSheet } from 'react-native';
1
+ import { useTokens, useNewtoneTheme, useBreakpoint, useTypographyCalibrations, useLocalCalibration, enqueueObservation, useFrameContext, computeTokens, FrameContext } from 'newtone-api';
2
+ export { ACCENT_DEFAULTS, DEFAULT_FONT_SIZES, DEFAULT_LINE_HEIGHTS, DEFAULT_ROLE_SCALES, DEFAULT_THEME_CONFIG, ERROR_DEFAULTS, FrameContext, NEUTRAL_DEFAULTS, NewtoneProvider, SUCCESS_DEFAULTS, WARNING_DEFAULTS, buildGoogleFontsUrl, computeTokens, enqueueObservation, isV2TokenOverrides, measureAvgCharWidth, migrateV1ToV2, useBreakpoint, useFrameContext, useLocalCalibration, useNewtoneTheme, useTokens, useTypographyCalibrations } from 'newtone-api';
3
+ import React13, { createContext, useState, useMemo, useEffect, useContext, useCallback, useRef } from 'react';
4
+ import { Text, View, Pressable, TextInput as TextInput$1, ScrollView, PanResponder, Animated, StyleSheet } from 'react-native';
5
+ import { SEMANTIC_WEIGHT_MAP, ROLE_DEFAULT_WEIGHTS, BREAKPOINT_ROLE_SCALE, scaleRoleStep, resolveResponsiveSize, estimateLineWidths, REFERENCE_LINE_HEIGHT_RATIO, buildFontFeatureSettings } from '@newtonedev/fonts';
6
+ import { srgbToHex, gamutMapToSrgb } from 'newtone';
6
7
 
7
- // src/theme/NewtoneProvider.tsx
8
- var DEFAULT_THEME_CONFIG = {
9
- colorSystem: {
10
- dynamicRange: {
11
- lightest: 1,
12
- darkest: 1
13
- },
14
- palettes: [
15
- { hue: DEFAULT_NEUTRAL_HUE, saturation: DEFAULT_NEUTRAL_SATURATION },
16
- { hue: DEFAULT_ACCENT_HUE, saturation: DEFAULT_ACCENT_SATURATION },
17
- { hue: DEFAULT_SUCCESS_HUE, saturation: DEFAULT_SUCCESS_SATURATION },
18
- { hue: DEFAULT_WARNING_HUE, saturation: DEFAULT_WARNING_SATURATION },
19
- { hue: DEFAULT_ERROR_HUE, saturation: DEFAULT_ERROR_SATURATION }
20
- ]
21
- },
22
- spacing: {
23
- "00": 0,
24
- // base * 0
25
- "02": 2,
26
- // base * 0.25
27
- "04": 4,
28
- // base * 0.5
29
- "06": 6,
30
- // base * 0.75
31
- "08": 8,
32
- // base * 1 (Medium preset, 8px base)
33
- "10": 10,
34
- // base * 1.25
35
- "12": 12,
36
- // base * 1.5
37
- "16": 16,
38
- // base * 2
39
- "20": 20,
40
- // base * 2.5
41
- "24": 24,
42
- // base * 3
43
- "32": 32,
44
- // base * 4
45
- "40": 40,
46
- // base * 5
47
- "48": 48
48
- // base * 6
49
- },
50
- radius: {
51
- none: 0,
52
- sm: 4,
53
- md: 6,
54
- lg: 8,
55
- xl: 12,
56
- pill: 999
57
- },
58
- typography: {
59
- fonts: DEFAULT_FONT_SLOTS,
60
- fontSizes: DEFAULT_FONT_SIZES,
61
- lineHeights: DEFAULT_LINE_HEIGHTS,
62
- roles: DEFAULT_ROLE_SCALES
63
- },
64
- icons: {
65
- variant: "rounded",
66
- // Material Design 3 aesthetic
67
- weight: 400,
68
- // Normal weight
69
- autoGrade: true
70
- // Enable mode-aware grade
71
- }
72
- };
73
-
74
- // src/fonts/GoogleFontLoader.tsx
75
- function GoogleFontLoader({ fonts }) {
76
- const linkRef = useRef(null);
77
- useEffect(() => {
78
- if (typeof document === "undefined") return;
79
- const url = buildGoogleFontsUrl(fonts);
80
- if (linkRef.current) {
81
- linkRef.current.remove();
82
- linkRef.current = null;
83
- }
84
- if (!url) return;
85
- const links = Array.from(document.head.querySelectorAll('link[rel="stylesheet"]'));
86
- if (links.some((el) => el.href === url)) return;
87
- const link = document.createElement("link");
88
- link.rel = "stylesheet";
89
- link.href = url;
90
- document.head.appendChild(link);
91
- linkRef.current = link;
92
- return () => {
93
- if (linkRef.current) {
94
- linkRef.current.remove();
95
- linkRef.current = null;
96
- }
97
- };
98
- }, [
99
- fonts.main.config.family,
100
- fonts.main.config.type,
101
- fonts.main.weights.regular,
102
- fonts.main.weights.medium,
103
- fonts.main.weights.bold,
104
- fonts.display.config.family,
105
- fonts.display.config.type,
106
- fonts.display.weights.regular,
107
- fonts.display.weights.medium,
108
- fonts.display.weights.bold,
109
- fonts.mono.config.family,
110
- fonts.mono.config.type,
111
- fonts.mono.weights.regular,
112
- fonts.mono.weights.medium,
113
- fonts.mono.weights.bold,
114
- fonts.currency.config.family,
115
- fonts.currency.config.type,
116
- fonts.currency.weights.regular,
117
- fonts.currency.weights.medium,
118
- fonts.currency.weights.bold
8
+ // src/index.ts
9
+ var hadKeyboardEvent = false;
10
+ var isListenerSetup = false;
11
+ function setupModality() {
12
+ if (isListenerSetup || typeof document === "undefined") return;
13
+ isListenerSetup = true;
14
+ const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
15
+ "Tab",
16
+ "ArrowUp",
17
+ "ArrowDown",
18
+ "ArrowLeft",
19
+ "ArrowRight",
20
+ "Enter",
21
+ " ",
22
+ "Escape"
119
23
  ]);
120
- return null;
121
- }
122
- function SelfHostedFontLoader({ fontFaceCss }) {
123
- const styleRef = useRef(null);
124
- useEffect(() => {
125
- if (typeof document === "undefined") return;
126
- if (styleRef.current) {
127
- styleRef.current.remove();
128
- styleRef.current = null;
24
+ document.addEventListener("keydown", (e) => {
25
+ if (NAVIGATION_KEYS.has(e.key)) {
26
+ hadKeyboardEvent = true;
129
27
  }
130
- if (!fontFaceCss) return;
131
- const style = document.createElement("style");
132
- style.setAttribute("data-newtone-fonts", "self-hosted");
133
- style.textContent = fontFaceCss;
134
- document.head.appendChild(style);
135
- styleRef.current = style;
136
- return () => {
137
- if (styleRef.current) {
138
- styleRef.current.remove();
139
- styleRef.current = null;
140
- }
141
- };
142
- }, [fontFaceCss]);
143
- return null;
28
+ }, true);
29
+ document.addEventListener("pointerdown", () => {
30
+ hadKeyboardEvent = false;
31
+ }, true);
32
+ document.addEventListener("mousedown", () => {
33
+ hadKeyboardEvent = false;
34
+ }, true);
144
35
  }
145
- function IconFontLoader({ icons }) {
146
- const linkRef = useRef(null);
36
+ function useFocusVisible() {
37
+ const [isFocusVisible, setIsFocusVisible] = useState(false);
147
38
  useEffect(() => {
148
- if (typeof document === "undefined") return;
149
- const variantName = icons.variant.charAt(0).toUpperCase() + icons.variant.slice(1);
150
- const family = `Material+Symbols+${variantName}`;
151
- const url = `https://fonts.googleapis.com/css2?family=${family}:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block`;
152
- if (linkRef.current) {
153
- linkRef.current.remove();
154
- linkRef.current = null;
39
+ setupModality();
40
+ }, []);
41
+ const onFocus = useCallback(() => {
42
+ if (hadKeyboardEvent) {
43
+ setIsFocusVisible(true);
155
44
  }
156
- const links = Array.from(document.head.querySelectorAll('link[rel="stylesheet"]'));
157
- if (links.some((el) => el.href === url)) return;
158
- const link = document.createElement("link");
159
- link.rel = "stylesheet";
160
- link.href = url;
161
- document.head.appendChild(link);
162
- linkRef.current = link;
163
- return () => {
164
- if (linkRef.current) {
165
- linkRef.current.remove();
166
- linkRef.current = null;
167
- }
168
- };
169
- }, [icons.variant]);
170
- return null;
45
+ }, []);
46
+ const onBlur = useCallback(() => {
47
+ setIsFocusVisible(false);
48
+ }, []);
49
+ const focusProps = { onFocus, onBlur };
50
+ return { isFocusVisible, focusProps };
171
51
  }
172
52
 
173
- // src/theme/NewtoneProvider.tsx
174
- var ThemeContext = createContext(null);
175
- function NewtoneProvider({
176
- config = DEFAULT_THEME_CONFIG,
177
- initialMode = "light",
178
- children,
179
- reportingEndpoint,
180
- fontFaceCss
181
- }) {
182
- const [mode, setMode] = useState(initialMode);
183
- const value = useMemo(
184
- () => ({
185
- config,
186
- mode,
187
- setMode,
188
- reportingEndpoint
189
- }),
190
- [config, mode, reportingEndpoint]
191
- );
192
- return /* @__PURE__ */ React14.createElement(ThemeContext.Provider, { value }, fontFaceCss ? /* @__PURE__ */ React14.createElement(SelfHostedFontLoader, { fontFaceCss }) : /* @__PURE__ */ React14.createElement(GoogleFontLoader, { fonts: config.typography.fonts }), /* @__PURE__ */ React14.createElement(IconFontLoader, { icons: config.icons }), children);
53
+ // src/primitives/Frame/Frame.utils.ts
54
+ function resolveSpacing(value, tokens) {
55
+ if (typeof value === "number") return value;
56
+ return tokens.spacing[value];
193
57
  }
194
- function useNewtoneTheme() {
195
- const context = useContext(ThemeContext);
196
- if (!context) {
197
- throw new Error("useNewtoneTheme must be used within NewtoneProvider");
198
- }
199
- return context;
200
- }
201
- var FrameContext = createContext(null);
202
- function useFrameContext() {
203
- return useContext(FrameContext);
204
- }
205
- var NEUTRAL_DEFAULTS = {
206
- light: {
207
- background: { elevated: 0, ground: 0.03, sunken: 0.06 },
208
- text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
209
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
210
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
211
- },
212
- dark: {
213
- background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
214
- text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
215
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
216
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
217
- }
218
- };
219
- var ACCENT_DEFAULTS = {
220
- light: {
221
- background: { elevated: 0, ground: 0.03, sunken: 0.06 },
222
- text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
223
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
224
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
225
- },
226
- dark: {
227
- background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
228
- text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
229
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
230
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
231
- }
232
- };
233
- var SUCCESS_DEFAULTS = {
234
- light: {
235
- background: { elevated: 0, ground: 0.03, sunken: 0.06 },
236
- text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
237
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
238
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
239
- },
240
- dark: {
241
- background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
242
- text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
243
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
244
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
245
- }
246
- };
247
- var WARNING_DEFAULTS = {
248
- light: {
249
- background: { elevated: 0, ground: 0.03, sunken: 0.06 },
250
- text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
251
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
252
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
253
- },
254
- dark: {
255
- background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
256
- text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
257
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
258
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
58
+ function resolvePadding(prop, tokens) {
59
+ if (typeof prop === "string" || typeof prop === "number") {
60
+ const px = resolveSpacing(prop, tokens);
61
+ return { top: px, right: px, bottom: px, left: px };
259
62
  }
260
- };
261
- var ERROR_DEFAULTS = {
262
- light: {
263
- background: { elevated: 0, ground: 0.03, sunken: 0.06 },
264
- text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
265
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
266
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
267
- },
268
- dark: {
269
- background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
270
- text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
271
- action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
272
- border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
63
+ if ("x" in prop || "y" in prop) {
64
+ const axes = prop;
65
+ const x = axes.x !== void 0 ? resolveSpacing(axes.x, tokens) : 0;
66
+ const y = axes.y !== void 0 ? resolveSpacing(axes.y, tokens) : 0;
67
+ return { top: y, right: x, bottom: y, left: x };
273
68
  }
274
- };
275
- var clamp = (n) => Math.max(0, Math.min(1, n));
276
- function computePaletteTokens(palette, defaults, mode, elevation, dynamicRange, elevationDelta, effectiveTextMode, autoAccentNv, neutralTextPrimary, neutralBgElevated) {
277
- const modeDefaults = defaults[mode];
278
- const toEngineNv = (nv) => mode === "light" ? 1 - nv : nv;
279
- const textToEngineNv = (nv) => effectiveTextMode === "light" ? 1 - nv : nv;
280
- const colorAt = (engineNv) => getColor(
281
- palette.hue,
282
- palette.saturation,
283
- dynamicRange,
284
- clamp(engineNv),
285
- palette.desaturation,
286
- palette.paletteHueGrading
287
- );
288
- const resolveKeyNv = (p) => mode === "dark" ? p.keyNormalizedValueDark : p.keyNormalizedValue;
289
- const keyNv = resolveKeyNv(palette);
290
- const fillBaseNv = keyNv ?? autoAccentNv;
291
- const fillNv = clamp(fillBaseNv + elevationDelta);
292
- const fill = colorAt(fillNv);
293
- const hoverDir = effectiveTextMode === "light" ? -modeDefaults.action.hovered : modeDefaults.action.hovered;
294
- const activeDir = effectiveTextMode === "light" ? -modeDefaults.action.pressed : modeDefaults.action.pressed;
295
- const fillHover = colorAt(clamp(fillNv + hoverDir));
296
- const fillActive = colorAt(clamp(fillNv + activeDir));
297
- const onFill = fill.oklch.L > 0.6 ? neutralTextPrimary : neutralBgElevated;
298
- const bgNormalized = elevation === 2 ? modeDefaults.background.elevated : elevation === 1 ? modeDefaults.background.ground : modeDefaults.background.sunken;
299
- const bgNv = clamp(toEngineNv(bgNormalized));
300
- const background = colorAt(bgNv);
301
- const backgroundElevated = colorAt(clamp(toEngineNv(modeDefaults.background.elevated)));
302
- const backgroundSunken = colorAt(clamp(toEngineNv(modeDefaults.background.sunken)));
303
- const interactiveOffset = modeDefaults.action.enabled;
304
- const interactiveNv = clamp(bgNv + (effectiveTextMode === "light" ? -interactiveOffset : interactiveOffset));
305
- const backgroundInteractive = colorAt(interactiveNv);
306
- const hoverShift = modeDefaults.action.hovered;
307
- const activeShift = modeDefaults.action.pressed;
308
- const backgroundInteractiveHover = colorAt(clamp(interactiveNv + (effectiveTextMode === "light" ? -hoverShift : hoverShift)));
309
- const backgroundInteractiveActive = colorAt(clamp(interactiveNv + (effectiveTextMode === "light" ? -activeShift : activeShift)));
310
- const textPrimary = colorAt(clamp(textToEngineNv(modeDefaults.text.primary) + elevationDelta));
311
- const textSecondary = colorAt(clamp(textToEngineNv(modeDefaults.text.secondary) + elevationDelta));
312
- const textTertiary = colorAt(clamp(textToEngineNv(modeDefaults.text.tertiary) + elevationDelta));
313
- const textDisabled = colorAt(clamp(textToEngineNv(modeDefaults.text.disabled) + elevationDelta));
314
- const borderOffset = modeDefaults.border.enabled;
315
- const borderNv = effectiveTextMode === "light" ? bgNv - borderOffset : bgNv + borderOffset;
316
- const border = colorAt(clamp(borderNv));
69
+ const sides = prop;
317
70
  return {
318
- fill,
319
- fillHover,
320
- fillActive,
321
- onFill,
322
- background,
323
- backgroundElevated,
324
- backgroundSunken,
325
- backgroundInteractive,
326
- backgroundInteractiveHover,
327
- backgroundInteractiveActive,
328
- textPrimary,
329
- textSecondary,
330
- textTertiary,
331
- textDisabled,
332
- border
71
+ top: sides.top !== void 0 ? resolveSpacing(sides.top, tokens) : 0,
72
+ right: sides.right !== void 0 ? resolveSpacing(sides.right, tokens) : 0,
73
+ bottom: sides.bottom !== void 0 ? resolveSpacing(sides.bottom, tokens) : 0,
74
+ left: sides.left !== void 0 ? resolveSpacing(sides.left, tokens) : 0
333
75
  };
334
76
  }
335
- function computeTokens(config, mode, elevation, spacing, radius, typography, icons, tokenOverrides) {
336
- const { dynamicRange, palettes } = config;
337
- const palette = palettes[0];
338
- if (!palette) {
339
- throw new Error("Neutral palette (index 0) not found");
340
- }
341
- const neutralDefaults = NEUTRAL_DEFAULTS[mode];
342
- const toEngineNv = (nv) => mode === "light" ? 1 - nv : nv;
343
- const bgElevatedNorm = mode === "light" ? tokenOverrides?.backgroundElevated : tokenOverrides?.backgroundElevatedDark;
344
- const bgDefaultNorm = mode === "light" ? tokenOverrides?.backgroundDefault : tokenOverrides?.backgroundDefaultDark;
345
- const bgSunkenNorm = mode === "light" ? tokenOverrides?.backgroundSunken : tokenOverrides?.backgroundSunkenDark;
346
- const textPrimaryNorm = mode === "light" ? tokenOverrides?.textPrimaryNormalized : tokenOverrides?.textPrimaryNormalizedDark;
347
- const textSecondaryNorm = mode === "light" ? tokenOverrides?.textSecondaryNormalized : tokenOverrides?.textSecondaryNormalizedDark;
348
- const textTertiaryNorm = mode === "light" ? tokenOverrides?.textTertiaryNormalized : tokenOverrides?.textTertiaryNormalizedDark;
349
- const textDisabledNorm = mode === "light" ? tokenOverrides?.textDisabledNormalized : tokenOverrides?.textDisabledNormalizedDark;
350
- const bgNormalized = elevation === 2 ? bgElevatedNorm ?? neutralDefaults.background.elevated : elevation === 1 ? bgDefaultNorm ?? neutralDefaults.background.ground : bgSunkenNorm ?? neutralDefaults.background.sunken;
351
- const backgroundNv = clamp(toEngineNv(bgNormalized));
352
- const elevatedNv = clamp(toEngineNv(bgElevatedNorm ?? neutralDefaults.background.elevated));
353
- const sunkenNv = clamp(toEngineNv(bgSunkenNorm ?? neutralDefaults.background.sunken));
354
- const elevationDelta = backgroundNv - elevatedNv;
355
- const effectiveTextMode = backgroundNv >= 0.5 ? "light" : "dark";
356
- const background = getColor(
357
- palette.hue,
358
- palette.saturation,
359
- dynamicRange,
360
- backgroundNv,
361
- palette.desaturation,
362
- palette.paletteHueGrading
363
- );
364
- const backgroundElevated = getColor(
365
- palette.hue,
366
- palette.saturation,
367
- dynamicRange,
368
- elevatedNv,
369
- palette.desaturation,
370
- palette.paletteHueGrading
371
- );
372
- const backgroundSunken = getColor(
373
- palette.hue,
374
- palette.saturation,
375
- dynamicRange,
376
- sunkenNv,
377
- palette.desaturation,
378
- palette.paletteHueGrading
379
- );
380
- const INTERACTIVE_COMPONENT_OFFSET = mode === "light" ? tokenOverrides?.interactiveComponentOffset ?? neutralDefaults.action.enabled : tokenOverrides?.interactiveComponentOffsetDark ?? neutralDefaults.action.enabled;
381
- const HOVER_SHIFT = mode === "light" ? tokenOverrides?.hoverShift ?? neutralDefaults.action.hovered : tokenOverrides?.hoverShiftDark ?? neutralDefaults.action.hovered;
382
- const ACTIVE_SHIFT = mode === "light" ? tokenOverrides?.activeShift ?? neutralDefaults.action.pressed : tokenOverrides?.activeShiftDark ?? neutralDefaults.action.pressed;
383
- const BORDER_OFFSET = mode === "light" ? tokenOverrides?.borderOffset ?? neutralDefaults.border.enabled : tokenOverrides?.borderOffsetDark ?? neutralDefaults.border.enabled;
384
- const interactiveComponentNv = clamp(backgroundNv + (effectiveTextMode === "light" ? -INTERACTIVE_COMPONENT_OFFSET : INTERACTIVE_COMPONENT_OFFSET));
385
- const backgroundInteractive = getColor(
386
- palette.hue,
387
- palette.saturation,
388
- dynamicRange,
389
- interactiveComponentNv,
390
- palette.desaturation,
391
- palette.paletteHueGrading
392
- );
393
- const neutralHoverNv = clamp(interactiveComponentNv + (effectiveTextMode === "light" ? -HOVER_SHIFT : HOVER_SHIFT));
394
- const backgroundInteractiveHover = getColor(
395
- palette.hue,
396
- palette.saturation,
397
- dynamicRange,
398
- neutralHoverNv,
399
- palette.desaturation,
400
- palette.paletteHueGrading
401
- );
402
- const neutralActiveNv = clamp(interactiveComponentNv + (effectiveTextMode === "light" ? -ACTIVE_SHIFT : ACTIVE_SHIFT));
403
- const backgroundInteractiveActive = getColor(
404
- palette.hue,
405
- palette.saturation,
406
- dynamicRange,
407
- neutralActiveNv,
408
- palette.desaturation,
409
- palette.paletteHueGrading
410
- );
411
- const textToEngineNv = (nv) => effectiveTextMode === "light" ? 1 - nv : nv;
412
- const textPrimary = getColor(
413
- palette.hue,
414
- palette.saturation,
415
- dynamicRange,
416
- clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary) + elevationDelta),
417
- palette.desaturation,
418
- palette.paletteHueGrading
419
- );
420
- const textSecondary = getColor(
421
- palette.hue,
422
- palette.saturation,
423
- dynamicRange,
424
- clamp(textToEngineNv(textSecondaryNorm ?? neutralDefaults.text.secondary) + elevationDelta),
425
- palette.desaturation,
426
- palette.paletteHueGrading
427
- );
428
- const textTertiary = getColor(
429
- palette.hue,
430
- palette.saturation,
431
- dynamicRange,
432
- clamp(textToEngineNv(textTertiaryNorm ?? neutralDefaults.text.tertiary) + elevationDelta),
433
- palette.desaturation,
434
- palette.paletteHueGrading
435
- );
436
- const textDisabled = getColor(
437
- palette.hue,
438
- palette.saturation,
439
- dynamicRange,
440
- clamp(textToEngineNv(textDisabledNorm ?? neutralDefaults.text.disabled) + elevationDelta),
441
- palette.desaturation,
442
- palette.paletteHueGrading
443
- );
444
- const borderNv = effectiveTextMode === "light" ? backgroundNv - BORDER_OFFSET : backgroundNv + BORDER_OFFSET;
445
- const border = getColor(
446
- palette.hue,
447
- palette.saturation,
448
- dynamicRange,
449
- clamp(borderNv),
450
- palette.desaturation,
451
- palette.paletteHueGrading
452
- );
453
- const autoAccentNv = clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary));
454
- const accentPalette = palettes[1];
455
- if (!accentPalette) {
456
- throw new Error("Accent palette (index 1) not found");
77
+ function resolveGap(prop, tokens) {
78
+ if (typeof prop === "string" || typeof prop === "number") {
79
+ const px = resolveSpacing(prop, tokens);
80
+ return { rowGap: px, columnGap: px };
457
81
  }
458
- const accent = computePaletteTokens(
459
- accentPalette,
460
- ACCENT_DEFAULTS,
461
- mode,
462
- elevation,
463
- dynamicRange,
464
- elevationDelta,
465
- effectiveTextMode,
466
- autoAccentNv,
467
- textPrimary,
468
- backgroundElevated
469
- );
470
- const successPalette = palettes[2];
471
- const warningPalette = palettes[3];
472
- const errorPalette = palettes[4];
473
- const success = successPalette ? computePaletteTokens(
474
- successPalette,
475
- SUCCESS_DEFAULTS,
476
- mode,
477
- elevation,
478
- dynamicRange,
479
- elevationDelta,
480
- effectiveTextMode,
481
- autoAccentNv,
482
- textPrimary,
483
- backgroundElevated
484
- ) : accent;
485
- const warning = warningPalette ? computePaletteTokens(
486
- warningPalette,
487
- WARNING_DEFAULTS,
488
- mode,
489
- elevation,
490
- dynamicRange,
491
- elevationDelta,
492
- effectiveTextMode,
493
- autoAccentNv,
494
- textPrimary,
495
- backgroundElevated
496
- ) : accent;
497
- const error = errorPalette ? computePaletteTokens(
498
- errorPalette,
499
- ERROR_DEFAULTS,
500
- mode,
501
- elevation,
502
- dynamicRange,
503
- elevationDelta,
504
- effectiveTextMode,
505
- autoAccentNv,
506
- textPrimary,
507
- backgroundElevated
508
- ) : accent;
509
82
  return {
510
- background,
511
- backgroundElevated,
512
- backgroundSunken,
513
- backgroundInteractive,
514
- backgroundInteractiveHover,
515
- backgroundInteractiveActive,
516
- textPrimary,
517
- textSecondary,
518
- textTertiary,
519
- textDisabled,
520
- border,
521
- accent,
522
- success,
523
- warning,
524
- error,
525
- spacing,
526
- radius,
527
- typography: {
528
- fonts: {
529
- main: {
530
- family: fontConfigToFamily(typography.fonts.main.config),
531
- weights: typography.fonts.main.weights
532
- },
533
- display: {
534
- family: fontConfigToFamily(typography.fonts.display.config),
535
- weights: typography.fonts.display.weights
536
- },
537
- mono: {
538
- family: fontConfigToFamily(typography.fonts.mono.config),
539
- weights: typography.fonts.mono.weights
540
- },
541
- currency: {
542
- family: fontConfigToFamily(typography.fonts.currency.config),
543
- weights: typography.fonts.currency.weights
544
- }
545
- },
546
- fontSizes: typography.fontSizes,
547
- lineHeights: typography.lineHeights
548
- },
549
- icons: {
550
- variant: icons.variant,
551
- weight: icons.weight,
552
- grade: icons.autoGrade ? mode === "light" ? -25 : 200 : 0
553
- }
83
+ rowGap: prop.row !== void 0 ? resolveSpacing(prop.row, tokens) : 0,
84
+ columnGap: prop.column !== void 0 ? resolveSpacing(prop.column, tokens) : 0
554
85
  };
555
86
  }
556
-
557
- // src/tokens/useTokens.ts
558
- function useTokens(elevation) {
559
- const { config, mode } = useNewtoneTheme();
560
- const frameCtx = useFrameContext();
561
- const resolvedElevation = elevation ?? frameCtx?.elevation ?? 1;
562
- const canReuse = frameCtx !== null && elevation === void 0 && frameCtx.elevation === resolvedElevation;
563
- return useMemo(() => {
564
- if (canReuse) {
565
- return { ...frameCtx.tokens, elevation: resolvedElevation };
566
- }
567
- const tokens = computeTokens(
568
- config.colorSystem,
569
- mode,
570
- resolvedElevation,
571
- config.spacing,
572
- config.radius,
573
- config.typography,
574
- config.icons,
575
- config.tokenOverrides
576
- );
577
- return { ...tokens, elevation: resolvedElevation };
578
- }, [config, mode, resolvedElevation, canReuse, frameCtx?.tokens]);
87
+ function resolveRadius(value, tokens) {
88
+ if (typeof value === "number") return value;
89
+ return tokens.radius[value];
579
90
  }
580
- function computeButtonPadding(size, hasIcon, hasText, iconPosition) {
581
- const basePadding = {
582
- sm: 8,
583
- md: 12,
584
- lg: 16
585
- };
586
- const base = basePadding[size];
587
- const textExtra = 8;
588
- if (!hasText && hasIcon) {
589
- return {
590
- paddingLeft: base,
591
- paddingRight: base,
592
- paddingTop: base,
593
- paddingBottom: base
594
- };
595
- }
596
- if (hasText && !hasIcon) {
597
- return {
598
- paddingLeft: base + textExtra,
599
- paddingRight: base + textExtra,
600
- paddingTop: base,
601
- paddingBottom: base
602
- };
603
- }
604
- if (hasText && hasIcon) {
605
- if (iconPosition === "left") {
606
- return {
607
- paddingLeft: base,
608
- paddingRight: base + textExtra,
609
- paddingTop: base,
610
- paddingBottom: base
611
- };
612
- } else {
613
- return {
614
- paddingLeft: base + textExtra,
615
- paddingRight: base,
616
- paddingTop: base,
617
- paddingBottom: base
618
- };
619
- }
91
+ function resolveRadiusCorners(prop, tokens) {
92
+ if (typeof prop === "string" || typeof prop === "number") {
93
+ const px = resolveRadius(prop, tokens);
94
+ return { topLeft: px, topRight: px, bottomLeft: px, bottomRight: px };
620
95
  }
621
96
  return {
622
- paddingLeft: base,
623
- paddingRight: base,
624
- paddingTop: base,
625
- paddingBottom: base
97
+ topLeft: prop.topLeft !== void 0 ? resolveRadius(prop.topLeft, tokens) : 0,
98
+ topRight: prop.topRight !== void 0 ? resolveRadius(prop.topRight, tokens) : 0,
99
+ bottomLeft: prop.bottomLeft !== void 0 ? resolveRadius(prop.bottomLeft, tokens) : 0,
100
+ bottomRight: prop.bottomRight !== void 0 ? resolveRadius(prop.bottomRight, tokens) : 0
626
101
  };
627
102
  }
628
- function getPaletteTokens(semantic, tokens) {
629
- switch (semantic) {
630
- case "accent":
631
- return tokens.accent;
632
- case "success":
633
- return tokens.success;
634
- case "error":
635
- return tokens.error;
636
- case "warning":
637
- return tokens.warning;
638
- default:
639
- return void 0;
640
- }
103
+ function hasPositiveRadius(corners) {
104
+ return corners.topLeft > 0 || corners.topRight > 0 || corners.bottomLeft > 0 || corners.bottomRight > 0;
641
105
  }
642
- function getButtonConfig(variant, semantic, size, disabled, tokens) {
643
- const sizeConfig = getSizeConfig(size, tokens);
644
- const variantColors = getVariantColors(variant, semantic, disabled, tokens);
645
- return {
646
- variantColors,
647
- sizeTokens: {
648
- padding: sizeConfig.padding,
649
- gap: sizeConfig.gap,
650
- borderRadius: sizeConfig.borderRadius,
651
- textSize: sizeConfig.textSize,
652
- iconSize: sizeConfig.iconSize
106
+ function resolveSizing(width, height) {
107
+ const style = {};
108
+ if (width !== void 0) {
109
+ if (width === "fill") {
110
+ style.flexGrow = 1;
111
+ style.width = "100%";
112
+ } else if (typeof width === "number") {
113
+ style.width = width;
653
114
  }
654
- };
115
+ }
116
+ if (height !== void 0) {
117
+ if (height === "fill") {
118
+ style.flexGrow = 1;
119
+ style.height = "100%";
120
+ } else if (typeof height === "number") {
121
+ style.height = height;
122
+ }
123
+ }
124
+ return style;
655
125
  }
656
- function getSizeConfig(size, tokens) {
657
- const configs = {
658
- sm: {
659
- padding: 8,
660
- gap: tokens.spacing["08"],
661
- borderRadius: 8,
662
- textSize: "md",
663
- // 16px
664
- iconSize: 24
665
- },
666
- md: {
667
- padding: 12,
668
- gap: tokens.spacing["08"],
669
- borderRadius: 12,
670
- textSize: "md",
671
- // 16px
672
- iconSize: 24
673
- },
674
- lg: {
675
- padding: 16,
676
- gap: tokens.spacing["08"],
677
- borderRadius: 16,
678
- textSize: "md",
679
- // 16px
680
- iconSize: 24
681
- }
682
- };
683
- return configs[size];
126
+ var ALIGN_MAP = {
127
+ start: "flex-start",
128
+ center: "center",
129
+ end: "flex-end",
130
+ stretch: "stretch",
131
+ baseline: "baseline"
132
+ };
133
+ var JUSTIFY_MAP = {
134
+ start: "flex-start",
135
+ center: "center",
136
+ end: "flex-end",
137
+ between: "space-between",
138
+ around: "space-around",
139
+ evenly: "space-evenly"
140
+ };
141
+ function resolveAlignment(align) {
142
+ return ALIGN_MAP[align];
684
143
  }
685
- function getVariantColors(variant, semantic, disabled, tokens) {
686
- if (disabled) {
687
- const baseColors = getVariantColorsForState(variant, semantic, tokens);
688
- const disabledBg = srgbToHex(tokens.backgroundSunken.srgb);
689
- return {
690
- ...baseColors,
691
- bg: disabledBg,
692
- hoveredBg: disabledBg,
693
- pressedBg: disabledBg,
694
- textColor: srgbToHex(tokens.textSecondary.srgb),
695
- iconColor: srgbToHex(tokens.textSecondary.srgb)
696
- };
144
+ function resolveJustification(justify) {
145
+ return JUSTIFY_MAP[justify];
146
+ }
147
+ function resolveFlexDirection(direction, reverse) {
148
+ if (direction === "horizontal") {
149
+ return reverse ? "row-reverse" : "row";
697
150
  }
698
- return getVariantColorsForState(variant, semantic, tokens);
151
+ return reverse ? "column-reverse" : "column";
699
152
  }
700
- function getVariantColorsForState(variant, semantic, tokens) {
701
- const paletteTokens = getPaletteTokens(semantic, tokens);
702
- if (variant === "primary") {
703
- if (semantic === "neutral") {
704
- return {
705
- bg: srgbToHex(tokens.backgroundInteractive.srgb),
706
- hoveredBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
707
- pressedBg: srgbToHex(tokens.backgroundInteractiveActive.srgb),
708
- textColor: srgbToHex(tokens.textPrimary.srgb),
709
- iconColor: srgbToHex(tokens.textPrimary.srgb),
710
- borderWidth: 1,
711
- borderColor: "transparent"
712
- };
713
- }
714
- return {
715
- bg: srgbToHex(paletteTokens.fill.srgb),
716
- hoveredBg: srgbToHex(paletteTokens.fillHover.srgb),
717
- pressedBg: srgbToHex(paletteTokens.fillActive.srgb),
718
- textColor: srgbToHex(paletteTokens.onFill.srgb),
719
- iconColor: srgbToHex(paletteTokens.onFill.srgb),
720
- borderWidth: 1,
721
- borderColor: "transparent"
722
- };
153
+
154
+ // src/primitives/Frame/Frame.styles.ts
155
+ function getFrameStyles(input) {
156
+ const {
157
+ tokens,
158
+ gamut,
159
+ frameElevation,
160
+ layout = "flex",
161
+ direction = "vertical",
162
+ wrap = false,
163
+ reverse = false,
164
+ columns,
165
+ rows,
166
+ align,
167
+ justify,
168
+ padding,
169
+ gap,
170
+ width,
171
+ height,
172
+ minWidth,
173
+ maxWidth,
174
+ minHeight,
175
+ maxHeight,
176
+ radius,
177
+ bordered = false,
178
+ disabled = false
179
+ } = input;
180
+ const container = {};
181
+ container.backgroundColor = tokens.background[gamut];
182
+ container.color = tokens.textPrimary[gamut];
183
+ if (layout === "flex") {
184
+ container.display = "flex";
185
+ container.flexDirection = resolveFlexDirection(direction, reverse);
186
+ if (wrap) container.flexWrap = "wrap";
723
187
  }
724
- if (variant === "secondary") {
725
- if (semantic === "neutral") {
726
- return {
727
- bg: "transparent",
728
- hoveredBg: srgbToHex(tokens.backgroundInteractive.srgb),
729
- pressedBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
730
- textColor: srgbToHex(tokens.textPrimary.srgb),
731
- iconColor: srgbToHex(tokens.textPrimary.srgb),
732
- borderWidth: 1,
733
- borderColor: srgbToHex(tokens.border.srgb)
734
- };
735
- }
736
- return {
737
- bg: srgbToHex(paletteTokens.background.srgb),
738
- hoveredBg: srgbToHex(paletteTokens.backgroundInteractive.srgb),
739
- pressedBg: srgbToHex(paletteTokens.backgroundInteractiveHover.srgb),
740
- textColor: srgbToHex(paletteTokens.fill.srgb),
741
- iconColor: srgbToHex(paletteTokens.fill.srgb),
742
- borderWidth: 1,
743
- borderColor: "transparent"
744
- };
188
+ if (layout === "grid") {
189
+ container.display = "flex";
190
+ container.flexDirection = "row";
191
+ container.flexWrap = "wrap";
745
192
  }
746
- if (variant === "tertiary") {
747
- if (semantic === "neutral") {
748
- return {
749
- bg: "transparent",
750
- hoveredBg: srgbToHex(tokens.backgroundInteractive.srgb),
751
- pressedBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
752
- textColor: srgbToHex(tokens.textPrimary.srgb),
753
- iconColor: srgbToHex(tokens.textPrimary.srgb),
754
- borderWidth: 1,
755
- borderColor: "transparent"
756
- };
193
+ if (align) container.alignItems = resolveAlignment(align);
194
+ if (justify) container.justifyContent = resolveJustification(justify);
195
+ if (padding !== void 0) {
196
+ const p = resolvePadding(padding, tokens);
197
+ container.paddingTop = p.top;
198
+ container.paddingRight = p.right;
199
+ container.paddingBottom = p.bottom;
200
+ container.paddingLeft = p.left;
201
+ }
202
+ if (gap !== void 0) {
203
+ const g = resolveGap(gap, tokens);
204
+ container.rowGap = g.rowGap;
205
+ container.columnGap = g.columnGap;
206
+ }
207
+ const sizing = resolveSizing(width, height);
208
+ Object.assign(container, sizing);
209
+ if (minWidth !== void 0) container.minWidth = minWidth;
210
+ if (maxWidth !== void 0) container.maxWidth = maxWidth;
211
+ if (minHeight !== void 0) container.minHeight = minHeight;
212
+ if (maxHeight !== void 0) container.maxHeight = maxHeight;
213
+ if (radius !== void 0) {
214
+ const corners = resolveRadiusCorners(radius, tokens);
215
+ container.borderTopLeftRadius = corners.topLeft;
216
+ container.borderTopRightRadius = corners.topRight;
217
+ container.borderBottomLeftRadius = corners.bottomLeft;
218
+ container.borderBottomRightRadius = corners.bottomRight;
219
+ if (hasPositiveRadius(corners)) {
220
+ container.overflow = "hidden";
757
221
  }
758
- return {
759
- bg: "transparent",
760
- hoveredBg: srgbToHex(paletteTokens.background.srgb),
761
- pressedBg: srgbToHex(paletteTokens.backgroundInteractive.srgb),
762
- textColor: srgbToHex(paletteTokens.fill.srgb),
763
- iconColor: srgbToHex(paletteTokens.fill.srgb),
764
- borderWidth: 1,
765
- borderColor: "transparent"
222
+ }
223
+ if (bordered) {
224
+ container.borderWidth = 1;
225
+ container.borderColor = tokens.border[gamut];
226
+ }
227
+ if (frameElevation === 2) {
228
+ container.shadowColor = "#000";
229
+ container.shadowOffset = { width: 0, height: 2 };
230
+ container.shadowOpacity = 0.12;
231
+ container.shadowRadius = 6;
232
+ container.elevation = 4;
233
+ }
234
+ if (disabled) {
235
+ container.opacity = 0.5;
236
+ }
237
+ const pressed = StyleSheet.create({
238
+ s: { backgroundColor: tokens.backgroundSunken[gamut] }
239
+ }).s;
240
+ let gridWebStyle = null;
241
+ if (layout === "grid") {
242
+ gridWebStyle = {
243
+ display: "grid",
244
+ // Divide into equal-width columns (e.g. 3 columns → "repeat(3, 1fr)").
245
+ gridTemplateColumns: columns ? `repeat(${columns}, 1fr)` : void 0,
246
+ gridTemplateRows: rows ? `repeat(${rows}, 1fr)` : void 0
766
247
  };
767
248
  }
249
+ const insetBoxShadow = frameElevation === -2 ? "inset 0 2px 4px rgba(0,0,0,0.12)" : null;
768
250
  return {
769
- bg: "transparent",
770
- hoveredBg: "transparent",
771
- pressedBg: "transparent",
772
- textColor: srgbToHex(tokens.textPrimary.srgb),
773
- iconColor: srgbToHex(tokens.textPrimary.srgb),
774
- borderWidth: 0
251
+ // Validate and optimize the container styles through StyleSheet.create(),
252
+ // then extract the single style object with `.c`.
253
+ container: StyleSheet.create({ c: container }).c,
254
+ pressed,
255
+ gridWebStyle,
256
+ insetBoxShadow
775
257
  };
776
258
  }
777
- function Icon({
778
- name,
779
- size,
780
- opticalSize,
781
- fill = 0,
782
- color,
783
- style,
259
+
260
+ // src/primitives/Frame/Frame.tsx
261
+ function wrapTextChildren(children, textStyle) {
262
+ return React13.Children.map(children, (child) => {
263
+ if (typeof child === "string" || typeof child === "number") {
264
+ return /* @__PURE__ */ React13.createElement(Text, { style: textStyle }, child);
265
+ }
266
+ return child;
267
+ });
268
+ }
269
+ function toElevationLevel(frameElevation) {
270
+ if (frameElevation <= -1) return 0;
271
+ if (frameElevation === 0) return 1;
272
+ return 2;
273
+ }
274
+ function Frame({
275
+ children,
276
+ // Elevation
277
+ elevation,
278
+ // Layout
279
+ layout,
280
+ direction,
281
+ wrap,
282
+ reverse,
283
+ columns,
284
+ rows,
285
+ // Alignment
286
+ align,
287
+ justify,
288
+ // Spacing
289
+ padding,
290
+ gap,
291
+ // Sizing
292
+ width,
293
+ height,
294
+ minWidth,
295
+ maxWidth,
296
+ minHeight,
297
+ maxHeight,
298
+ // Appearance
299
+ radius,
300
+ bordered,
301
+ // Interactivity
302
+ onPress,
303
+ href,
304
+ disabled = false,
784
305
  // Accessibility
785
306
  accessibilityLabel,
307
+ accessibilityHint,
786
308
  // Testing & platform
787
309
  testID,
788
310
  nativeID,
789
- ref
311
+ ref,
312
+ // Style override
313
+ style
790
314
  }) {
791
- const tokens = useTokens();
792
- const iconStyle = useMemo(() => {
793
- const fontSize = size ?? tokens.typography.fontSizes["05"];
794
- const getOpticalSize = (size2) => {
795
- if (size2 <= 22) return 20;
796
- if (size2 <= 32) return 24;
797
- if (size2 <= 44) return 40;
798
- return 48;
799
- };
800
- const opsz = opticalSize ?? getOpticalSize(fontSize);
801
- const iconColor = color ?? srgbToHex(tokens.textPrimary.srgb);
802
- const fontFamily = `Material Symbols ${tokens.icons.variant.charAt(0).toUpperCase() + tokens.icons.variant.slice(1)}`;
803
- const fillValue = typeof fill === "boolean" ? fill ? 1 : 0 : fill;
804
- const fontVariationSettings = `'FILL' ${fillValue}, 'wght' ${tokens.icons.weight}, 'GRAD' ${tokens.icons.grade}, 'opsz' ${opsz}`;
805
- return {
806
- fontFamily,
807
- fontSize,
808
- width: fontSize,
809
- // Explicit width ensures square rendering
810
- height: fontSize,
811
- // Explicit height ensures square rendering
812
- lineHeight: fontSize,
813
- // Prevent text line-height from affecting total height
814
- color: iconColor,
815
- userSelect: "none",
315
+ const { config, mode, gamut } = useNewtoneTheme();
316
+ const parentFrameCtx = useFrameContext();
317
+ const resolvedFrameElevation = elevation ?? 0;
318
+ const resolvedElevation = elevation !== void 0 ? toElevationLevel(elevation) : parentFrameCtx?.elevation ?? 1;
319
+ const tokens = useMemo(() => {
320
+ return computeTokens(
321
+ config.colorSystem,
322
+ mode,
323
+ resolvedElevation,
324
+ config.spacing,
325
+ config.radius,
326
+ config.typography,
327
+ config.icons,
328
+ config.tokenOverrides
329
+ );
330
+ }, [config, mode, resolvedElevation]);
331
+ const styles = useMemo(
332
+ () => getFrameStyles({
333
+ tokens,
334
+ gamut,
335
+ frameElevation: resolvedFrameElevation,
336
+ layout,
337
+ direction,
338
+ wrap,
339
+ reverse,
340
+ columns,
341
+ rows,
342
+ align,
343
+ justify,
344
+ padding,
345
+ gap,
346
+ width,
347
+ height,
348
+ minWidth,
349
+ maxWidth,
350
+ minHeight,
351
+ maxHeight,
352
+ radius,
353
+ bordered,
354
+ disabled
355
+ }),
356
+ [
357
+ tokens,
358
+ gamut,
359
+ resolvedFrameElevation,
360
+ layout,
361
+ direction,
362
+ wrap,
363
+ reverse,
364
+ columns,
365
+ rows,
366
+ align,
367
+ justify,
368
+ padding,
369
+ gap,
370
+ width,
371
+ height,
372
+ minWidth,
373
+ maxWidth,
374
+ minHeight,
375
+ maxHeight,
376
+ radius,
377
+ bordered,
378
+ disabled
379
+ ]
380
+ );
381
+ const contextValue = useMemo(
382
+ () => ({ elevation: resolvedElevation, tokens }),
383
+ [resolvedElevation, tokens]
384
+ );
385
+ const webOverrides = [];
386
+ if (styles.gridWebStyle) {
387
+ webOverrides.push(styles.gridWebStyle);
388
+ }
389
+ if (styles.insetBoxShadow) {
390
+ webOverrides.push({ boxShadow: styles.insetBoxShadow });
391
+ }
392
+ const userStyles = Array.isArray(style) ? style : style ? [style] : [];
393
+ const isInteractive = onPress !== void 0 || href !== void 0;
394
+ const { isFocusVisible, focusProps } = useFocusVisible();
395
+ const focusRingStyle = isFocusVisible && !disabled ? {
396
+ outlineWidth: 2,
397
+ outlineStyle: "solid",
398
+ outlineColor: tokens.accent.fill[gamut],
399
+ outlineOffset: 2
400
+ } : void 0;
401
+ const webFocusProps = isInteractive ? focusProps : {};
402
+ const textStyle = useMemo(
403
+ () => ({
404
+ color: tokens.textPrimary[gamut],
405
+ fontSize: tokens.typography.fontSizes["05"],
406
+ fontFamily: tokens.typography.fonts.main.family,
407
+ lineHeight: tokens.typography.lineHeights["06"]
408
+ }),
409
+ [tokens]
410
+ );
411
+ const wrappedChildren = useMemo(
412
+ () => wrapTextChildren(children, textStyle),
413
+ [children, textStyle]
414
+ );
415
+ return /* @__PURE__ */ React13.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
416
+ // Pressable handles taps. When href is set, react-native-web renders
417
+ // it as an <a> tag so it works like a regular link on the web.
418
+ /* @__PURE__ */ React13.createElement(
419
+ Pressable,
420
+ {
421
+ ref,
422
+ testID,
423
+ nativeID,
424
+ accessibilityLabel,
425
+ accessibilityHint,
426
+ accessibilityState: disabled ? { disabled: true } : void 0,
427
+ onPress,
428
+ disabled,
429
+ ...href ? { href, accessibilityRole: "link" } : { accessibilityRole: "button" },
430
+ ...webFocusProps,
431
+ style: ({ pressed }) => [
432
+ styles.container,
433
+ pressed && !disabled && styles.pressed,
434
+ focusRingStyle,
435
+ ...webOverrides,
436
+ ...userStyles
437
+ ]
438
+ },
439
+ wrappedChildren
440
+ )
441
+ ) : (
442
+ // Non-interactive Frame: just a plain View with no tap handling.
443
+ /* @__PURE__ */ React13.createElement(
444
+ View,
445
+ {
446
+ ref,
447
+ testID,
448
+ nativeID,
449
+ accessibilityLabel,
450
+ accessibilityHint,
451
+ style: [styles.container, ...webOverrides, ...userStyles]
452
+ },
453
+ wrappedChildren
454
+ )
455
+ ));
456
+ }
457
+ function Icon({
458
+ name,
459
+ size,
460
+ opticalSize,
461
+ fill = 0,
462
+ color,
463
+ style,
464
+ // Accessibility
465
+ accessibilityLabel,
466
+ // Testing & platform
467
+ testID,
468
+ nativeID,
469
+ ref
470
+ }) {
471
+ const tokens = useTokens();
472
+ const iconStyle = useMemo(() => {
473
+ const fontSize = size ?? tokens.typography.fontSizes["05"];
474
+ const getOpticalSize = (size2) => {
475
+ if (size2 <= 22) return 20;
476
+ if (size2 <= 32) return 24;
477
+ if (size2 <= 44) return 40;
478
+ return 48;
479
+ };
480
+ const opsz = opticalSize ?? getOpticalSize(fontSize);
481
+ const iconColor = color ?? tokens.textPrimary[tokens.gamut];
482
+ const fontFamily = `Material Symbols ${tokens.icons.variant.charAt(0).toUpperCase() + tokens.icons.variant.slice(1)}`;
483
+ const fillValue = typeof fill === "boolean" ? fill ? 1 : 0 : fill;
484
+ const fontVariationSettings = `'FILL' ${fillValue}, 'wght' ${tokens.icons.weight}, 'GRAD' ${tokens.icons.grade}, 'opsz' ${opsz}`;
485
+ return {
486
+ fontFamily,
487
+ fontSize,
488
+ width: fontSize,
489
+ // Explicit width ensures square rendering
490
+ height: fontSize,
491
+ // Explicit height ensures square rendering
492
+ lineHeight: fontSize,
493
+ // Prevent text line-height from affecting total height
494
+ color: iconColor,
495
+ userSelect: "none",
816
496
  // web-only: prevents users from selecting the icon as text
817
497
  fontVariationSettings,
818
498
  // web-only: controls the variable font axes listed above
819
499
  ...style
820
500
  };
821
501
  }, [tokens, size, opticalSize, fill, color, style]);
822
- return /* @__PURE__ */ React14.createElement(
502
+ return /* @__PURE__ */ React13.createElement(
823
503
  Text,
824
504
  {
825
505
  ref,
@@ -832,154 +512,144 @@ function Icon({
832
512
  name
833
513
  );
834
514
  }
835
-
836
- // src/fonts/measureFont.ts
837
- var REF_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
838
- function withTimeout(promise, ms, fallback) {
839
- return Promise.race([
840
- promise,
841
- new Promise((resolve) => setTimeout(() => resolve(fallback), ms))
842
- ]);
843
- }
844
- async function measureAvgCharWidth(fontFamily, fontWeight, fallback, fontSize = 16) {
845
- if (typeof document === "undefined") return 0.55;
846
- try {
847
- await withTimeout(
848
- document.fonts.load(`${fontWeight} ${fontSize}px "${fontFamily}"`),
849
- 3e3,
850
- []
851
- );
852
- const canvas = document.createElement("canvas");
853
- const ctx = canvas.getContext("2d");
854
- if (!ctx) return 0.55;
855
- ctx.font = `${fontWeight} ${fontSize}px "${fontFamily}", ${fallback}`;
856
- const ratio = ctx.measureText(REF_STRING).width / REF_STRING.length / fontSize;
857
- return Math.round(ratio * 1e3) / 1e3;
858
- } catch {
859
- return 0.55;
860
- }
861
- }
862
-
863
- // src/fonts/useLocalCalibration.ts
864
- var STORAGE_KEY = "newtone:font-metrics:v1";
865
- var TTL_MS = 7 * 24 * 60 * 60 * 1e3;
866
- function readCache() {
867
- if (typeof localStorage === "undefined") return {};
868
- try {
869
- const raw = localStorage.getItem(STORAGE_KEY);
870
- return raw ? JSON.parse(raw) : {};
871
- } catch {
872
- return {};
873
- }
874
- }
875
- function writeCache(cache) {
876
- if (typeof localStorage === "undefined") return;
877
- try {
878
- localStorage.setItem(STORAGE_KEY, JSON.stringify(cache));
879
- } catch {
880
- }
881
- }
882
- function cacheKey(fontFamily, fontWeight) {
883
- return `${fontFamily}:${fontWeight}`;
884
- }
885
- function useLocalCalibration(fontFamily, fontWeight, fallback, baseCalibration) {
886
- const key = cacheKey(fontFamily, fontWeight);
887
- const [ratio, setRatio] = useState(() => {
888
- const cache = readCache();
889
- const entry = cache[key];
890
- if (entry && Date.now() - entry.measuredAt < TTL_MS) {
891
- return entry.ratio;
892
- }
893
- return baseCalibration ?? 0.55;
894
- });
895
- useEffect(() => {
896
- const cache = readCache();
897
- const entry = cache[key];
898
- if (entry && Date.now() - entry.measuredAt < TTL_MS) {
899
- if (entry.ratio !== ratio) setRatio(entry.ratio);
900
- return;
901
- }
902
- let cancelled = false;
903
- measureAvgCharWidth(fontFamily, fontWeight, fallback).then((measured) => {
904
- if (cancelled) return;
905
- const updated = { ...readCache(), [key]: { ratio: measured, measuredAt: Date.now() } };
906
- writeCache(updated);
907
- setRatio(measured);
908
- });
909
- return () => {
910
- cancelled = true;
911
- };
912
- }, [key, fontFamily, fontWeight, fallback]);
913
- return ratio;
914
- }
915
-
916
- // src/fonts/useTypographyCalibrations.ts
917
- function useTypographyCalibrations() {
918
- const { config } = useNewtoneTheme();
919
- return config.typography.calibrations ?? {};
920
- }
921
-
922
- // src/fonts/reportQueue.ts
923
- var queue = [];
924
- var flushTimer;
925
- function flush() {
926
- if (queue.length === 0) return;
927
- const byEndpoint = /* @__PURE__ */ new Map();
928
- for (const item of queue) {
929
- const group = byEndpoint.get(item.endpoint) ?? [];
930
- group.push(item.payload);
931
- byEndpoint.set(item.endpoint, group);
932
- }
933
- queue.length = 0;
934
- for (const [endpoint, observations] of byEndpoint) {
935
- fetch(endpoint, {
936
- method: "POST",
937
- headers: { "Content-Type": "application/json" },
938
- body: JSON.stringify({ observations }),
939
- // keepalive: true allows the request to outlive the page
940
- keepalive: true
941
- }).catch(() => {
942
- });
515
+ function getWrapperStyles(input) {
516
+ const {
517
+ tokens,
518
+ direction = "vertical",
519
+ wrap = false,
520
+ reverse = false,
521
+ align,
522
+ justify,
523
+ padding,
524
+ gap,
525
+ width,
526
+ height,
527
+ minWidth,
528
+ maxWidth,
529
+ minHeight,
530
+ maxHeight
531
+ } = input;
532
+ const container = {};
533
+ container.flexDirection = resolveFlexDirection(direction, reverse);
534
+ if (wrap) container.flexWrap = "wrap";
535
+ if (align) container.alignItems = resolveAlignment(align);
536
+ if (justify) container.justifyContent = resolveJustification(justify);
537
+ if (padding !== void 0) {
538
+ const p = resolvePadding(padding, tokens);
539
+ container.paddingTop = p.top;
540
+ container.paddingRight = p.right;
541
+ container.paddingBottom = p.bottom;
542
+ container.paddingLeft = p.left;
943
543
  }
944
- }
945
- function enqueueObservation(endpoint, payload) {
946
- queue.push({ endpoint, payload });
947
- if (flushTimer !== void 0) clearTimeout(flushTimer);
948
- flushTimer = setTimeout(flush, 2e3);
949
- }
950
- function useBreakpoint() {
951
- const { width } = useWindowDimensions();
952
- return getBreakpointForWidth(width);
953
- }
954
-
955
- // src/primitives/Text/Text.tsx
956
- var TextScopeContext = createContext(null);
957
- function resolveTextColor(color, tokens) {
958
- switch (color) {
959
- case "primary":
960
- return srgbToHex(tokens.textPrimary.srgb);
961
- case "secondary":
962
- return srgbToHex(tokens.textSecondary.srgb);
963
- case "tertiary":
964
- return srgbToHex(tokens.textTertiary.srgb);
965
- case "disabled":
966
- return srgbToHex(tokens.textDisabled.srgb);
967
- case "accent":
968
- return srgbToHex(tokens.accent.fill.srgb);
969
- case "success":
970
- return srgbToHex(tokens.success.fill.srgb);
971
- case "warning":
972
- return srgbToHex(tokens.warning.fill.srgb);
973
- case "error":
974
- return srgbToHex(tokens.error.fill.srgb);
544
+ if (gap !== void 0) {
545
+ const g = resolveGap(gap, tokens);
546
+ container.rowGap = g.rowGap;
547
+ container.columnGap = g.columnGap;
975
548
  }
549
+ Object.assign(container, resolveSizing(width, height));
550
+ if (minWidth !== void 0) container.minWidth = minWidth;
551
+ if (maxWidth !== void 0) container.maxWidth = maxWidth;
552
+ if (minHeight !== void 0) container.minHeight = minHeight;
553
+ if (maxHeight !== void 0) container.maxHeight = maxHeight;
554
+ return StyleSheet.create({ c: container }).c;
976
555
  }
977
- var ADAPTIVE_ROLES = /* @__PURE__ */ new Set(["headline", "title", "heading", "subheading"]);
978
- var ROLE_HEADING_LEVEL = {
979
- headline: 1,
980
- title: 2,
981
- heading: 3
982
- };
556
+ function Wrapper({
557
+ children,
558
+ direction,
559
+ wrap,
560
+ reverse,
561
+ align,
562
+ justify,
563
+ padding,
564
+ gap,
565
+ width,
566
+ height,
567
+ minWidth,
568
+ maxWidth,
569
+ minHeight,
570
+ maxHeight,
571
+ style,
572
+ // Testing & platform
573
+ testID,
574
+ nativeID,
575
+ ref
576
+ }) {
577
+ const tokens = useTokens(1);
578
+ const containerStyle = useMemo(
579
+ () => getWrapperStyles({
580
+ tokens,
581
+ direction,
582
+ wrap,
583
+ reverse,
584
+ align,
585
+ justify,
586
+ padding,
587
+ gap,
588
+ width,
589
+ height,
590
+ minWidth,
591
+ maxWidth,
592
+ minHeight,
593
+ maxHeight
594
+ }),
595
+ [
596
+ tokens,
597
+ direction,
598
+ wrap,
599
+ reverse,
600
+ align,
601
+ justify,
602
+ padding,
603
+ gap,
604
+ width,
605
+ height,
606
+ minWidth,
607
+ maxWidth,
608
+ minHeight,
609
+ maxHeight
610
+ ]
611
+ );
612
+ const userStyles = Array.isArray(style) ? style : style ? [style] : [];
613
+ return /* @__PURE__ */ React13.createElement(
614
+ View,
615
+ {
616
+ ref,
617
+ testID,
618
+ nativeID,
619
+ accessibilityRole: "none",
620
+ style: [containerStyle, ...userStyles]
621
+ },
622
+ children
623
+ );
624
+ }
625
+ var TextScopeContext = createContext(null);
626
+ function resolveTextColor(color, tokens) {
627
+ const { gamut } = tokens;
628
+ switch (color) {
629
+ case "primary":
630
+ return tokens.textPrimary[gamut];
631
+ case "secondary":
632
+ return tokens.textSecondary[gamut];
633
+ case "tertiary":
634
+ return tokens.textTertiary[gamut];
635
+ case "disabled":
636
+ return tokens.textDisabled[gamut];
637
+ case "accent":
638
+ return tokens.accent.fill[gamut];
639
+ case "success":
640
+ return tokens.success.fill[gamut];
641
+ case "warning":
642
+ return tokens.warning.fill[gamut];
643
+ case "error":
644
+ return tokens.error.fill[gamut];
645
+ }
646
+ }
647
+ var ADAPTIVE_ROLES = /* @__PURE__ */ new Set(["headline", "title", "heading", "subheading"]);
648
+ var ROLE_HEADING_LEVEL = {
649
+ headline: 1,
650
+ title: 2,
651
+ heading: 3
652
+ };
983
653
  function extractCharacterCount(node) {
984
654
  if (typeof node === "string") return node.length;
985
655
  if (typeof node === "number") return String(node).length;
@@ -1086,7 +756,7 @@ function TextBase({
1086
756
  const effectiveA11yRole = accessibilityRoleOverride ?? inferredA11yRole;
1087
757
  const ariaLevel = effectiveA11yRole === "header" ? ROLE_HEADING_LEVEL[role] : void 0;
1088
758
  const scopeCtx = useMemo(() => ({ weights: SEMANTIC_WEIGHT_MAP }), []);
1089
- const textNode = /* @__PURE__ */ React14.createElement(TextScopeContext.Provider, { value: scopeCtx }, /* @__PURE__ */ React14.createElement(
759
+ const textNode = /* @__PURE__ */ React13.createElement(TextScopeContext.Provider, { value: scopeCtx }, /* @__PURE__ */ React13.createElement(
1090
760
  Text,
1091
761
  {
1092
762
  ref,
@@ -1100,7 +770,7 @@ function TextBase({
1100
770
  children
1101
771
  ));
1102
772
  if (responsive && isAdaptive) {
1103
- return /* @__PURE__ */ React14.createElement(
773
+ return /* @__PURE__ */ React13.createElement(
1104
774
  View,
1105
775
  {
1106
776
  onLayout: (e) => {
@@ -1126,30 +796,30 @@ function TextSpan({ children, color, weight, italic, underline, highlight, style
1126
796
  if (highlight) s.backgroundColor = resolveTextColor(highlight, tokens);
1127
797
  return s;
1128
798
  }, [tokens, scopeCtx, color, weight, italic, underline, highlight]);
1129
- return React14.createElement(
799
+ return React13.createElement(
1130
800
  Text,
1131
801
  { style: style ? [spanStyle, ...Array.isArray(style) ? style : [style]] : spanStyle },
1132
802
  children
1133
803
  );
1134
804
  }
1135
805
  function TextBold(props) {
1136
- return React14.createElement(TextSpan, { ...props, weight: "bold" });
806
+ return React13.createElement(TextSpan, { ...props, weight: "bold" });
1137
807
  }
1138
808
  function TextMedium(props) {
1139
- return React14.createElement(TextSpan, { ...props, weight: "medium" });
809
+ return React13.createElement(TextSpan, { ...props, weight: "medium" });
1140
810
  }
1141
811
  function TextItalic(props) {
1142
- return React14.createElement(TextSpan, { ...props, italic: true });
812
+ return React13.createElement(TextSpan, { ...props, italic: true });
1143
813
  }
1144
814
  function TextUnderline(props) {
1145
- return React14.createElement(TextSpan, { ...props, underline: true });
815
+ return React13.createElement(TextSpan, { ...props, underline: true });
1146
816
  }
1147
817
  function TextHighlight(props) {
1148
- return React14.createElement(TextSpan, props);
818
+ return React13.createElement(TextSpan, props);
1149
819
  }
1150
820
 
1151
821
  // src/primitives/Text/index.ts
1152
- var Text2 = Object.assign(TextBase, {
822
+ var Text3 = Object.assign(TextBase, {
1153
823
  Span: TextSpan,
1154
824
  Bold: TextBold,
1155
825
  Medium: TextMedium,
@@ -1158,655 +828,297 @@ var Text2 = Object.assign(TextBase, {
1158
828
  Highlight: TextHighlight
1159
829
  });
1160
830
 
1161
- // src/primitives/Frame/Frame.utils.ts
1162
- function resolveSpacing(value, tokens) {
1163
- if (typeof value === "number") return value;
1164
- return tokens.spacing[value];
1165
- }
1166
- function resolvePadding(prop, tokens) {
1167
- if (typeof prop === "string" || typeof prop === "number") {
1168
- const px = resolveSpacing(prop, tokens);
1169
- return { top: px, right: px, bottom: px, left: px };
831
+ // src/composites/actions/Button/Button.styles.ts
832
+ function computeButtonPadding(size, hasIcon, hasText, iconPosition) {
833
+ const basePadding = {
834
+ sm: 8,
835
+ md: 12,
836
+ lg: 16
837
+ };
838
+ const base = basePadding[size];
839
+ const textExtra = 8;
840
+ if (!hasText && hasIcon) {
841
+ return {
842
+ paddingLeft: base,
843
+ paddingRight: base,
844
+ paddingTop: base,
845
+ paddingBottom: base
846
+ };
1170
847
  }
1171
- if ("x" in prop || "y" in prop) {
1172
- const axes = prop;
1173
- const x = axes.x !== void 0 ? resolveSpacing(axes.x, tokens) : 0;
1174
- const y = axes.y !== void 0 ? resolveSpacing(axes.y, tokens) : 0;
1175
- return { top: y, right: x, bottom: y, left: x };
848
+ if (hasText && !hasIcon) {
849
+ return {
850
+ paddingLeft: base + textExtra,
851
+ paddingRight: base + textExtra,
852
+ paddingTop: base,
853
+ paddingBottom: base
854
+ };
855
+ }
856
+ if (hasText && hasIcon) {
857
+ if (iconPosition === "left") {
858
+ return {
859
+ paddingLeft: base,
860
+ paddingRight: base + textExtra,
861
+ paddingTop: base,
862
+ paddingBottom: base
863
+ };
864
+ } else {
865
+ return {
866
+ paddingLeft: base + textExtra,
867
+ paddingRight: base,
868
+ paddingTop: base,
869
+ paddingBottom: base
870
+ };
871
+ }
1176
872
  }
1177
- const sides = prop;
1178
873
  return {
1179
- top: sides.top !== void 0 ? resolveSpacing(sides.top, tokens) : 0,
1180
- right: sides.right !== void 0 ? resolveSpacing(sides.right, tokens) : 0,
1181
- bottom: sides.bottom !== void 0 ? resolveSpacing(sides.bottom, tokens) : 0,
1182
- left: sides.left !== void 0 ? resolveSpacing(sides.left, tokens) : 0
874
+ paddingLeft: base,
875
+ paddingRight: base,
876
+ paddingTop: base,
877
+ paddingBottom: base
1183
878
  };
1184
879
  }
1185
- function resolveGap(prop, tokens) {
1186
- if (typeof prop === "string" || typeof prop === "number") {
1187
- const px = resolveSpacing(prop, tokens);
1188
- return { rowGap: px, columnGap: px };
880
+ function getPaletteTokens(semantic, tokens) {
881
+ switch (semantic) {
882
+ case "accent":
883
+ return tokens.accent;
884
+ case "success":
885
+ return tokens.success;
886
+ case "error":
887
+ return tokens.error;
888
+ case "warning":
889
+ return tokens.warning;
890
+ default:
891
+ return void 0;
1189
892
  }
893
+ }
894
+ function getButtonConfig(variant, semantic, size, disabled, tokens) {
895
+ const sizeConfig = getSizeConfig(size, tokens);
896
+ const variantColors = getVariantColors(variant, semantic, disabled, tokens);
1190
897
  return {
1191
- rowGap: prop.row !== void 0 ? resolveSpacing(prop.row, tokens) : 0,
1192
- columnGap: prop.column !== void 0 ? resolveSpacing(prop.column, tokens) : 0
898
+ variantColors,
899
+ sizeTokens: {
900
+ padding: sizeConfig.padding,
901
+ gap: sizeConfig.gap,
902
+ borderRadius: sizeConfig.borderRadius,
903
+ textSize: sizeConfig.textSize,
904
+ iconSize: sizeConfig.iconSize
905
+ }
1193
906
  };
1194
907
  }
1195
- function resolveRadius(value, tokens) {
1196
- if (typeof value === "number") return value;
1197
- return tokens.radius[value];
1198
- }
1199
- function resolveRadiusCorners(prop, tokens) {
1200
- if (typeof prop === "string" || typeof prop === "number") {
1201
- const px = resolveRadius(prop, tokens);
1202
- return { topLeft: px, topRight: px, bottomLeft: px, bottomRight: px };
1203
- }
1204
- return {
1205
- topLeft: prop.topLeft !== void 0 ? resolveRadius(prop.topLeft, tokens) : 0,
1206
- topRight: prop.topRight !== void 0 ? resolveRadius(prop.topRight, tokens) : 0,
1207
- bottomLeft: prop.bottomLeft !== void 0 ? resolveRadius(prop.bottomLeft, tokens) : 0,
1208
- bottomRight: prop.bottomRight !== void 0 ? resolveRadius(prop.bottomRight, tokens) : 0
908
+ function getSizeConfig(size, tokens) {
909
+ const configs = {
910
+ sm: {
911
+ padding: 8,
912
+ gap: tokens.spacing["08"],
913
+ borderRadius: 8,
914
+ textSize: "md",
915
+ // 16px
916
+ iconSize: 24
917
+ },
918
+ md: {
919
+ padding: 12,
920
+ gap: tokens.spacing["08"],
921
+ borderRadius: 12,
922
+ textSize: "md",
923
+ // 16px
924
+ iconSize: 24
925
+ },
926
+ lg: {
927
+ padding: 16,
928
+ gap: tokens.spacing["08"],
929
+ borderRadius: 16,
930
+ textSize: "md",
931
+ // 16px
932
+ iconSize: 24
933
+ }
1209
934
  };
935
+ return configs[size];
1210
936
  }
1211
- function hasPositiveRadius(corners) {
1212
- return corners.topLeft > 0 || corners.topRight > 0 || corners.bottomLeft > 0 || corners.bottomRight > 0;
937
+ function getVariantColors(variant, semantic, disabled, tokens) {
938
+ if (disabled) {
939
+ const baseColors = getVariantColorsForState(variant, semantic, tokens);
940
+ const { gamut } = tokens;
941
+ const disabledBg = tokens.backgroundSunken[gamut];
942
+ return {
943
+ ...baseColors,
944
+ bg: disabledBg,
945
+ hoveredBg: disabledBg,
946
+ pressedBg: disabledBg,
947
+ textColor: tokens.textSecondary[gamut],
948
+ iconColor: tokens.textSecondary[gamut]
949
+ };
950
+ }
951
+ return getVariantColorsForState(variant, semantic, tokens);
1213
952
  }
1214
- function resolveSizing(width, height) {
1215
- const style = {};
1216
- if (width !== void 0) {
1217
- if (width === "fill") {
1218
- style.flexGrow = 1;
1219
- style.width = "100%";
1220
- } else if (typeof width === "number") {
1221
- style.width = width;
953
+ function getVariantColorsForState(variant, semantic, tokens) {
954
+ const { gamut } = tokens;
955
+ const paletteTokens = getPaletteTokens(semantic, tokens);
956
+ if (variant === "primary") {
957
+ if (semantic === "neutral") {
958
+ return {
959
+ bg: tokens.backgroundInteractive[gamut],
960
+ hoveredBg: tokens.backgroundInteractiveHover[gamut],
961
+ pressedBg: tokens.backgroundInteractiveActive[gamut],
962
+ textColor: tokens.textPrimary[gamut],
963
+ iconColor: tokens.textPrimary[gamut],
964
+ borderWidth: 1,
965
+ borderColor: "transparent"
966
+ };
1222
967
  }
968
+ return {
969
+ bg: paletteTokens.fill[gamut],
970
+ hoveredBg: paletteTokens.fillHover[gamut],
971
+ pressedBg: paletteTokens.fillActive[gamut],
972
+ textColor: paletteTokens.onFill[gamut],
973
+ iconColor: paletteTokens.onFill[gamut],
974
+ borderWidth: 1,
975
+ borderColor: "transparent"
976
+ };
1223
977
  }
1224
- if (height !== void 0) {
1225
- if (height === "fill") {
1226
- style.flexGrow = 1;
1227
- style.height = "100%";
1228
- } else if (typeof height === "number") {
1229
- style.height = height;
978
+ if (variant === "secondary") {
979
+ if (semantic === "neutral") {
980
+ return {
981
+ bg: "transparent",
982
+ hoveredBg: tokens.backgroundInteractive[gamut],
983
+ pressedBg: tokens.backgroundInteractiveHover[gamut],
984
+ textColor: tokens.textPrimary[gamut],
985
+ iconColor: tokens.textPrimary[gamut],
986
+ borderWidth: 1,
987
+ borderColor: tokens.border[gamut]
988
+ };
1230
989
  }
1231
- }
1232
- return style;
1233
- }
1234
- var ALIGN_MAP = {
1235
- start: "flex-start",
1236
- center: "center",
1237
- end: "flex-end",
1238
- stretch: "stretch",
1239
- baseline: "baseline"
1240
- };
1241
- var JUSTIFY_MAP = {
1242
- start: "flex-start",
1243
- center: "center",
1244
- end: "flex-end",
1245
- between: "space-between",
1246
- around: "space-around",
1247
- evenly: "space-evenly"
1248
- };
1249
- function resolveAlignment(align) {
1250
- return ALIGN_MAP[align];
1251
- }
1252
- function resolveJustification(justify) {
1253
- return JUSTIFY_MAP[justify];
1254
- }
1255
- function resolveFlexDirection(direction, reverse) {
1256
- if (direction === "horizontal") {
1257
- return reverse ? "row-reverse" : "row";
1258
- }
1259
- return reverse ? "column-reverse" : "column";
1260
- }
1261
-
1262
- // src/primitives/Wrapper/Wrapper.styles.ts
1263
- function getWrapperStyles(input) {
1264
- const {
1265
- tokens,
1266
- direction = "vertical",
1267
- wrap = false,
1268
- reverse = false,
1269
- align,
1270
- justify,
1271
- padding,
1272
- gap,
1273
- width,
1274
- height,
1275
- minWidth,
1276
- maxWidth,
1277
- minHeight,
1278
- maxHeight
1279
- } = input;
1280
- const container = {};
1281
- container.flexDirection = resolveFlexDirection(direction, reverse);
1282
- if (wrap) container.flexWrap = "wrap";
1283
- if (align) container.alignItems = resolveAlignment(align);
1284
- if (justify) container.justifyContent = resolveJustification(justify);
1285
- if (padding !== void 0) {
1286
- const p = resolvePadding(padding, tokens);
1287
- container.paddingTop = p.top;
1288
- container.paddingRight = p.right;
1289
- container.paddingBottom = p.bottom;
1290
- container.paddingLeft = p.left;
1291
- }
1292
- if (gap !== void 0) {
1293
- const g = resolveGap(gap, tokens);
1294
- container.rowGap = g.rowGap;
1295
- container.columnGap = g.columnGap;
1296
- }
1297
- Object.assign(container, resolveSizing(width, height));
1298
- if (minWidth !== void 0) container.minWidth = minWidth;
1299
- if (maxWidth !== void 0) container.maxWidth = maxWidth;
1300
- if (minHeight !== void 0) container.minHeight = minHeight;
1301
- if (maxHeight !== void 0) container.maxHeight = maxHeight;
1302
- return StyleSheet.create({ c: container }).c;
1303
- }
1304
-
1305
- // src/primitives/Wrapper/Wrapper.tsx
1306
- function Wrapper({
1307
- children,
1308
- direction,
1309
- wrap,
1310
- reverse,
1311
- align,
1312
- justify,
1313
- padding,
1314
- gap,
1315
- width,
1316
- height,
1317
- minWidth,
1318
- maxWidth,
1319
- minHeight,
1320
- maxHeight,
1321
- style,
1322
- // Testing & platform
1323
- testID,
1324
- nativeID,
1325
- ref
1326
- }) {
1327
- const tokens = useTokens(1);
1328
- const containerStyle = useMemo(
1329
- () => getWrapperStyles({
1330
- tokens,
1331
- direction,
1332
- wrap,
1333
- reverse,
1334
- align,
1335
- justify,
1336
- padding,
1337
- gap,
1338
- width,
1339
- height,
1340
- minWidth,
1341
- maxWidth,
1342
- minHeight,
1343
- maxHeight
1344
- }),
1345
- [
1346
- tokens,
1347
- direction,
1348
- wrap,
1349
- reverse,
1350
- align,
1351
- justify,
1352
- padding,
1353
- gap,
1354
- width,
1355
- height,
1356
- minWidth,
1357
- maxWidth,
1358
- minHeight,
1359
- maxHeight
1360
- ]
1361
- );
1362
- const userStyles = Array.isArray(style) ? style : style ? [style] : [];
1363
- return /* @__PURE__ */ React14.createElement(
1364
- View,
1365
- {
1366
- ref,
1367
- testID,
1368
- nativeID,
1369
- accessibilityRole: "none",
1370
- style: [containerStyle, ...userStyles]
1371
- },
1372
- children
1373
- );
1374
- }
1375
-
1376
- // src/composites/actions/Button/Button.tsx
1377
- function Button({
1378
- children,
1379
- icon,
1380
- iconPosition = "left",
1381
- variant = "primary",
1382
- semantic = "neutral",
1383
- size = "md",
1384
- disabled = false,
1385
- style,
1386
- textStyle,
1387
- ...pressableProps
1388
- }) {
1389
- const tokens = useTokens();
1390
- const { variantColors, sizeTokens } = React14.useMemo(
1391
- () => getButtonConfig(variant, semantic, size, disabled, tokens),
1392
- [variant, semantic, size, disabled, tokens]
1393
- );
1394
- const padding = React14.useMemo(
1395
- () => computeButtonPadding(size, !!icon, !!children, iconPosition),
1396
- [size, icon, children, iconPosition]
1397
- );
1398
- return /* @__PURE__ */ React14.createElement(Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1399
- // Wrapper handles layout: direction, gap, alignment (padding via style)
1400
- /* @__PURE__ */ React14.createElement(
1401
- Wrapper,
1402
- {
1403
- direction: "horizontal",
1404
- align: "center",
1405
- justify: "center",
1406
- gap: sizeTokens.gap,
1407
- style: [
1408
- {
1409
- ...padding,
1410
- // Asymmetric horizontal padding for text optical balance
1411
- backgroundColor: pressed && !disabled ? variantColors.pressedBg : hovered && !disabled ? variantColors.hoveredBg : variantColors.bg,
1412
- borderRadius: sizeTokens.borderRadius,
1413
- borderWidth: variantColors.borderWidth,
1414
- // Always 1 for consistent sizing
1415
- borderColor: variantColors.borderColor || "transparent",
1416
- opacity: disabled ? 0.4 : 1
1417
- },
1418
- ...Array.isArray(style) ? style : style ? [style] : []
1419
- ]
1420
- },
1421
- icon && iconPosition === "left" && /* @__PURE__ */ React14.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1422
- children && // Text primitive with semantic props + color style override
1423
- /* @__PURE__ */ React14.createElement(
1424
- Text2,
1425
- {
1426
- role: "label",
1427
- size: sizeTokens.textSize,
1428
- centerVertically: true,
1429
- style: [
1430
- { color: variantColors.textColor },
1431
- ...Array.isArray(textStyle) ? textStyle : textStyle ? [textStyle] : []
1432
- ]
1433
- },
1434
- children
1435
- ),
1436
- icon && iconPosition === "right" && /* @__PURE__ */ React14.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1437
- )
1438
- ));
1439
- }
1440
- function getCardStyles(tokens, disabled) {
1441
- return StyleSheet.create({
1442
- container: {
1443
- backgroundColor: srgbToHex(tokens.background.srgb),
990
+ return {
991
+ bg: paletteTokens.background[gamut],
992
+ hoveredBg: paletteTokens.backgroundInteractive[gamut],
993
+ pressedBg: paletteTokens.backgroundInteractiveHover[gamut],
994
+ textColor: paletteTokens.fill[gamut],
995
+ iconColor: paletteTokens.fill[gamut],
1444
996
  borderWidth: 1,
1445
- borderColor: srgbToHex(tokens.border.srgb),
1446
- borderRadius: tokens.radius.lg,
1447
- padding: tokens.spacing["16"],
1448
- opacity: disabled ? 0.5 : 1
1449
- }
1450
- });
1451
- }
1452
-
1453
- // src/composites/layout/Card/Card.tsx
1454
- function Card({
1455
- children,
1456
- elevation = 1,
1457
- style,
1458
- disabled = false
1459
- }) {
1460
- const tokens = useTokens(elevation);
1461
- const styles = React14.useMemo(
1462
- () => getCardStyles(tokens, disabled),
1463
- [tokens, disabled]
1464
- );
1465
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1466
- }
1467
- var hadKeyboardEvent = false;
1468
- var isListenerSetup = false;
1469
- function setupModality() {
1470
- if (isListenerSetup || typeof document === "undefined") return;
1471
- isListenerSetup = true;
1472
- const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
1473
- "Tab",
1474
- "ArrowUp",
1475
- "ArrowDown",
1476
- "ArrowLeft",
1477
- "ArrowRight",
1478
- "Enter",
1479
- " ",
1480
- "Escape"
1481
- ]);
1482
- document.addEventListener("keydown", (e) => {
1483
- if (NAVIGATION_KEYS.has(e.key)) {
1484
- hadKeyboardEvent = true;
1485
- }
1486
- }, true);
1487
- document.addEventListener("pointerdown", () => {
1488
- hadKeyboardEvent = false;
1489
- }, true);
1490
- document.addEventListener("mousedown", () => {
1491
- hadKeyboardEvent = false;
1492
- }, true);
1493
- }
1494
- function useFocusVisible() {
1495
- const [isFocusVisible, setIsFocusVisible] = useState(false);
1496
- useEffect(() => {
1497
- setupModality();
1498
- }, []);
1499
- const onFocus = useCallback(() => {
1500
- if (hadKeyboardEvent) {
1501
- setIsFocusVisible(true);
1502
- }
1503
- }, []);
1504
- const onBlur = useCallback(() => {
1505
- setIsFocusVisible(false);
1506
- }, []);
1507
- const focusProps = { onFocus, onBlur };
1508
- return { isFocusVisible, focusProps };
1509
- }
1510
- function getFrameStyles(input) {
1511
- const {
1512
- tokens,
1513
- frameElevation,
1514
- layout = "flex",
1515
- direction = "vertical",
1516
- wrap = false,
1517
- reverse = false,
1518
- columns,
1519
- rows,
1520
- align,
1521
- justify,
1522
- padding,
1523
- gap,
1524
- width,
1525
- height,
1526
- minWidth,
1527
- maxWidth,
1528
- minHeight,
1529
- maxHeight,
1530
- radius,
1531
- bordered = false,
1532
- disabled = false
1533
- } = input;
1534
- const container = {};
1535
- container.backgroundColor = srgbToHex(tokens.background.srgb);
1536
- container.color = srgbToHex(tokens.textPrimary.srgb);
1537
- if (layout === "flex") {
1538
- container.display = "flex";
1539
- container.flexDirection = resolveFlexDirection(direction, reverse);
1540
- if (wrap) container.flexWrap = "wrap";
1541
- }
1542
- if (layout === "grid") {
1543
- container.display = "flex";
1544
- container.flexDirection = "row";
1545
- container.flexWrap = "wrap";
1546
- }
1547
- if (align) container.alignItems = resolveAlignment(align);
1548
- if (justify) container.justifyContent = resolveJustification(justify);
1549
- if (padding !== void 0) {
1550
- const p = resolvePadding(padding, tokens);
1551
- container.paddingTop = p.top;
1552
- container.paddingRight = p.right;
1553
- container.paddingBottom = p.bottom;
1554
- container.paddingLeft = p.left;
1555
- }
1556
- if (gap !== void 0) {
1557
- const g = resolveGap(gap, tokens);
1558
- container.rowGap = g.rowGap;
1559
- container.columnGap = g.columnGap;
1560
- }
1561
- const sizing = resolveSizing(width, height);
1562
- Object.assign(container, sizing);
1563
- if (minWidth !== void 0) container.minWidth = minWidth;
1564
- if (maxWidth !== void 0) container.maxWidth = maxWidth;
1565
- if (minHeight !== void 0) container.minHeight = minHeight;
1566
- if (maxHeight !== void 0) container.maxHeight = maxHeight;
1567
- if (radius !== void 0) {
1568
- const corners = resolveRadiusCorners(radius, tokens);
1569
- container.borderTopLeftRadius = corners.topLeft;
1570
- container.borderTopRightRadius = corners.topRight;
1571
- container.borderBottomLeftRadius = corners.bottomLeft;
1572
- container.borderBottomRightRadius = corners.bottomRight;
1573
- if (hasPositiveRadius(corners)) {
1574
- container.overflow = "hidden";
1575
- }
1576
- }
1577
- if (bordered) {
1578
- container.borderWidth = 1;
1579
- container.borderColor = srgbToHex(tokens.border.srgb);
1580
- }
1581
- if (frameElevation === 2) {
1582
- container.shadowColor = "#000";
1583
- container.shadowOffset = { width: 0, height: 2 };
1584
- container.shadowOpacity = 0.12;
1585
- container.shadowRadius = 6;
1586
- container.elevation = 4;
1587
- }
1588
- if (disabled) {
1589
- container.opacity = 0.5;
1590
- }
1591
- const pressed = StyleSheet.create({
1592
- s: { backgroundColor: srgbToHex(tokens.backgroundSunken.srgb) }
1593
- }).s;
1594
- let gridWebStyle = null;
1595
- if (layout === "grid") {
1596
- gridWebStyle = {
1597
- display: "grid",
1598
- // Divide into equal-width columns (e.g. 3 columns → "repeat(3, 1fr)").
1599
- gridTemplateColumns: columns ? `repeat(${columns}, 1fr)` : void 0,
1600
- gridTemplateRows: rows ? `repeat(${rows}, 1fr)` : void 0
997
+ borderColor: "transparent"
1601
998
  };
1602
999
  }
1603
- const insetBoxShadow = frameElevation === -2 ? "inset 0 2px 4px rgba(0,0,0,0.12)" : null;
1604
- return {
1605
- // Validate and optimize the container styles through StyleSheet.create(),
1606
- // then extract the single style object with `.c`.
1607
- container: StyleSheet.create({ c: container }).c,
1608
- pressed,
1609
- gridWebStyle,
1610
- insetBoxShadow
1611
- };
1612
- }
1613
-
1614
- // src/primitives/Frame/Frame.tsx
1615
- function wrapTextChildren(children, textStyle) {
1616
- return React14.Children.map(children, (child) => {
1617
- if (typeof child === "string" || typeof child === "number") {
1618
- return /* @__PURE__ */ React14.createElement(Text, { style: textStyle }, child);
1000
+ if (variant === "tertiary") {
1001
+ if (semantic === "neutral") {
1002
+ return {
1003
+ bg: "transparent",
1004
+ hoveredBg: tokens.backgroundInteractive[gamut],
1005
+ pressedBg: tokens.backgroundInteractiveHover[gamut],
1006
+ textColor: tokens.textPrimary[gamut],
1007
+ iconColor: tokens.textPrimary[gamut],
1008
+ borderWidth: 1,
1009
+ borderColor: "transparent"
1010
+ };
1619
1011
  }
1620
- return child;
1621
- });
1622
- }
1623
- function toElevationLevel(frameElevation) {
1624
- if (frameElevation <= -1) return 0;
1625
- if (frameElevation === 0) return 1;
1626
- return 2;
1012
+ return {
1013
+ bg: "transparent",
1014
+ hoveredBg: paletteTokens.background[gamut],
1015
+ pressedBg: paletteTokens.backgroundInteractive[gamut],
1016
+ textColor: paletteTokens.fill[gamut],
1017
+ iconColor: paletteTokens.fill[gamut],
1018
+ borderWidth: 1,
1019
+ borderColor: "transparent"
1020
+ };
1021
+ }
1022
+ return {
1023
+ bg: "transparent",
1024
+ hoveredBg: "transparent",
1025
+ pressedBg: "transparent",
1026
+ textColor: tokens.textPrimary[gamut],
1027
+ iconColor: tokens.textPrimary[gamut],
1028
+ borderWidth: 0
1029
+ };
1627
1030
  }
1628
- function Frame({
1031
+ function Button({
1629
1032
  children,
1630
- // Elevation
1631
- elevation,
1632
- // Layout
1633
- layout,
1634
- direction,
1635
- wrap,
1636
- reverse,
1637
- columns,
1638
- rows,
1639
- // Alignment
1640
- align,
1641
- justify,
1642
- // Spacing
1643
- padding,
1644
- gap,
1645
- // Sizing
1646
- width,
1647
- height,
1648
- minWidth,
1649
- maxWidth,
1650
- minHeight,
1651
- maxHeight,
1652
- // Appearance
1653
- radius,
1654
- bordered,
1655
- // Interactivity
1656
- onPress,
1657
- href,
1033
+ icon,
1034
+ iconPosition = "left",
1035
+ variant = "primary",
1036
+ semantic = "neutral",
1037
+ size = "md",
1658
1038
  disabled = false,
1659
- // Accessibility
1660
- accessibilityLabel,
1661
- accessibilityHint,
1662
- // Testing & platform
1663
- testID,
1664
- nativeID,
1665
- ref,
1666
- // Style override
1667
- style
1039
+ style,
1040
+ textStyle,
1041
+ ...pressableProps
1668
1042
  }) {
1669
- const { config, mode } = useNewtoneTheme();
1670
- const parentFrameCtx = useFrameContext();
1671
- const resolvedFrameElevation = elevation ?? 0;
1672
- const resolvedElevation = elevation !== void 0 ? toElevationLevel(elevation) : parentFrameCtx?.elevation ?? 1;
1673
- const tokens = useMemo(() => {
1674
- return computeTokens(
1675
- config.colorSystem,
1676
- mode,
1677
- resolvedElevation,
1678
- config.spacing,
1679
- config.radius,
1680
- config.typography,
1681
- config.icons,
1682
- config.tokenOverrides
1683
- );
1684
- }, [config, mode, resolvedElevation]);
1685
- const styles = useMemo(
1686
- () => getFrameStyles({
1687
- tokens,
1688
- frameElevation: resolvedFrameElevation,
1689
- layout,
1690
- direction,
1691
- wrap,
1692
- reverse,
1693
- columns,
1694
- rows,
1695
- align,
1696
- justify,
1697
- padding,
1698
- gap,
1699
- width,
1700
- height,
1701
- minWidth,
1702
- maxWidth,
1703
- minHeight,
1704
- maxHeight,
1705
- radius,
1706
- bordered,
1707
- disabled
1708
- }),
1709
- [
1710
- tokens,
1711
- resolvedFrameElevation,
1712
- layout,
1713
- direction,
1714
- wrap,
1715
- reverse,
1716
- columns,
1717
- rows,
1718
- align,
1719
- justify,
1720
- padding,
1721
- gap,
1722
- width,
1723
- height,
1724
- minWidth,
1725
- maxWidth,
1726
- minHeight,
1727
- maxHeight,
1728
- radius,
1729
- bordered,
1730
- disabled
1731
- ]
1732
- );
1733
- const contextValue = useMemo(
1734
- () => ({ elevation: resolvedElevation, tokens }),
1735
- [resolvedElevation, tokens]
1736
- );
1737
- const webOverrides = [];
1738
- if (styles.gridWebStyle) {
1739
- webOverrides.push(styles.gridWebStyle);
1740
- }
1741
- if (styles.insetBoxShadow) {
1742
- webOverrides.push({ boxShadow: styles.insetBoxShadow });
1743
- }
1744
- const userStyles = Array.isArray(style) ? style : style ? [style] : [];
1745
- const isInteractive = onPress !== void 0 || href !== void 0;
1746
- const { isFocusVisible, focusProps } = useFocusVisible();
1747
- const focusRingStyle = isFocusVisible && !disabled ? {
1748
- outlineWidth: 2,
1749
- outlineStyle: "solid",
1750
- outlineColor: srgbToHex(tokens.accent.fill.srgb),
1751
- outlineOffset: 2
1752
- } : void 0;
1753
- const webFocusProps = isInteractive ? focusProps : {};
1754
- const textStyle = useMemo(
1755
- () => ({
1756
- color: srgbToHex(tokens.textPrimary.srgb),
1757
- fontSize: tokens.typography.fontSizes["05"],
1758
- fontFamily: tokens.typography.fonts.main.family,
1759
- lineHeight: tokens.typography.lineHeights["06"]
1760
- }),
1761
- [tokens]
1043
+ const tokens = useTokens();
1044
+ const { variantColors, sizeTokens } = React13.useMemo(
1045
+ () => getButtonConfig(variant, semantic, size, disabled, tokens),
1046
+ [variant, semantic, size, disabled, tokens]
1762
1047
  );
1763
- const wrappedChildren = useMemo(
1764
- () => wrapTextChildren(children, textStyle),
1765
- [children, textStyle]
1048
+ const padding = React13.useMemo(
1049
+ () => computeButtonPadding(size, !!icon, !!children, iconPosition),
1050
+ [size, icon, children, iconPosition]
1766
1051
  );
1767
- return /* @__PURE__ */ React14.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1768
- // Pressable handles taps. When href is set, react-native-web renders
1769
- // it as an <a> tag so it works like a regular link on the web.
1770
- /* @__PURE__ */ React14.createElement(
1771
- Pressable,
1052
+ return /* @__PURE__ */ React13.createElement(Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1053
+ // Wrapper handles layout: direction, gap, alignment (padding via style)
1054
+ /* @__PURE__ */ React13.createElement(
1055
+ Wrapper,
1772
1056
  {
1773
- ref,
1774
- testID,
1775
- nativeID,
1776
- accessibilityLabel,
1777
- accessibilityHint,
1778
- accessibilityState: disabled ? { disabled: true } : void 0,
1779
- onPress,
1780
- disabled,
1781
- ...href ? { href, accessibilityRole: "link" } : { accessibilityRole: "button" },
1782
- ...webFocusProps,
1783
- style: ({ pressed }) => [
1784
- styles.container,
1785
- pressed && !disabled && styles.pressed,
1786
- focusRingStyle,
1787
- ...webOverrides,
1788
- ...userStyles
1057
+ direction: "horizontal",
1058
+ align: "center",
1059
+ justify: "center",
1060
+ gap: sizeTokens.gap,
1061
+ style: [
1062
+ {
1063
+ ...padding,
1064
+ // Asymmetric horizontal padding for text optical balance
1065
+ backgroundColor: pressed && !disabled ? variantColors.pressedBg : hovered && !disabled ? variantColors.hoveredBg : variantColors.bg,
1066
+ borderRadius: sizeTokens.borderRadius,
1067
+ borderWidth: variantColors.borderWidth,
1068
+ // Always 1 for consistent sizing
1069
+ borderColor: variantColors.borderColor || "transparent",
1070
+ opacity: disabled ? 0.4 : 1
1071
+ },
1072
+ ...Array.isArray(style) ? style : style ? [style] : []
1789
1073
  ]
1790
1074
  },
1791
- wrappedChildren
1792
- )
1793
- ) : (
1794
- // Non-interactive Frame: just a plain View with no tap handling.
1795
- /* @__PURE__ */ React14.createElement(
1796
- View,
1797
- {
1798
- ref,
1799
- testID,
1800
- nativeID,
1801
- accessibilityLabel,
1802
- accessibilityHint,
1803
- style: [styles.container, ...webOverrides, ...userStyles]
1804
- },
1805
- wrappedChildren
1075
+ icon && iconPosition === "left" && /* @__PURE__ */ React13.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1076
+ children && // Text primitive with semantic props + color style override
1077
+ /* @__PURE__ */ React13.createElement(
1078
+ Text3,
1079
+ {
1080
+ role: "label",
1081
+ size: sizeTokens.textSize,
1082
+ centerVertically: true,
1083
+ style: [
1084
+ { color: variantColors.textColor },
1085
+ ...Array.isArray(textStyle) ? textStyle : textStyle ? [textStyle] : []
1086
+ ]
1087
+ },
1088
+ children
1089
+ ),
1090
+ icon && iconPosition === "right" && /* @__PURE__ */ React13.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1806
1091
  )
1807
1092
  ));
1808
1093
  }
1809
- function getTextInputStyles(tokens, disabled) {
1094
+ function getCardStyles(tokens, gamut, disabled) {
1095
+ return StyleSheet.create({
1096
+ container: {
1097
+ backgroundColor: tokens.background[gamut],
1098
+ borderWidth: 1,
1099
+ borderColor: tokens.border[gamut],
1100
+ borderRadius: tokens.radius.lg,
1101
+ padding: tokens.spacing["16"],
1102
+ opacity: disabled ? 0.5 : 1
1103
+ }
1104
+ });
1105
+ }
1106
+
1107
+ // src/composites/layout/Card/Card.tsx
1108
+ function Card({
1109
+ children,
1110
+ elevation = 1,
1111
+ style,
1112
+ disabled = false
1113
+ }) {
1114
+ const tokens = useTokens(elevation);
1115
+ const styles = React13.useMemo(
1116
+ () => getCardStyles(tokens, tokens.gamut, disabled),
1117
+ [tokens, disabled]
1118
+ );
1119
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1120
+ }
1121
+ function getTextInputStyles(tokens, gamut, disabled) {
1810
1122
  return StyleSheet.create({
1811
1123
  container: {
1812
1124
  gap: tokens.spacing["04"]
@@ -1815,22 +1127,24 @@ function getTextInputStyles(tokens, disabled) {
1815
1127
  fontFamily: tokens.typography.fonts.main.family,
1816
1128
  fontSize: tokens.typography.fontSizes["04"],
1817
1129
  fontWeight: tokens.typography.fonts.main.weights.medium,
1818
- color: srgbToHex(tokens.textSecondary.srgb)
1130
+ color: tokens.textSecondary[gamut]
1819
1131
  },
1820
1132
  input: {
1821
1133
  fontFamily: tokens.typography.fonts.main.family,
1822
- backgroundColor: srgbToHex(tokens.backgroundSunken.srgb),
1134
+ backgroundColor: tokens.backgroundSunken[gamut],
1823
1135
  borderWidth: 1,
1824
- borderColor: srgbToHex(tokens.border.srgb),
1136
+ borderColor: tokens.border[gamut],
1825
1137
  borderRadius: tokens.radius.md,
1826
1138
  paddingVertical: tokens.spacing["08"],
1827
1139
  paddingHorizontal: tokens.spacing["12"],
1828
1140
  fontSize: tokens.typography.fontSizes["05"],
1829
- color: disabled ? srgbToHex(tokens.textSecondary.srgb) : srgbToHex(tokens.textPrimary.srgb),
1141
+ color: disabled ? tokens.textSecondary[gamut] : tokens.textPrimary[gamut],
1830
1142
  opacity: disabled ? 0.5 : 1
1831
1143
  }
1832
1144
  });
1833
1145
  }
1146
+
1147
+ // src/composites/form-controls/TextInput/TextInput.tsx
1834
1148
  function TextInput({
1835
1149
  label,
1836
1150
  disabled = false,
@@ -1838,21 +1152,21 @@ function TextInput({
1838
1152
  ...textInputProps
1839
1153
  }) {
1840
1154
  const tokens = useTokens(1);
1841
- const styles = React14.useMemo(
1842
- () => getTextInputStyles(tokens, disabled),
1155
+ const styles = React13.useMemo(
1156
+ () => getTextInputStyles(tokens, tokens.gamut, disabled),
1843
1157
  [tokens, disabled]
1844
1158
  );
1845
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React14.createElement(
1159
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
1846
1160
  TextInput$1,
1847
1161
  {
1848
1162
  style: styles.input,
1849
1163
  editable: !disabled,
1850
- placeholderTextColor: srgbToHex(tokens.textSecondary.srgb),
1164
+ placeholderTextColor: tokens.textSecondary[tokens.gamut],
1851
1165
  ...textInputProps
1852
1166
  }
1853
1167
  ));
1854
1168
  }
1855
- function getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpen) {
1169
+ function getPopoverStyles(tokens, gamut, triggerHeight, offset, maxHeight, width, isOpen) {
1856
1170
  const widthStyle = width === "trigger" ? { left: 0, right: 0 } : typeof width === "number" ? { width, left: 0 } : { left: 0 };
1857
1171
  return StyleSheet.create({
1858
1172
  container: {
@@ -1863,9 +1177,9 @@ function getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpe
1863
1177
  position: "absolute",
1864
1178
  top: triggerHeight + offset,
1865
1179
  ...widthStyle,
1866
- backgroundColor: srgbToHex(tokens.backgroundElevated.srgb),
1180
+ backgroundColor: tokens.backgroundElevated[gamut],
1867
1181
  borderWidth: 1,
1868
- borderColor: srgbToHex(tokens.border.srgb),
1182
+ borderColor: tokens.border[gamut],
1869
1183
  borderRadius: tokens.radius.md,
1870
1184
  maxHeight,
1871
1185
  zIndex: 1e3,
@@ -1933,7 +1247,7 @@ function Popover({
1933
1247
  [closeOnEscape, onClose]
1934
1248
  );
1935
1249
  const styles = useMemo(
1936
- () => getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpen),
1250
+ () => getPopoverStyles(tokens, tokens.gamut, triggerHeight, offset, maxHeight, width, isOpen),
1937
1251
  [tokens, triggerHeight, offset, maxHeight, width, isOpen]
1938
1252
  );
1939
1253
  const containerStyles = useMemo(
@@ -1945,15 +1259,15 @@ function Popover({
1945
1259
  [styles.content, contentStyle]
1946
1260
  );
1947
1261
  const webProps = { onKeyDown: handleKeyDown };
1948
- return /* @__PURE__ */ React14.createElement(
1262
+ return /* @__PURE__ */ React13.createElement(
1949
1263
  View,
1950
1264
  {
1951
1265
  ref: containerRef,
1952
1266
  style: containerStyles,
1953
1267
  ...webProps
1954
1268
  },
1955
- /* @__PURE__ */ React14.createElement(View, { onLayout: onTriggerLayout }, trigger),
1956
- isOpen && /* @__PURE__ */ React14.createElement(View, { style: mergedContentStyles }, children)
1269
+ /* @__PURE__ */ React13.createElement(View, { onLayout: onTriggerLayout }, trigger),
1270
+ isOpen && /* @__PURE__ */ React13.createElement(View, { style: mergedContentStyles }, children)
1957
1271
  );
1958
1272
  }
1959
1273
  function usePopover(options) {
@@ -1980,7 +1294,7 @@ function usePopover(options) {
1980
1294
  function isOptionGroup(item) {
1981
1295
  return "options" in item;
1982
1296
  }
1983
- function getSelectStyles(tokens, disabled, size, isOpen) {
1297
+ function getSelectStyles(tokens, gamut, disabled, size, isOpen) {
1984
1298
  const isSm = size === "sm";
1985
1299
  const fontSize = isSm ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
1986
1300
  const iconSize = fontSize + 2;
@@ -1996,14 +1310,14 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1996
1310
  fontFamily: tokens.typography.fonts.main.family,
1997
1311
  fontSize: tokens.typography.fontSizes["04"],
1998
1312
  fontWeight: tokens.typography.fonts.main.weights.medium,
1999
- color: srgbToHex(tokens.textSecondary.srgb)
1313
+ color: tokens.textSecondary[gamut]
2000
1314
  },
2001
1315
  trigger: {
2002
1316
  flexDirection: "row",
2003
1317
  alignItems: "center",
2004
- backgroundColor: srgbToHex(tokens.backgroundSunken.srgb),
1318
+ backgroundColor: tokens.backgroundSunken[gamut],
2005
1319
  borderWidth: 1,
2006
- borderColor: srgbToHex(tokens.border.srgb),
1320
+ borderColor: tokens.border[gamut],
2007
1321
  borderRadius: tokens.radius.md,
2008
1322
  paddingVertical,
2009
1323
  paddingLeft: paddingHorizontal,
@@ -2014,7 +1328,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
2014
1328
  flex: 1,
2015
1329
  fontFamily: tokens.typography.fonts.main.family,
2016
1330
  fontSize,
2017
- color: disabled ? srgbToHex(tokens.textSecondary.srgb) : srgbToHex(tokens.textPrimary.srgb)
1331
+ color: disabled ? tokens.textSecondary[gamut] : tokens.textPrimary[gamut]
2018
1332
  },
2019
1333
  iconWrapper: {
2020
1334
  position: "absolute",
@@ -2027,7 +1341,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
2027
1341
  fontFamily: tokens.typography.fonts.main.family,
2028
1342
  fontSize: tokens.typography.fontSizes["01"],
2029
1343
  fontWeight: tokens.typography.fonts.main.weights.medium,
2030
- color: srgbToHex(tokens.textSecondary.srgb),
1344
+ color: tokens.textSecondary[gamut],
2031
1345
  textTransform: "uppercase",
2032
1346
  letterSpacing: 0.5,
2033
1347
  paddingVertical: tokens.spacing["04"],
@@ -2150,7 +1464,7 @@ function SelectOptionRow({
2150
1464
  const paddingHorizontal = size === "sm" ? tokens.spacing["08"] : tokens.spacing["12"];
2151
1465
  const fontSize = size === "sm" ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
2152
1466
  if (renderOption) {
2153
- return /* @__PURE__ */ React14.createElement(
1467
+ return /* @__PURE__ */ React13.createElement(
2154
1468
  Pressable,
2155
1469
  {
2156
1470
  onPress: option.disabled ? void 0 : onSelect,
@@ -2161,7 +1475,7 @@ function SelectOptionRow({
2161
1475
  renderOption(option, { isSelected, isFocused })
2162
1476
  );
2163
1477
  }
2164
- return /* @__PURE__ */ React14.createElement(
1478
+ return /* @__PURE__ */ React13.createElement(
2165
1479
  Pressable,
2166
1480
  {
2167
1481
  onPress: option.disabled ? void 0 : onSelect,
@@ -2177,10 +1491,10 @@ function SelectOptionRow({
2177
1491
  paddingHorizontal
2178
1492
  },
2179
1493
  isSelected && {
2180
- backgroundColor: srgbToHex(tokens.backgroundSunken.srgb)
1494
+ backgroundColor: tokens.backgroundSunken[tokens.gamut]
2181
1495
  },
2182
1496
  isFocused && !isSelected && {
2183
- backgroundColor: `${srgbToHex(tokens.border.srgb)}20`
1497
+ backgroundColor: `${tokens.border[tokens.gamut]}20`
2184
1498
  },
2185
1499
  option.disabled && {
2186
1500
  opacity: 0.5
@@ -2190,7 +1504,7 @@ function SelectOptionRow({
2190
1504
  }
2191
1505
  ]
2192
1506
  },
2193
- /* @__PURE__ */ React14.createElement(
1507
+ /* @__PURE__ */ React13.createElement(
2194
1508
  Text,
2195
1509
  {
2196
1510
  style: [
@@ -2198,30 +1512,32 @@ function SelectOptionRow({
2198
1512
  flex: 1,
2199
1513
  fontFamily: tokens.typography.fonts.main.family,
2200
1514
  fontSize,
2201
- color: srgbToHex(tokens.textPrimary.srgb)
1515
+ color: tokens.textPrimary[tokens.gamut]
2202
1516
  },
2203
1517
  isSelected && {
2204
1518
  fontWeight: tokens.typography.fonts.main.weights.medium,
2205
- color: srgbToHex(tokens.accent.fill.srgb)
1519
+ color: tokens.accent.fill[tokens.gamut]
2206
1520
  },
2207
1521
  option.disabled && {
2208
- color: srgbToHex(tokens.textSecondary.srgb)
1522
+ color: tokens.textSecondary[tokens.gamut]
2209
1523
  }
2210
1524
  ],
2211
1525
  numberOfLines: 1
2212
1526
  },
2213
1527
  option.label
2214
1528
  ),
2215
- isSelected && /* @__PURE__ */ React14.createElement(View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React14.createElement(
1529
+ isSelected && /* @__PURE__ */ React13.createElement(View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React13.createElement(
2216
1530
  Icon,
2217
1531
  {
2218
1532
  name: "check",
2219
1533
  size: fontSize,
2220
- color: srgbToHex(tokens.accent.fill.srgb)
1534
+ color: tokens.accent.fill[tokens.gamut]
2221
1535
  }
2222
1536
  ))
2223
1537
  );
2224
1538
  }
1539
+
1540
+ // src/composites/form-controls/Select/Select.tsx
2225
1541
  function flattenOptions(items) {
2226
1542
  const result = [];
2227
1543
  for (const item of items) {
@@ -2260,14 +1576,14 @@ function Select({
2260
1576
  onOpen: open
2261
1577
  });
2262
1578
  const styles = useMemo(
2263
- () => getSelectStyles(tokens, disabled, size, isOpen),
1579
+ () => getSelectStyles(tokens, tokens.gamut, disabled, size, isOpen),
2264
1580
  [tokens, disabled, size, isOpen]
2265
1581
  );
2266
1582
  const selectedOption = flatOptions.find((o) => o.value === value);
2267
1583
  const displayLabel = selectedOption?.label ?? placeholder ?? value;
2268
- const iconColor = disabled ? srgbToHex(tokens.textSecondary.srgb) : srgbToHex(tokens.textPrimary.srgb);
1584
+ const iconColor = disabled ? tokens.textSecondary[tokens.gamut] : tokens.textPrimary[tokens.gamut];
2269
1585
  const triggerWebProps = { onKeyDown: handleKeyDown };
2270
- const trigger = /* @__PURE__ */ React14.createElement(
1586
+ const trigger = /* @__PURE__ */ React13.createElement(
2271
1587
  Pressable,
2272
1588
  {
2273
1589
  onPress: disabled ? void 0 : toggle,
@@ -2277,8 +1593,8 @@ function Select({
2277
1593
  ...triggerWebProps,
2278
1594
  style: styles.trigger
2279
1595
  },
2280
- renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React14.createElement(Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
2281
- /* @__PURE__ */ React14.createElement(View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React14.createElement(
1596
+ renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React13.createElement(Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
1597
+ /* @__PURE__ */ React13.createElement(View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React13.createElement(
2282
1598
  Icon,
2283
1599
  {
2284
1600
  name: isOpen ? "expand_less" : "expand_more",
@@ -2287,14 +1603,14 @@ function Select({
2287
1603
  }
2288
1604
  ))
2289
1605
  );
2290
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React14.createElement(
1606
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
2291
1607
  Popover,
2292
1608
  {
2293
1609
  isOpen: isOpen && !disabled,
2294
1610
  onClose: close,
2295
1611
  trigger
2296
1612
  },
2297
- /* @__PURE__ */ React14.createElement(
1613
+ /* @__PURE__ */ React13.createElement(
2298
1614
  ScrollView,
2299
1615
  {
2300
1616
  bounces: false,
@@ -2303,7 +1619,7 @@ function Select({
2303
1619
  },
2304
1620
  options.map((item) => {
2305
1621
  if (isOptionGroup(item)) {
2306
- return /* @__PURE__ */ React14.createElement(View, { key: item.label }, /* @__PURE__ */ React14.createElement(Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React14.createElement(
1622
+ return /* @__PURE__ */ React13.createElement(View, { key: item.label }, /* @__PURE__ */ React13.createElement(Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React13.createElement(
2307
1623
  SelectOptionRow,
2308
1624
  {
2309
1625
  key: opt.value,
@@ -2319,7 +1635,7 @@ function Select({
2319
1635
  }
2320
1636
  )));
2321
1637
  }
2322
- return /* @__PURE__ */ React14.createElement(
1638
+ return /* @__PURE__ */ React13.createElement(
2323
1639
  SelectOptionRow,
2324
1640
  {
2325
1641
  key: item.value,
@@ -2342,7 +1658,7 @@ var TRACK_WIDTH = 40;
2342
1658
  var TRACK_HEIGHT = 22;
2343
1659
  var THUMB_SIZE = 18;
2344
1660
  var THUMB_OFFSET = 2;
2345
- function getToggleStyles(tokens, value, disabled) {
1661
+ function getToggleStyles(tokens, gamut, value, disabled) {
2346
1662
  return StyleSheet.create({
2347
1663
  container: {
2348
1664
  flexDirection: "row",
@@ -2354,13 +1670,13 @@ function getToggleStyles(tokens, value, disabled) {
2354
1670
  fontFamily: tokens.typography.fonts.main.family,
2355
1671
  fontSize: tokens.typography.fontSizes["04"],
2356
1672
  fontWeight: tokens.typography.fonts.main.weights.medium,
2357
- color: srgbToHex(tokens.textSecondary.srgb)
1673
+ color: tokens.textSecondary[gamut]
2358
1674
  },
2359
1675
  track: {
2360
1676
  width: TRACK_WIDTH,
2361
1677
  height: TRACK_HEIGHT,
2362
1678
  borderRadius: TRACK_HEIGHT / 2,
2363
- backgroundColor: value ? srgbToHex(tokens.accent.fill.srgb) : srgbToHex(tokens.border.srgb),
1679
+ backgroundColor: value ? tokens.accent.fill[gamut] : tokens.border[gamut],
2364
1680
  justifyContent: "center",
2365
1681
  paddingHorizontal: THUMB_OFFSET
2366
1682
  },
@@ -2368,7 +1684,7 @@ function getToggleStyles(tokens, value, disabled) {
2368
1684
  width: THUMB_SIZE,
2369
1685
  height: THUMB_SIZE,
2370
1686
  borderRadius: THUMB_SIZE / 2,
2371
- backgroundColor: srgbToHex(tokens.background.srgb),
1687
+ backgroundColor: tokens.background[gamut],
2372
1688
  alignSelf: value ? "flex-end" : "flex-start"
2373
1689
  }
2374
1690
  });
@@ -2383,16 +1699,16 @@ function Toggle({
2383
1699
  style
2384
1700
  }) {
2385
1701
  const tokens = useTokens(1);
2386
- const styles = React14.useMemo(
2387
- () => getToggleStyles(tokens, value, disabled),
1702
+ const styles = React13.useMemo(
1703
+ () => getToggleStyles(tokens, tokens.gamut, value, disabled),
2388
1704
  [tokens, value, disabled]
2389
1705
  );
2390
- const handlePress = React14.useCallback(() => {
1706
+ const handlePress = React13.useCallback(() => {
2391
1707
  if (!disabled) {
2392
1708
  onValueChange(!value);
2393
1709
  }
2394
1710
  }, [disabled, value, onValueChange]);
2395
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React14.createElement(
1711
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
2396
1712
  Pressable,
2397
1713
  {
2398
1714
  onPress: handlePress,
@@ -2400,12 +1716,12 @@ function Toggle({
2400
1716
  accessibilityRole: "switch",
2401
1717
  accessibilityState: { checked: value, disabled }
2402
1718
  },
2403
- /* @__PURE__ */ React14.createElement(View, { style: styles.track }, /* @__PURE__ */ React14.createElement(View, { style: styles.thumb }))
1719
+ /* @__PURE__ */ React13.createElement(View, { style: styles.track }, /* @__PURE__ */ React13.createElement(View, { style: styles.thumb }))
2404
1720
  ));
2405
1721
  }
2406
1722
  var TRACK_HEIGHT2 = 6;
2407
1723
  var THUMB_SIZE2 = 16;
2408
- function getSliderStyles(tokens, disabled) {
1724
+ function getSliderStyles(tokens, gamut, disabled) {
2409
1725
  return StyleSheet.create({
2410
1726
  container: {
2411
1727
  gap: tokens.spacing["04"],
@@ -2420,23 +1736,23 @@ function getSliderStyles(tokens, disabled) {
2420
1736
  fontFamily: tokens.typography.fonts.main.family,
2421
1737
  fontSize: tokens.typography.fontSizes["04"],
2422
1738
  fontWeight: tokens.typography.fonts.main.weights.medium,
2423
- color: srgbToHex(tokens.textSecondary.srgb)
1739
+ color: tokens.textSecondary[gamut]
2424
1740
  },
2425
1741
  value: {
2426
1742
  fontFamily: tokens.typography.fonts.main.family,
2427
1743
  fontSize: tokens.typography.fontSizes["04"],
2428
1744
  fontWeight: tokens.typography.fonts.main.weights.medium,
2429
- color: srgbToHex(tokens.textPrimary.srgb)
1745
+ color: tokens.textPrimary[gamut]
2430
1746
  },
2431
1747
  valueInput: {
2432
1748
  width: 48,
2433
1749
  paddingVertical: 0,
2434
1750
  paddingHorizontal: 4,
2435
1751
  borderWidth: 1,
2436
- borderColor: srgbToHex(tokens.border.srgb),
1752
+ borderColor: tokens.border[gamut],
2437
1753
  borderRadius: 4,
2438
1754
  backgroundColor: "transparent",
2439
- color: srgbToHex(tokens.textPrimary.srgb),
1755
+ color: tokens.textPrimary[gamut],
2440
1756
  fontFamily: tokens.typography.fonts.main.family,
2441
1757
  fontSize: tokens.typography.fontSizes["04"],
2442
1758
  fontWeight: tokens.typography.fonts.main.weights.medium,
@@ -2453,21 +1769,21 @@ function getSliderStyles(tokens, disabled) {
2453
1769
  right: 0,
2454
1770
  height: TRACK_HEIGHT2,
2455
1771
  borderRadius: TRACK_HEIGHT2 / 2,
2456
- backgroundColor: srgbToHex(tokens.border.srgb)
1772
+ backgroundColor: tokens.border[gamut]
2457
1773
  },
2458
1774
  trackFill: {
2459
1775
  position: "absolute",
2460
1776
  left: 0,
2461
1777
  height: TRACK_HEIGHT2,
2462
1778
  borderRadius: TRACK_HEIGHT2 / 2,
2463
- backgroundColor: srgbToHex(tokens.accent.fill.srgb)
1779
+ backgroundColor: tokens.accent.fill[gamut]
2464
1780
  },
2465
1781
  thumb: {
2466
1782
  position: "absolute",
2467
1783
  width: THUMB_SIZE2,
2468
1784
  height: THUMB_SIZE2,
2469
1785
  borderRadius: THUMB_SIZE2 / 2,
2470
- backgroundColor: srgbToHex(tokens.accent.fill.srgb)
1786
+ backgroundColor: tokens.accent.fill[gamut]
2471
1787
  }
2472
1788
  });
2473
1789
  }
@@ -2486,42 +1802,42 @@ function Slider({
2486
1802
  style
2487
1803
  }) {
2488
1804
  const tokens = useTokens(1);
2489
- const styles = React14.useMemo(
2490
- () => getSliderStyles(tokens, disabled),
1805
+ const styles = React13.useMemo(
1806
+ () => getSliderStyles(tokens, tokens.gamut, disabled),
2491
1807
  [tokens, disabled]
2492
1808
  );
2493
- const trackRef = React14.useRef(null);
2494
- const trackWidth = React14.useRef(0);
2495
- const trackPageX = React14.useRef(0);
2496
- const [layoutWidth, setLayoutWidth] = React14.useState(0);
2497
- const onValueChangeRef = React14.useRef(onValueChange);
2498
- const minRef = React14.useRef(min);
2499
- const maxRef = React14.useRef(max);
2500
- const stepRef = React14.useRef(step);
2501
- const disabledRef = React14.useRef(disabled);
2502
- React14.useEffect(() => {
1809
+ const trackRef = React13.useRef(null);
1810
+ const trackWidth = React13.useRef(0);
1811
+ const trackPageX = React13.useRef(0);
1812
+ const [layoutWidth, setLayoutWidth] = React13.useState(0);
1813
+ const onValueChangeRef = React13.useRef(onValueChange);
1814
+ const minRef = React13.useRef(min);
1815
+ const maxRef = React13.useRef(max);
1816
+ const stepRef = React13.useRef(step);
1817
+ const disabledRef = React13.useRef(disabled);
1818
+ React13.useEffect(() => {
2503
1819
  onValueChangeRef.current = onValueChange;
2504
1820
  }, [onValueChange]);
2505
- React14.useEffect(() => {
1821
+ React13.useEffect(() => {
2506
1822
  minRef.current = min;
2507
1823
  }, [min]);
2508
- React14.useEffect(() => {
1824
+ React13.useEffect(() => {
2509
1825
  maxRef.current = max;
2510
1826
  }, [max]);
2511
- React14.useEffect(() => {
1827
+ React13.useEffect(() => {
2512
1828
  stepRef.current = step;
2513
1829
  }, [step]);
2514
- React14.useEffect(() => {
1830
+ React13.useEffect(() => {
2515
1831
  disabledRef.current = disabled;
2516
1832
  }, [disabled]);
2517
- const computeValue = React14.useCallback((pageX) => {
1833
+ const computeValue = React13.useCallback((pageX) => {
2518
1834
  const localX = pageX - trackPageX.current;
2519
1835
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2520
1836
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2521
1837
  const stepped = Math.round(raw / stepRef.current) * stepRef.current;
2522
1838
  return Math.min(maxRef.current, Math.max(minRef.current, stepped));
2523
1839
  }, []);
2524
- const panResponder = React14.useRef(
1840
+ const panResponder = React13.useRef(
2525
1841
  PanResponder.create({
2526
1842
  onStartShouldSetPanResponder: () => !disabledRef.current,
2527
1843
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2549,7 +1865,7 @@ function Slider({
2549
1865
  fillLeft = 0;
2550
1866
  fillWidth = thumbLeft + THUMB_SIZE2 / 2;
2551
1867
  }
2552
- const handleValueTextSubmit = React14.useCallback(
1868
+ const handleValueTextSubmit = React13.useCallback(
2553
1869
  (text) => {
2554
1870
  const raw = Number(text);
2555
1871
  if (!Number.isNaN(raw)) {
@@ -2558,12 +1874,12 @@ function Slider({
2558
1874
  },
2559
1875
  [onValueChange, min, max]
2560
1876
  );
2561
- const [editText, setEditText] = React14.useState(String(value));
2562
- React14.useEffect(() => {
1877
+ const [editText, setEditText] = React13.useState(String(value));
1878
+ React13.useEffect(() => {
2563
1879
  setEditText(String(value));
2564
1880
  }, [value]);
2565
1881
  const showLabel = label || showValue || editableValue;
2566
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React14.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React14.createElement(
1882
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13.createElement(
2567
1883
  TextInput$1,
2568
1884
  {
2569
1885
  style: styles.valueInput,
@@ -2575,7 +1891,7 @@ function Slider({
2575
1891
  selectTextOnFocus: true,
2576
1892
  editable: !disabled
2577
1893
  }
2578
- ) : showValue && /* @__PURE__ */ React14.createElement(Text, { style: styles.value }, value)), /* @__PURE__ */ React14.createElement(
1894
+ ) : showValue && /* @__PURE__ */ React13.createElement(Text, { style: styles.value }, value)), /* @__PURE__ */ React13.createElement(
2579
1895
  View,
2580
1896
  {
2581
1897
  ref: trackRef,
@@ -2590,45 +1906,19 @@ function Slider({
2590
1906
  },
2591
1907
  ...panResponder.panHandlers
2592
1908
  },
2593
- /* @__PURE__ */ React14.createElement(View, { style: styles.trackRail }),
2594
- /* @__PURE__ */ React14.createElement(View, { style: [styles.trackFill, { left: fillLeft, width: fillWidth }] }),
2595
- /* @__PURE__ */ React14.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
1909
+ /* @__PURE__ */ React13.createElement(View, { style: styles.trackRail }),
1910
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.trackFill, { left: fillLeft, width: fillWidth }] }),
1911
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2596
1912
  ));
2597
1913
  }
2598
1914
  var TRACK_HEIGHT3 = 22;
2599
1915
  var THUMB_SIZE3 = 18;
2600
1916
  var SEGMENT_COUNT = 48;
2601
- function hueToHex(hue) {
2602
- const h = (hue % 360 + 360) % 360;
2603
- const x = 1 - Math.abs(h / 60 % 2 - 1);
2604
- let r, g, b;
2605
- if (h < 60) {
2606
- r = 1;
2607
- g = x;
2608
- b = 0;
2609
- } else if (h < 120) {
2610
- r = x;
2611
- g = 1;
2612
- b = 0;
2613
- } else if (h < 180) {
2614
- r = 0;
2615
- g = 1;
2616
- b = x;
2617
- } else if (h < 240) {
2618
- r = 0;
2619
- g = x;
2620
- b = 1;
2621
- } else if (h < 300) {
2622
- r = x;
2623
- g = 0;
2624
- b = 1;
2625
- } else {
2626
- r = 1;
2627
- g = 0;
2628
- b = x;
2629
- }
2630
- const toHex = (v) => Math.round(v * 255).toString(16).padStart(2, "0");
2631
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
1917
+ var OKLCH_L = 0.7;
1918
+ var OKLCH_C = 0.4;
1919
+ function hueToHex(oklchHue) {
1920
+ const { color } = gamutMapToSrgb({ L: OKLCH_L, C: OKLCH_C, h: oklchHue });
1921
+ return srgbToHex(color);
2632
1922
  }
2633
1923
  function buildHueSegments(min, max) {
2634
1924
  return Array.from({ length: SEGMENT_COUNT }, (_, i) => {
@@ -2636,7 +1926,7 @@ function buildHueSegments(min, max) {
2636
1926
  return hueToHex(hue);
2637
1927
  });
2638
1928
  }
2639
- function getHueSliderStyles(tokens, disabled) {
1929
+ function getHueSliderStyles(tokens, gamut, disabled) {
2640
1930
  return StyleSheet.create({
2641
1931
  container: {
2642
1932
  gap: tokens.spacing["04"],
@@ -2651,23 +1941,23 @@ function getHueSliderStyles(tokens, disabled) {
2651
1941
  fontFamily: tokens.typography.fonts.main.family,
2652
1942
  fontSize: tokens.typography.fontSizes["04"],
2653
1943
  fontWeight: tokens.typography.fonts.main.weights.medium,
2654
- color: srgbToHex(tokens.textSecondary.srgb)
1944
+ color: tokens.textSecondary[gamut]
2655
1945
  },
2656
1946
  value: {
2657
1947
  fontFamily: tokens.typography.fonts.main.family,
2658
1948
  fontSize: tokens.typography.fontSizes["04"],
2659
1949
  fontWeight: tokens.typography.fonts.main.weights.medium,
2660
- color: srgbToHex(tokens.textPrimary.srgb)
1950
+ color: tokens.textPrimary[gamut]
2661
1951
  },
2662
1952
  valueInput: {
2663
1953
  width: 48,
2664
1954
  paddingVertical: 0,
2665
1955
  paddingHorizontal: 4,
2666
1956
  borderWidth: 1,
2667
- borderColor: srgbToHex(tokens.border.srgb),
1957
+ borderColor: tokens.border[gamut],
2668
1958
  borderRadius: 4,
2669
1959
  backgroundColor: "transparent",
2670
- color: srgbToHex(tokens.textPrimary.srgb),
1960
+ color: tokens.textPrimary[gamut],
2671
1961
  fontFamily: tokens.typography.fonts.main.family,
2672
1962
  fontSize: tokens.typography.fontSizes["04"],
2673
1963
  fontWeight: tokens.typography.fonts.main.weights.medium,
@@ -2697,7 +1987,7 @@ function getHueSliderStyles(tokens, disabled) {
2697
1987
  borderRadius: THUMB_SIZE3 / 2,
2698
1988
  backgroundColor: "#ffffff",
2699
1989
  borderWidth: 2,
2700
- borderColor: srgbToHex(tokens.border.srgb)
1990
+ borderColor: tokens.border[gamut]
2701
1991
  }
2702
1992
  });
2703
1993
  }
@@ -2707,7 +1997,7 @@ function HueSlider({
2707
1997
  value,
2708
1998
  onValueChange,
2709
1999
  min = 0,
2710
- max = 359,
2000
+ max = 360,
2711
2001
  label,
2712
2002
  showValue = false,
2713
2003
  editableValue = false,
@@ -2715,42 +2005,42 @@ function HueSlider({
2715
2005
  style
2716
2006
  }) {
2717
2007
  const tokens = useTokens(1);
2718
- const styles = React14.useMemo(
2719
- () => getHueSliderStyles(tokens, disabled),
2008
+ const styles = React13.useMemo(
2009
+ () => getHueSliderStyles(tokens, tokens.gamut, disabled),
2720
2010
  [tokens, disabled]
2721
2011
  );
2722
- const segments = React14.useMemo(
2012
+ const segments = React13.useMemo(
2723
2013
  () => buildHueSegments(min, max),
2724
2014
  [min, max]
2725
2015
  );
2726
- const trackRef = React14.useRef(null);
2727
- const trackWidth = React14.useRef(0);
2728
- const trackPageX = React14.useRef(0);
2729
- const [layoutWidth, setLayoutWidth] = React14.useState(0);
2730
- const onValueChangeRef = React14.useRef(onValueChange);
2731
- const minRef = React14.useRef(min);
2732
- const maxRef = React14.useRef(max);
2733
- const disabledRef = React14.useRef(disabled);
2734
- React14.useEffect(() => {
2016
+ const trackRef = React13.useRef(null);
2017
+ const trackWidth = React13.useRef(0);
2018
+ const trackPageX = React13.useRef(0);
2019
+ const [layoutWidth, setLayoutWidth] = React13.useState(0);
2020
+ const onValueChangeRef = React13.useRef(onValueChange);
2021
+ const minRef = React13.useRef(min);
2022
+ const maxRef = React13.useRef(max);
2023
+ const disabledRef = React13.useRef(disabled);
2024
+ React13.useEffect(() => {
2735
2025
  onValueChangeRef.current = onValueChange;
2736
2026
  }, [onValueChange]);
2737
- React14.useEffect(() => {
2027
+ React13.useEffect(() => {
2738
2028
  minRef.current = min;
2739
2029
  }, [min]);
2740
- React14.useEffect(() => {
2030
+ React13.useEffect(() => {
2741
2031
  maxRef.current = max;
2742
2032
  }, [max]);
2743
- React14.useEffect(() => {
2033
+ React13.useEffect(() => {
2744
2034
  disabledRef.current = disabled;
2745
2035
  }, [disabled]);
2746
- const computeHue = React14.useCallback((pageX) => {
2036
+ const computeHue = React13.useCallback((pageX) => {
2747
2037
  const localX = pageX - trackPageX.current;
2748
2038
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2749
2039
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2750
2040
  const stepped = Math.round(raw);
2751
2041
  return (stepped % 360 + 360) % 360;
2752
2042
  }, []);
2753
- const panResponder = React14.useRef(
2043
+ const panResponder = React13.useRef(
2754
2044
  PanResponder.create({
2755
2045
  onStartShouldSetPanResponder: () => !disabledRef.current,
2756
2046
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2762,11 +2052,11 @@ function HueSlider({
2762
2052
  }
2763
2053
  })
2764
2054
  ).current;
2765
- const sliderValue = max > 359 && value < min ? value + 360 : value;
2055
+ const sliderValue = max > 360 && value < min ? value + 360 : value;
2766
2056
  const ratio = max > min ? (sliderValue - min) / (max - min) : 0;
2767
2057
  const usableWidth = Math.max(0, layoutWidth - THUMB_SIZE3);
2768
2058
  const thumbLeft = ratio * usableWidth;
2769
- const handleValueTextSubmit = React14.useCallback(
2059
+ const handleValueTextSubmit = React13.useCallback(
2770
2060
  (text) => {
2771
2061
  const raw = Number(text);
2772
2062
  if (!Number.isNaN(raw)) {
@@ -2775,12 +2065,12 @@ function HueSlider({
2775
2065
  },
2776
2066
  [onValueChange]
2777
2067
  );
2778
- const [editText, setEditText] = React14.useState(String(value));
2779
- React14.useEffect(() => {
2068
+ const [editText, setEditText] = React13.useState(String(value));
2069
+ React13.useEffect(() => {
2780
2070
  setEditText(String(value));
2781
2071
  }, [value]);
2782
2072
  const showLabel = label || showValue || editableValue;
2783
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React14.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React14.createElement(
2073
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13.createElement(
2784
2074
  TextInput$1,
2785
2075
  {
2786
2076
  style: styles.valueInput,
@@ -2792,7 +2082,7 @@ function HueSlider({
2792
2082
  selectTextOnFocus: true,
2793
2083
  editable: !disabled
2794
2084
  }
2795
- ) : showValue && /* @__PURE__ */ React14.createElement(Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React14.createElement(
2085
+ ) : showValue && /* @__PURE__ */ React13.createElement(Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React13.createElement(
2796
2086
  View,
2797
2087
  {
2798
2088
  ref: trackRef,
@@ -2807,13 +2097,69 @@ function HueSlider({
2807
2097
  },
2808
2098
  ...panResponder.panHandlers
2809
2099
  },
2810
- /* @__PURE__ */ React14.createElement(View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React14.createElement(View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2811
- /* @__PURE__ */ React14.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2100
+ /* @__PURE__ */ React13.createElement(View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React13.createElement(View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2101
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2812
2102
  ));
2813
2103
  }
2104
+
2105
+ // node_modules/@newtonedev/colors/dist/index.js
2106
+ var SRGB_GAMMA_THRESHOLD_LINEAR = 31308e-7;
2107
+ var SRGB_GAMMA_SLOPE = 12.92;
2108
+ var SRGB_GAMMA_EXPONENT = 2.4;
2109
+ var SRGB_GAMMA_OFFSET = 0.055;
2110
+ var SRGB_GAMMA_SCALE = 1.055;
2111
+ var OKLAB_TO_LMS_PRIME = [
2112
+ [1, 0.3963377774, 0.2158037573],
2113
+ [1, -0.1055613458, -0.0638541728],
2114
+ [1, -0.0894841775, -1.291485548]
2115
+ ];
2116
+ var LMS_TO_LINEAR_P3 = [
2117
+ [3.127769439, -2.2570600176, 0.1291828502],
2118
+ [-1.0910091977, 2.4133065499, -0.3222615148],
2119
+ [-0.0260108068, -0.5080402362, 1.5340494942]
2120
+ ];
2121
+ var DEG_TO_RAD = Math.PI / 180;
2122
+ function oklchToOklab(lch) {
2123
+ const hRad = lch.h * DEG_TO_RAD;
2124
+ return {
2125
+ L: lch.L,
2126
+ a: lch.C * Math.cos(hRad),
2127
+ b: lch.C * Math.sin(hRad)
2128
+ };
2129
+ }
2130
+ function oklabToLinearP3(color) {
2131
+ const lp = OKLAB_TO_LMS_PRIME[0][0] * color.L + OKLAB_TO_LMS_PRIME[0][1] * color.a + OKLAB_TO_LMS_PRIME[0][2] * color.b;
2132
+ const mp = OKLAB_TO_LMS_PRIME[1][0] * color.L + OKLAB_TO_LMS_PRIME[1][1] * color.a + OKLAB_TO_LMS_PRIME[1][2] * color.b;
2133
+ const sp = OKLAB_TO_LMS_PRIME[2][0] * color.L + OKLAB_TO_LMS_PRIME[2][1] * color.a + OKLAB_TO_LMS_PRIME[2][2] * color.b;
2134
+ const l = lp * lp * lp;
2135
+ const m = mp * mp * mp;
2136
+ const s = sp * sp * sp;
2137
+ return {
2138
+ r: LMS_TO_LINEAR_P3[0][0] * l + LMS_TO_LINEAR_P3[0][1] * m + LMS_TO_LINEAR_P3[0][2] * s,
2139
+ g: LMS_TO_LINEAR_P3[1][0] * l + LMS_TO_LINEAR_P3[1][1] * m + LMS_TO_LINEAR_P3[1][2] * s,
2140
+ b: LMS_TO_LINEAR_P3[2][0] * l + LMS_TO_LINEAR_P3[2][1] * m + LMS_TO_LINEAR_P3[2][2] * s
2141
+ };
2142
+ }
2143
+ function linearChannelToSrgb(value) {
2144
+ return value <= SRGB_GAMMA_THRESHOLD_LINEAR ? value * SRGB_GAMMA_SLOPE : SRGB_GAMMA_SCALE * value ** (1 / SRGB_GAMMA_EXPONENT) - SRGB_GAMMA_OFFSET;
2145
+ }
2146
+ function linearSrgbToSrgb(color) {
2147
+ return {
2148
+ r: linearChannelToSrgb(color.r),
2149
+ g: linearChannelToSrgb(color.g),
2150
+ b: linearChannelToSrgb(color.b)
2151
+ };
2152
+ }
2153
+ function oklchToP3(color) {
2154
+ return linearSrgbToSrgb(oklabToLinearP3(oklchToOklab(color)));
2155
+ }
2156
+ function oklchToP3Css(color) {
2157
+ const { r, g, b } = oklchToP3(color);
2158
+ return `color(display-p3 ${r} ${g} ${b})`;
2159
+ }
2814
2160
  var TRACK_HEIGHT4 = 22;
2815
2161
  var THUMB_SIZE4 = 18;
2816
- function getColorScaleSliderStyles(tokens, disabled) {
2162
+ function getColorScaleSliderStyles(tokens, gamut, disabled) {
2817
2163
  return StyleSheet.create({
2818
2164
  container: {
2819
2165
  gap: tokens.spacing["04"],
@@ -2828,7 +2174,7 @@ function getColorScaleSliderStyles(tokens, disabled) {
2828
2174
  fontFamily: tokens.typography.fonts.main.family,
2829
2175
  fontSize: tokens.typography.fontSizes["04"],
2830
2176
  fontWeight: tokens.typography.fonts.main.weights.medium,
2831
- color: srgbToHex(tokens.textSecondary.srgb)
2177
+ color: tokens.textSecondary[gamut]
2832
2178
  },
2833
2179
  trackContainer: {
2834
2180
  height: TRACK_HEIGHT4 + THUMB_SIZE4,
@@ -2854,13 +2200,13 @@ function getColorScaleSliderStyles(tokens, disabled) {
2854
2200
  borderRadius: THUMB_SIZE4 / 2,
2855
2201
  backgroundColor: "#ffffff",
2856
2202
  borderWidth: 2,
2857
- borderColor: srgbToHex(tokens.border.srgb)
2203
+ borderColor: tokens.border[gamut]
2858
2204
  },
2859
2205
  warning: {
2860
2206
  fontFamily: tokens.typography.fonts.main.family,
2861
2207
  fontSize: tokens.typography.fontSizes["01"],
2862
2208
  fontWeight: tokens.typography.fonts.main.weights.medium,
2863
- color: srgbToHex(tokens.error.fill.srgb)
2209
+ color: tokens.error.fill[gamut]
2864
2210
  }
2865
2211
  });
2866
2212
  }
@@ -2876,40 +2222,41 @@ function ColorScaleSlider({
2876
2222
  snap = false,
2877
2223
  disabled = false,
2878
2224
  animateValue = false,
2225
+ useP3: _useP3,
2879
2226
  style
2880
2227
  }) {
2881
2228
  const tokens = useTokens(1);
2882
- const styles = React14.useMemo(
2883
- () => getColorScaleSliderStyles(tokens, disabled),
2229
+ const styles = React13.useMemo(
2230
+ () => getColorScaleSliderStyles(tokens, tokens.gamut, disabled),
2884
2231
  [tokens, disabled]
2885
2232
  );
2886
- const trackRef = React14.useRef(null);
2887
- const trackWidth = React14.useRef(0);
2888
- const trackPageX = React14.useRef(0);
2889
- const isDragging = React14.useRef(false);
2890
- const thumbAnim = React14.useRef(new Animated.Value(0)).current;
2891
- const [layoutWidth, setLayoutWidth] = React14.useState(0);
2892
- const onValueChangeRef = React14.useRef(onValueChange);
2893
- const disabledRef = React14.useRef(disabled);
2894
- const colorsLengthRef = React14.useRef(colors.length);
2895
- const trimEndsRef = React14.useRef(trimEnds);
2896
- const snapRef = React14.useRef(snap);
2897
- React14.useEffect(() => {
2233
+ const trackRef = React13.useRef(null);
2234
+ const trackWidth = React13.useRef(0);
2235
+ const trackPageX = React13.useRef(0);
2236
+ const isDragging = React13.useRef(false);
2237
+ const thumbAnim = React13.useRef(new Animated.Value(0)).current;
2238
+ const [layoutWidth, setLayoutWidth] = React13.useState(0);
2239
+ const onValueChangeRef = React13.useRef(onValueChange);
2240
+ const disabledRef = React13.useRef(disabled);
2241
+ const colorsLengthRef = React13.useRef(colors.length);
2242
+ const trimEndsRef = React13.useRef(trimEnds);
2243
+ const snapRef = React13.useRef(snap);
2244
+ React13.useEffect(() => {
2898
2245
  onValueChangeRef.current = onValueChange;
2899
2246
  }, [onValueChange]);
2900
- React14.useEffect(() => {
2247
+ React13.useEffect(() => {
2901
2248
  disabledRef.current = disabled;
2902
2249
  }, [disabled]);
2903
- React14.useEffect(() => {
2250
+ React13.useEffect(() => {
2904
2251
  colorsLengthRef.current = colors.length;
2905
2252
  }, [colors.length]);
2906
- React14.useEffect(() => {
2253
+ React13.useEffect(() => {
2907
2254
  trimEndsRef.current = trimEnds;
2908
2255
  }, [trimEnds]);
2909
- React14.useEffect(() => {
2256
+ React13.useEffect(() => {
2910
2257
  snapRef.current = snap;
2911
2258
  }, [snap]);
2912
- const computeNv = React14.useCallback((pageX) => {
2259
+ const computeNv = React13.useCallback((pageX) => {
2913
2260
  const localX = pageX - trackPageX.current;
2914
2261
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2915
2262
  const totalSteps2 = colorsLengthRef.current - 1;
@@ -2924,7 +2271,7 @@ function ColorScaleSlider({
2924
2271
  }
2925
2272
  return nv;
2926
2273
  }, []);
2927
- const panResponder = React14.useRef(
2274
+ const panResponder = React13.useRef(
2928
2275
  PanResponder.create({
2929
2276
  onStartShouldSetPanResponder: () => !disabledRef.current,
2930
2277
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2952,7 +2299,7 @@ function ColorScaleSlider({
2952
2299
  const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
2953
2300
  const usableWidth = Math.max(0, layoutWidth - THUMB_SIZE4);
2954
2301
  const thumbLeft = ratio * usableWidth;
2955
- React14.useEffect(() => {
2302
+ React13.useEffect(() => {
2956
2303
  if (isDragging.current || !animateValue) {
2957
2304
  thumbAnim.setValue(thumbLeft);
2958
2305
  } else {
@@ -2963,7 +2310,7 @@ function ColorScaleSlider({
2963
2310
  }).start();
2964
2311
  }
2965
2312
  }, [thumbLeft, animateValue, thumbAnim]);
2966
- return /* @__PURE__ */ React14.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14.createElement(View, { style: styles.labelRow }, /* @__PURE__ */ React14.createElement(Text, { style: styles.label }, label)), /* @__PURE__ */ React14.createElement(
2313
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label)), /* @__PURE__ */ React13.createElement(
2967
2314
  View,
2968
2315
  {
2969
2316
  ref: trackRef,
@@ -2978,17 +2325,17 @@ function ColorScaleSlider({
2978
2325
  },
2979
2326
  ...panResponder.panHandlers
2980
2327
  },
2981
- /* @__PURE__ */ React14.createElement(View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React14.createElement(View, { key: i, style: [styles.segment, { backgroundColor: srgbToHex(color.srgb) }] }))),
2982
- /* @__PURE__ */ React14.createElement(Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2983
- ), warning && /* @__PURE__ */ React14.createElement(Text, { style: styles.warning }, warning));
2328
+ /* @__PURE__ */ React13.createElement(View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React13.createElement(View, { key: i, style: [styles.segment, { backgroundColor: tokens.gamut === "p3" ? oklchToP3Css(color.oklch) : srgbToHex(color.srgb) }] }))),
2329
+ /* @__PURE__ */ React13.createElement(Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2330
+ ), warning && /* @__PURE__ */ React13.createElement(Text, { style: styles.warning }, warning));
2984
2331
  }
2985
- function getAppShellStyles(tokens) {
2332
+ function getAppShellStyles(tokens, gamut) {
2986
2333
  return StyleSheet.create({
2987
2334
  container: {
2988
2335
  flex: 1,
2989
2336
  flexDirection: "row",
2990
2337
  overflow: "hidden",
2991
- backgroundColor: srgbToHex(tokens.background.srgb)
2338
+ backgroundColor: tokens.background[gamut]
2992
2339
  },
2993
2340
  main: {
2994
2341
  flex: 1,
@@ -3002,17 +2349,17 @@ function getAppShellStyles(tokens) {
3002
2349
  // src/composites/layout/AppShell/AppShell.tsx
3003
2350
  function AppShell({ sidebar, children }) {
3004
2351
  const tokens = useTokens();
3005
- const styles = React14.useMemo(() => getAppShellStyles(tokens), [tokens]);
3006
- return /* @__PURE__ */ React14.createElement(View, { style: styles.container }, sidebar, /* @__PURE__ */ React14.createElement(View, { style: styles.main }, children));
2352
+ const styles = React13.useMemo(() => getAppShellStyles(tokens, tokens.gamut), [tokens]);
2353
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, sidebar, /* @__PURE__ */ React13.createElement(View, { style: styles.main }, children));
3007
2354
  }
3008
- function getSidebarStyles({ tokens, width, bordered }) {
3009
- const borderColor = srgbToHex(tokens.border.srgb);
2355
+ function getSidebarStyles({ tokens, gamut, width, bordered }) {
2356
+ const borderColor = tokens.border[gamut];
3010
2357
  return StyleSheet.create({
3011
2358
  container: {
3012
2359
  width,
3013
2360
  flexShrink: 0,
3014
2361
  flexDirection: "column",
3015
- backgroundColor: srgbToHex(tokens.background.srgb),
2362
+ backgroundColor: tokens.background[gamut],
3016
2363
  borderRightWidth: bordered ? 1 : 0,
3017
2364
  borderRightColor: borderColor
3018
2365
  },
@@ -3041,14 +2388,14 @@ function Sidebar({
3041
2388
  bordered = true
3042
2389
  }) {
3043
2390
  const tokens = useTokens();
3044
- const styles = React14.useMemo(
3045
- () => getSidebarStyles({ tokens, width, bordered }),
2391
+ const styles = React13.useMemo(
2392
+ () => getSidebarStyles({ tokens, gamut: tokens.gamut, width, bordered }),
3046
2393
  [tokens, width, bordered]
3047
2394
  );
3048
- return /* @__PURE__ */ React14.createElement(View, { style: styles.container }, header && /* @__PURE__ */ React14.createElement(View, { style: styles.header }, header), /* @__PURE__ */ React14.createElement(ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React14.createElement(View, { style: styles.footer }, footer));
2395
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, header && /* @__PURE__ */ React13.createElement(View, { style: styles.header }, header), /* @__PURE__ */ React13.createElement(ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React13.createElement(View, { style: styles.footer }, footer));
3049
2396
  }
3050
- function getNavbarStyles({ tokens, height, bordered }) {
3051
- const borderColor = srgbToHex(tokens.border.srgb);
2397
+ function getNavbarStyles({ tokens, gamut, height, bordered }) {
2398
+ const borderColor = tokens.border[gamut];
3052
2399
  return StyleSheet.create({
3053
2400
  container: {
3054
2401
  flexDirection: "row",
@@ -3056,7 +2403,7 @@ function getNavbarStyles({ tokens, height, bordered }) {
3056
2403
  height,
3057
2404
  flexShrink: 0,
3058
2405
  paddingHorizontal: 24,
3059
- backgroundColor: srgbToHex(tokens.background.srgb),
2406
+ backgroundColor: tokens.background[gamut],
3060
2407
  borderBottomWidth: bordered ? 1 : 0,
3061
2408
  borderBottomColor: borderColor
3062
2409
  },
@@ -3083,11 +2430,11 @@ function Navbar({
3083
2430
  bordered = true
3084
2431
  }) {
3085
2432
  const tokens = useTokens();
3086
- const styles = React14.useMemo(
3087
- () => getNavbarStyles({ tokens, height, bordered }),
2433
+ const styles = React13.useMemo(
2434
+ () => getNavbarStyles({ tokens, gamut: tokens.gamut, height, bordered }),
3088
2435
  [tokens, height, bordered]
3089
2436
  );
3090
- return /* @__PURE__ */ React14.createElement(View, { style: styles.container }, children ? children : /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(View, { style: styles.left }, left), /* @__PURE__ */ React14.createElement(View, { style: styles.right }, right)));
2437
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, children ? children : /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(View, { style: styles.left }, left), /* @__PURE__ */ React13.createElement(View, { style: styles.right }, right)));
3091
2438
  }
3092
2439
 
3093
2440
  // src/registry/registry.ts
@@ -4035,6 +3382,6 @@ var ICON_CATALOG = [
4035
3382
  }
4036
3383
  ];
4037
3384
 
4038
- export { ACCENT_DEFAULTS, AppShell, Button, CATEGORIES, COMPONENTS, Card, ColorScaleSlider, DEFAULT_THEME_CONFIG, ERROR_DEFAULTS, Frame, HueSlider, ICON_CATALOG, Icon, NEUTRAL_DEFAULTS, Navbar, NewtoneProvider, Popover, SUCCESS_DEFAULTS, Select, Sidebar, Slider, Text2 as Text, TextInput, Toggle, WARNING_DEFAULTS, Wrapper, computeTokens, generateComponentCode, getCategory, getComponent, getComponentsByCategory, isOptionGroup, measureAvgCharWidth, useFocusVisible, useFrameContext, useLocalCalibration, useNewtoneTheme, usePopover, useTokens, useTypographyCalibrations };
3385
+ export { AppShell, Button, CATEGORIES, COMPONENTS, Card, ColorScaleSlider, Frame, HueSlider, ICON_CATALOG, Icon, Navbar, Popover, Select, Sidebar, Slider, Text3 as Text, TextInput, Toggle, Wrapper, generateComponentCode, getCategory, getComponent, getComponentsByCategory, isOptionGroup, useFocusVisible, usePopover };
4039
3386
  //# sourceMappingURL=index.js.map
4040
3387
  //# sourceMappingURL=index.js.map