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