@newtonedev/components 0.1.4 → 0.1.6

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 (255) hide show
  1. package/dist/composites/actions/Button/Button.d.ts +37 -0
  2. package/dist/composites/actions/Button/Button.d.ts.map +1 -0
  3. package/dist/composites/actions/Button/Button.styles.d.ts +65 -0
  4. package/dist/composites/actions/Button/Button.styles.d.ts.map +1 -0
  5. package/dist/{Button → composites/actions/Button}/Button.types.d.ts +12 -3
  6. package/dist/composites/actions/Button/Button.types.d.ts.map +1 -0
  7. package/dist/composites/actions/Button/index.d.ts.map +1 -0
  8. package/dist/composites/form-controls/Select/Select.d.ts.map +1 -0
  9. package/dist/{Select → composites/form-controls/Select}/Select.styles.d.ts +1 -1
  10. package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -0
  11. package/dist/composites/form-controls/Select/Select.types.d.ts.map +1 -0
  12. package/dist/composites/form-controls/Select/SelectOption.d.ts.map +1 -0
  13. package/dist/composites/form-controls/Select/index.d.ts.map +1 -0
  14. package/dist/composites/form-controls/Select/useSelect.d.ts.map +1 -0
  15. package/dist/composites/form-controls/TextInput/TextInput.d.ts.map +1 -0
  16. package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.styles.d.ts +1 -1
  17. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -0
  18. package/dist/composites/form-controls/TextInput/TextInput.types.d.ts.map +1 -0
  19. package/dist/composites/form-controls/TextInput/index.d.ts.map +1 -0
  20. package/dist/composites/form-controls/Toggle/Toggle.d.ts.map +1 -0
  21. package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.styles.d.ts +1 -1
  22. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -0
  23. package/dist/composites/form-controls/Toggle/Toggle.types.d.ts.map +1 -0
  24. package/dist/composites/form-controls/Toggle/index.d.ts.map +1 -0
  25. package/dist/composites/layout/AppShell/AppShell.d.ts.map +1 -0
  26. package/dist/{AppShell → composites/layout/AppShell}/AppShell.styles.d.ts +1 -1
  27. package/dist/composites/layout/AppShell/AppShell.styles.d.ts.map +1 -0
  28. package/dist/composites/layout/AppShell/AppShell.types.d.ts.map +1 -0
  29. package/dist/composites/layout/AppShell/index.d.ts.map +1 -0
  30. package/dist/composites/layout/Card/Card.d.ts.map +1 -0
  31. package/dist/{Card → composites/layout/Card}/Card.styles.d.ts +1 -1
  32. package/dist/composites/layout/Card/Card.styles.d.ts.map +1 -0
  33. package/dist/{Card → composites/layout/Card}/Card.types.d.ts +1 -1
  34. package/dist/composites/layout/Card/Card.types.d.ts.map +1 -0
  35. package/dist/composites/layout/Card/index.d.ts.map +1 -0
  36. package/dist/composites/layout/Navbar/Navbar.d.ts.map +1 -0
  37. package/dist/{Navbar → composites/layout/Navbar}/Navbar.styles.d.ts +1 -1
  38. package/dist/composites/layout/Navbar/Navbar.styles.d.ts.map +1 -0
  39. package/dist/composites/layout/Navbar/Navbar.types.d.ts.map +1 -0
  40. package/dist/composites/layout/Navbar/index.d.ts.map +1 -0
  41. package/dist/composites/layout/Sidebar/Sidebar.d.ts.map +1 -0
  42. package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.styles.d.ts +1 -1
  43. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts.map +1 -0
  44. package/dist/composites/layout/Sidebar/Sidebar.types.d.ts.map +1 -0
  45. package/dist/composites/layout/Sidebar/index.d.ts.map +1 -0
  46. package/dist/composites/overlays/Popover/Popover.d.ts.map +1 -0
  47. package/dist/{Popover → composites/overlays/Popover}/Popover.styles.d.ts +1 -1
  48. package/dist/composites/overlays/Popover/Popover.styles.d.ts.map +1 -0
  49. package/dist/composites/overlays/Popover/Popover.types.d.ts.map +1 -0
  50. package/dist/composites/overlays/Popover/index.d.ts.map +1 -0
  51. package/dist/composites/overlays/Popover/usePopover.d.ts.map +1 -0
  52. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts.map +1 -0
  53. package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.styles.d.ts +1 -1
  54. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -0
  55. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.types.d.ts.map +1 -0
  56. package/dist/composites/range-inputs/ColorScaleSlider/index.d.ts.map +1 -0
  57. package/dist/composites/range-inputs/HueSlider/HueSlider.d.ts.map +1 -0
  58. package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.styles.d.ts +1 -1
  59. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -0
  60. package/dist/composites/range-inputs/HueSlider/HueSlider.types.d.ts.map +1 -0
  61. package/dist/composites/range-inputs/HueSlider/index.d.ts.map +1 -0
  62. package/dist/composites/range-inputs/Slider/Slider.d.ts.map +1 -0
  63. package/dist/{Slider → composites/range-inputs/Slider}/Slider.styles.d.ts +1 -1
  64. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -0
  65. package/dist/composites/range-inputs/Slider/Slider.types.d.ts.map +1 -0
  66. package/dist/composites/range-inputs/Slider/index.d.ts.map +1 -0
  67. package/dist/index.cjs +1277 -764
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.ts +30 -29
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +1234 -726
  72. package/dist/index.js.map +1 -1
  73. package/dist/primitives/Frame/Frame.d.ts +2 -3
  74. package/dist/primitives/Frame/Frame.d.ts.map +1 -1
  75. package/dist/primitives/Frame/Frame.types.d.ts +4 -15
  76. package/dist/primitives/Frame/Frame.types.d.ts.map +1 -1
  77. package/dist/primitives/Icon/Icon.d.ts.map +1 -1
  78. package/dist/primitives/Text/Text.d.ts.map +1 -1
  79. package/dist/primitives/Text/Text.types.d.ts +9 -4
  80. package/dist/primitives/Text/Text.types.d.ts.map +1 -1
  81. package/dist/primitives/Wrapper/Wrapper.d.ts +1 -1
  82. package/dist/primitives/Wrapper/Wrapper.types.d.ts +1 -1
  83. package/dist/registry/registry.d.ts.map +1 -1
  84. package/dist/theme/FrameContext.d.ts +7 -5
  85. package/dist/theme/FrameContext.d.ts.map +1 -1
  86. package/dist/theme/NewtoneProvider.d.ts +5 -6
  87. package/dist/theme/NewtoneProvider.d.ts.map +1 -1
  88. package/dist/theme/defaults.d.ts.map +1 -1
  89. package/dist/theme/types.d.ts +38 -24
  90. package/dist/theme/types.d.ts.map +1 -1
  91. package/dist/tokens/computeTokens.d.ts +82 -7
  92. package/dist/tokens/computeTokens.d.ts.map +1 -1
  93. package/dist/tokens/types.d.ts +66 -14
  94. package/dist/tokens/types.d.ts.map +1 -1
  95. package/dist/tokens/useTokens.d.ts +11 -14
  96. package/dist/tokens/useTokens.d.ts.map +1 -1
  97. package/package.json +1 -1
  98. package/src/composites/actions/Button/Button.styles.ts +338 -0
  99. package/src/composites/actions/Button/Button.tsx +119 -0
  100. package/src/{Button → composites/actions/Button}/Button.types.ts +14 -3
  101. package/src/{Select → composites/form-controls/Select}/Select.styles.ts +1 -1
  102. package/src/{Select → composites/form-controls/Select}/Select.tsx +4 -4
  103. package/src/{Select → composites/form-controls/Select}/SelectOption.tsx +4 -4
  104. package/src/{TextInput → composites/form-controls/TextInput}/TextInput.styles.ts +1 -1
  105. package/src/{TextInput → composites/form-controls/TextInput}/TextInput.tsx +1 -1
  106. package/src/{Toggle → composites/form-controls/Toggle}/Toggle.styles.ts +2 -2
  107. package/src/{Toggle → composites/form-controls/Toggle}/Toggle.tsx +1 -1
  108. package/src/{AppShell → composites/layout/AppShell}/AppShell.styles.ts +1 -1
  109. package/src/{AppShell → composites/layout/AppShell}/AppShell.tsx +1 -1
  110. package/src/{Card → composites/layout/Card}/Card.styles.ts +1 -1
  111. package/src/{Card → composites/layout/Card}/Card.tsx +1 -1
  112. package/src/{Card → composites/layout/Card}/Card.types.ts +1 -1
  113. package/src/{Navbar → composites/layout/Navbar}/Navbar.styles.ts +1 -1
  114. package/src/{Navbar → composites/layout/Navbar}/Navbar.tsx +1 -1
  115. package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.styles.ts +1 -1
  116. package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.tsx +1 -1
  117. package/src/{Popover → composites/overlays/Popover}/Popover.styles.ts +1 -1
  118. package/src/{Popover → composites/overlays/Popover}/Popover.tsx +1 -1
  119. package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.styles.ts +2 -2
  120. package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.tsx +1 -1
  121. package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.styles.ts +1 -1
  122. package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.tsx +1 -1
  123. package/src/{Slider → composites/range-inputs/Slider}/Slider.styles.ts +3 -3
  124. package/src/{Slider → composites/range-inputs/Slider}/Slider.tsx +1 -1
  125. package/src/index.ts +40 -33
  126. package/src/primitives/Frame/Frame.tsx +10 -18
  127. package/src/primitives/Frame/Frame.types.ts +5 -17
  128. package/src/primitives/Icon/Icon.tsx +16 -1
  129. package/src/primitives/Text/Text.tsx +18 -8
  130. package/src/primitives/Text/Text.types.ts +9 -4
  131. package/src/primitives/Wrapper/Wrapper.tsx +1 -1
  132. package/src/primitives/Wrapper/Wrapper.types.ts +1 -1
  133. package/src/registry/registry.ts +239 -6
  134. package/src/theme/FrameContext.tsx +7 -5
  135. package/src/theme/NewtoneProvider.tsx +5 -10
  136. package/src/theme/defaults.ts +0 -9
  137. package/src/theme/types.ts +53 -26
  138. package/src/tokens/computeTokens.ts +351 -113
  139. package/src/tokens/types.ts +82 -14
  140. package/src/tokens/useTokens.ts +29 -24
  141. package/dist/AppShell/AppShell.d.ts.map +0 -1
  142. package/dist/AppShell/AppShell.styles.d.ts.map +0 -1
  143. package/dist/AppShell/AppShell.types.d.ts.map +0 -1
  144. package/dist/AppShell/index.d.ts.map +0 -1
  145. package/dist/Button/Button.d.ts +0 -28
  146. package/dist/Button/Button.d.ts.map +0 -1
  147. package/dist/Button/Button.styles.d.ts +0 -46
  148. package/dist/Button/Button.styles.d.ts.map +0 -1
  149. package/dist/Button/Button.types.d.ts.map +0 -1
  150. package/dist/Button/index.d.ts.map +0 -1
  151. package/dist/Card/Card.d.ts.map +0 -1
  152. package/dist/Card/Card.styles.d.ts.map +0 -1
  153. package/dist/Card/Card.types.d.ts.map +0 -1
  154. package/dist/Card/index.d.ts.map +0 -1
  155. package/dist/ColorScaleSlider/ColorScaleSlider.d.ts.map +0 -1
  156. package/dist/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +0 -1
  157. package/dist/ColorScaleSlider/ColorScaleSlider.types.d.ts.map +0 -1
  158. package/dist/ColorScaleSlider/index.d.ts.map +0 -1
  159. package/dist/HueSlider/HueSlider.d.ts.map +0 -1
  160. package/dist/HueSlider/HueSlider.styles.d.ts.map +0 -1
  161. package/dist/HueSlider/HueSlider.types.d.ts.map +0 -1
  162. package/dist/HueSlider/index.d.ts.map +0 -1
  163. package/dist/Navbar/Navbar.d.ts.map +0 -1
  164. package/dist/Navbar/Navbar.styles.d.ts.map +0 -1
  165. package/dist/Navbar/Navbar.types.d.ts.map +0 -1
  166. package/dist/Navbar/index.d.ts.map +0 -1
  167. package/dist/Popover/Popover.d.ts.map +0 -1
  168. package/dist/Popover/Popover.styles.d.ts.map +0 -1
  169. package/dist/Popover/Popover.types.d.ts.map +0 -1
  170. package/dist/Popover/index.d.ts.map +0 -1
  171. package/dist/Popover/usePopover.d.ts.map +0 -1
  172. package/dist/Select/Select.d.ts.map +0 -1
  173. package/dist/Select/Select.styles.d.ts.map +0 -1
  174. package/dist/Select/Select.types.d.ts.map +0 -1
  175. package/dist/Select/SelectOption.d.ts.map +0 -1
  176. package/dist/Select/index.d.ts.map +0 -1
  177. package/dist/Select/useSelect.d.ts.map +0 -1
  178. package/dist/Sidebar/Sidebar.d.ts.map +0 -1
  179. package/dist/Sidebar/Sidebar.styles.d.ts.map +0 -1
  180. package/dist/Sidebar/Sidebar.types.d.ts.map +0 -1
  181. package/dist/Sidebar/index.d.ts.map +0 -1
  182. package/dist/Slider/Slider.d.ts.map +0 -1
  183. package/dist/Slider/Slider.styles.d.ts.map +0 -1
  184. package/dist/Slider/Slider.types.d.ts.map +0 -1
  185. package/dist/Slider/index.d.ts.map +0 -1
  186. package/dist/TextInput/TextInput.d.ts.map +0 -1
  187. package/dist/TextInput/TextInput.styles.d.ts.map +0 -1
  188. package/dist/TextInput/TextInput.types.d.ts.map +0 -1
  189. package/dist/TextInput/index.d.ts.map +0 -1
  190. package/dist/Toggle/Toggle.d.ts.map +0 -1
  191. package/dist/Toggle/Toggle.styles.d.ts.map +0 -1
  192. package/dist/Toggle/Toggle.types.d.ts.map +0 -1
  193. package/dist/Toggle/index.d.ts.map +0 -1
  194. package/src/Button/Button.styles.ts +0 -133
  195. package/src/Button/Button.tsx +0 -86
  196. /package/dist/{Button → composites/actions/Button}/index.d.ts +0 -0
  197. /package/dist/{Select → composites/form-controls/Select}/Select.d.ts +0 -0
  198. /package/dist/{Select → composites/form-controls/Select}/Select.types.d.ts +0 -0
  199. /package/dist/{Select → composites/form-controls/Select}/SelectOption.d.ts +0 -0
  200. /package/dist/{Select → composites/form-controls/Select}/index.d.ts +0 -0
  201. /package/dist/{Select → composites/form-controls/Select}/useSelect.d.ts +0 -0
  202. /package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.d.ts +0 -0
  203. /package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.types.d.ts +0 -0
  204. /package/dist/{TextInput → composites/form-controls/TextInput}/index.d.ts +0 -0
  205. /package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.d.ts +0 -0
  206. /package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.types.d.ts +0 -0
  207. /package/dist/{Toggle → composites/form-controls/Toggle}/index.d.ts +0 -0
  208. /package/dist/{AppShell → composites/layout/AppShell}/AppShell.d.ts +0 -0
  209. /package/dist/{AppShell → composites/layout/AppShell}/AppShell.types.d.ts +0 -0
  210. /package/dist/{AppShell → composites/layout/AppShell}/index.d.ts +0 -0
  211. /package/dist/{Card → composites/layout/Card}/Card.d.ts +0 -0
  212. /package/dist/{Card → composites/layout/Card}/index.d.ts +0 -0
  213. /package/dist/{Navbar → composites/layout/Navbar}/Navbar.d.ts +0 -0
  214. /package/dist/{Navbar → composites/layout/Navbar}/Navbar.types.d.ts +0 -0
  215. /package/dist/{Navbar → composites/layout/Navbar}/index.d.ts +0 -0
  216. /package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.d.ts +0 -0
  217. /package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.types.d.ts +0 -0
  218. /package/dist/{Sidebar → composites/layout/Sidebar}/index.d.ts +0 -0
  219. /package/dist/{Popover → composites/overlays/Popover}/Popover.d.ts +0 -0
  220. /package/dist/{Popover → composites/overlays/Popover}/Popover.types.d.ts +0 -0
  221. /package/dist/{Popover → composites/overlays/Popover}/index.d.ts +0 -0
  222. /package/dist/{Popover → composites/overlays/Popover}/usePopover.d.ts +0 -0
  223. /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.d.ts +0 -0
  224. /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.types.d.ts +0 -0
  225. /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/index.d.ts +0 -0
  226. /package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.d.ts +0 -0
  227. /package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.types.d.ts +0 -0
  228. /package/dist/{HueSlider → composites/range-inputs/HueSlider}/index.d.ts +0 -0
  229. /package/dist/{Slider → composites/range-inputs/Slider}/Slider.d.ts +0 -0
  230. /package/dist/{Slider → composites/range-inputs/Slider}/Slider.types.d.ts +0 -0
  231. /package/dist/{Slider → composites/range-inputs/Slider}/index.d.ts +0 -0
  232. /package/src/{Button → composites/actions/Button}/index.ts +0 -0
  233. /package/src/{Select → composites/form-controls/Select}/Select.types.ts +0 -0
  234. /package/src/{Select → composites/form-controls/Select}/index.ts +0 -0
  235. /package/src/{Select → composites/form-controls/Select}/useSelect.ts +0 -0
  236. /package/src/{TextInput → composites/form-controls/TextInput}/TextInput.types.ts +0 -0
  237. /package/src/{TextInput → composites/form-controls/TextInput}/index.ts +0 -0
  238. /package/src/{Toggle → composites/form-controls/Toggle}/Toggle.types.ts +0 -0
  239. /package/src/{Toggle → composites/form-controls/Toggle}/index.ts +0 -0
  240. /package/src/{AppShell → composites/layout/AppShell}/AppShell.types.ts +0 -0
  241. /package/src/{AppShell → composites/layout/AppShell}/index.ts +0 -0
  242. /package/src/{Card → composites/layout/Card}/index.ts +0 -0
  243. /package/src/{Navbar → composites/layout/Navbar}/Navbar.types.ts +0 -0
  244. /package/src/{Navbar → composites/layout/Navbar}/index.ts +0 -0
  245. /package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.types.ts +0 -0
  246. /package/src/{Sidebar → composites/layout/Sidebar}/index.ts +0 -0
  247. /package/src/{Popover → composites/overlays/Popover}/Popover.types.ts +0 -0
  248. /package/src/{Popover → composites/overlays/Popover}/index.ts +0 -0
  249. /package/src/{Popover → composites/overlays/Popover}/usePopover.ts +0 -0
  250. /package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.types.ts +0 -0
  251. /package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/index.ts +0 -0
  252. /package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.types.ts +0 -0
  253. /package/src/{HueSlider → composites/range-inputs/HueSlider}/index.ts +0 -0
  254. /package/src/{Slider → composites/range-inputs/Slider}/Slider.types.ts +0 -0
  255. /package/src/{Slider → composites/range-inputs/Slider}/index.ts +0 -0
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import React11, { createContext, useState, useMemo, useContext, useEffect, useCallback, useRef } from 'react';
2
- import { DEFAULT_NEUTRAL_SATURATION, DEFAULT_NEUTRAL_HUE, DEFAULT_ACCENT_SATURATION, DEFAULT_ACCENT_HUE, DEFAULT_SUCCESS_SATURATION, DEFAULT_SUCCESS_HUE, DEFAULT_WARNING_SATURATION, DEFAULT_WARNING_HUE, DEFAULT_ERROR_SATURATION, DEFAULT_ERROR_HUE, getColor, getColorByContrast, srgbToHex } from 'newtone';
3
- import { Text, Pressable, View, TextInput as TextInput$1, ScrollView, PanResponder, Animated, StyleSheet } from 'react-native';
1
+ import React13, { createContext, useState, useMemo, useContext, useEffect, useCallback, useRef } from 'react';
2
+ import { DEFAULT_NEUTRAL_SATURATION, DEFAULT_NEUTRAL_HUE, DEFAULT_ACCENT_SATURATION, DEFAULT_ACCENT_HUE, DEFAULT_SUCCESS_SATURATION, DEFAULT_SUCCESS_HUE, DEFAULT_WARNING_SATURATION, DEFAULT_WARNING_HUE, DEFAULT_ERROR_SATURATION, DEFAULT_ERROR_HUE, getColor, srgbToHex } from 'newtone';
3
+ import { Text, View, Pressable, TextInput as TextInput$1, ScrollView, PanResponder, Animated, StyleSheet } from 'react-native';
4
4
 
5
5
  // src/theme/NewtoneProvider.tsx
6
6
  var DEFAULT_THEME_CONFIG = {
@@ -17,16 +17,6 @@ var DEFAULT_THEME_CONFIG = {
17
17
  { hue: DEFAULT_ERROR_HUE, saturation: DEFAULT_ERROR_SATURATION }
18
18
  ]
19
19
  },
20
- themes: {
21
- neutral: { paletteIndex: 0, lightModeNv: 0.95, darkModeNv: 0.1 },
22
- primary: { paletteIndex: 1, lightModeNv: 0.95, darkModeNv: 0.1 },
23
- secondary: { paletteIndex: 1, lightModeNv: 0.85, darkModeNv: 0.15 },
24
- strong: { paletteIndex: 0, lightModeNv: 0.1, darkModeNv: 0.95 }
25
- },
26
- elevation: {
27
- offsets: [-0.02, 0, 0.04]
28
- // [sunken, default, elevated]
29
- },
30
20
  spacing: {
31
21
  "00": 0,
32
22
  // base * 0
@@ -190,22 +180,18 @@ var ThemeContext = createContext(null);
190
180
  function NewtoneProvider({
191
181
  config = DEFAULT_THEME_CONFIG,
192
182
  initialMode = "light",
193
- initialTheme = "neutral",
194
183
  children
195
184
  }) {
196
185
  const [mode, setMode] = useState(initialMode);
197
- const [theme, setTheme] = useState(initialTheme);
198
186
  const value = useMemo(
199
187
  () => ({
200
188
  config,
201
189
  mode,
202
- theme,
203
- setMode,
204
- setTheme
190
+ setMode
205
191
  }),
206
- [config, mode, theme]
192
+ [config, mode]
207
193
  );
208
- return /* @__PURE__ */ React11.createElement(ThemeContext.Provider, { value }, /* @__PURE__ */ React11.createElement(GoogleFontLoader, { fonts: config.typography.fonts }), /* @__PURE__ */ React11.createElement(IconFontLoader, { icons: config.icons }), children);
194
+ return /* @__PURE__ */ React13.createElement(ThemeContext.Provider, { value }, /* @__PURE__ */ React13.createElement(GoogleFontLoader, { fonts: config.typography.fonts }), /* @__PURE__ */ React13.createElement(IconFontLoader, { icons: config.icons }), children);
209
195
  }
210
196
  function useNewtoneTheme() {
211
197
  const context = useContext(ThemeContext);
@@ -218,19 +204,160 @@ var FrameContext = createContext(null);
218
204
  function useFrameContext() {
219
205
  return useContext(FrameContext);
220
206
  }
207
+ var NEUTRAL_DEFAULTS = {
208
+ light: {
209
+ background: { elevated: 0, ground: 0.03, sunken: 0.06 },
210
+ text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
211
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
212
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
213
+ },
214
+ dark: {
215
+ background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
216
+ text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
217
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
218
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
219
+ }
220
+ };
221
+ var ACCENT_DEFAULTS = {
222
+ light: {
223
+ background: { elevated: 0, ground: 0.03, sunken: 0.06 },
224
+ text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
225
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
226
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
227
+ },
228
+ dark: {
229
+ background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
230
+ text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
231
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
232
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
233
+ }
234
+ };
235
+ var SUCCESS_DEFAULTS = {
236
+ light: {
237
+ background: { elevated: 0, ground: 0.03, sunken: 0.06 },
238
+ text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
239
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
240
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
241
+ },
242
+ dark: {
243
+ background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
244
+ text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
245
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
246
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
247
+ }
248
+ };
249
+ var WARNING_DEFAULTS = {
250
+ light: {
251
+ background: { elevated: 0, ground: 0.03, sunken: 0.06 },
252
+ text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
253
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
254
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
255
+ },
256
+ dark: {
257
+ background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
258
+ text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
259
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
260
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
261
+ }
262
+ };
263
+ var ERROR_DEFAULTS = {
264
+ light: {
265
+ background: { elevated: 0, ground: 0.03, sunken: 0.06 },
266
+ text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
267
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
268
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
269
+ },
270
+ dark: {
271
+ background: { elevated: 0.24, ground: 0.2, sunken: 0.16 },
272
+ text: { primary: 1, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
273
+ action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
274
+ border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
275
+ }
276
+ };
221
277
  function fontConfigToFamily(font) {
222
278
  const family = font.family.includes(" ") ? `"${font.family}"` : font.family;
223
279
  return `${family}, ${font.fallback}`;
224
280
  }
225
- function computeTokens(config, mode, themeMapping, elevation, elevationOffsets, spacing, radius, typography, icons) {
281
+ var clamp = (n) => Math.max(0, Math.min(1, n));
282
+ function computePaletteTokens(palette, defaults, mode, elevation, dynamicRange, elevationDelta, effectiveTextMode, autoAccentNv, neutralTextPrimary, neutralBgElevated) {
283
+ const modeDefaults = defaults[mode];
284
+ const toEngineNv = (nv) => mode === "light" ? 1 - nv : nv;
285
+ const textToEngineNv = (nv) => effectiveTextMode === "light" ? 1 - nv : nv;
286
+ const colorAt = (engineNv) => getColor(
287
+ palette.hue,
288
+ palette.saturation,
289
+ dynamicRange,
290
+ clamp(engineNv),
291
+ palette.desaturation,
292
+ palette.paletteHueGrading
293
+ );
294
+ const resolveKeyNv = (p) => mode === "dark" ? p.keyNormalizedValueDark : p.keyNormalizedValue;
295
+ const keyNv = resolveKeyNv(palette);
296
+ const fillBaseNv = keyNv ?? autoAccentNv;
297
+ const fillNv = clamp(fillBaseNv + elevationDelta);
298
+ const fill = colorAt(fillNv);
299
+ const hoverDir = effectiveTextMode === "light" ? -modeDefaults.action.hovered : modeDefaults.action.hovered;
300
+ const activeDir = effectiveTextMode === "light" ? -modeDefaults.action.pressed : modeDefaults.action.pressed;
301
+ const fillHover = colorAt(clamp(fillNv + hoverDir));
302
+ const fillActive = colorAt(clamp(fillNv + activeDir));
303
+ const onFill = fill.oklch.L > 0.6 ? neutralTextPrimary : neutralBgElevated;
304
+ const bgNormalized = elevation === 2 ? modeDefaults.background.elevated : elevation === 1 ? modeDefaults.background.ground : modeDefaults.background.sunken;
305
+ const bgNv = clamp(toEngineNv(bgNormalized));
306
+ const background = colorAt(bgNv);
307
+ const backgroundElevated = colorAt(clamp(toEngineNv(modeDefaults.background.elevated)));
308
+ const backgroundSunken = colorAt(clamp(toEngineNv(modeDefaults.background.sunken)));
309
+ const interactiveOffset = modeDefaults.action.enabled;
310
+ const interactiveNv = clamp(bgNv + (effectiveTextMode === "light" ? -interactiveOffset : interactiveOffset));
311
+ const backgroundInteractive = colorAt(interactiveNv);
312
+ const hoverShift = modeDefaults.action.hovered;
313
+ const activeShift = modeDefaults.action.pressed;
314
+ const backgroundInteractiveHover = colorAt(clamp(interactiveNv + (effectiveTextMode === "light" ? -hoverShift : hoverShift)));
315
+ const backgroundInteractiveActive = colorAt(clamp(interactiveNv + (effectiveTextMode === "light" ? -activeShift : activeShift)));
316
+ const textPrimary = colorAt(clamp(textToEngineNv(modeDefaults.text.primary) + elevationDelta));
317
+ const textSecondary = colorAt(clamp(textToEngineNv(modeDefaults.text.secondary) + elevationDelta));
318
+ const textTertiary = colorAt(clamp(textToEngineNv(modeDefaults.text.tertiary) + elevationDelta));
319
+ const textDisabled = colorAt(clamp(textToEngineNv(modeDefaults.text.disabled) + elevationDelta));
320
+ const borderOffset = modeDefaults.border.enabled;
321
+ const borderNv = effectiveTextMode === "light" ? bgNv - borderOffset : bgNv + borderOffset;
322
+ const border = colorAt(clamp(borderNv));
323
+ return {
324
+ fill,
325
+ fillHover,
326
+ fillActive,
327
+ onFill,
328
+ background,
329
+ backgroundElevated,
330
+ backgroundSunken,
331
+ backgroundInteractive,
332
+ backgroundInteractiveHover,
333
+ backgroundInteractiveActive,
334
+ textPrimary,
335
+ textSecondary,
336
+ textTertiary,
337
+ textDisabled,
338
+ border
339
+ };
340
+ }
341
+ function computeTokens(config, mode, elevation, spacing, radius, typography, icons, tokenOverrides) {
226
342
  const { dynamicRange, palettes } = config;
227
- const palette = palettes[themeMapping.paletteIndex];
343
+ const palette = palettes[0];
228
344
  if (!palette) {
229
- throw new Error(`Palette at index ${themeMapping.paletteIndex} not found`);
345
+ throw new Error("Neutral palette (index 0) not found");
230
346
  }
231
- const baseNv = mode === "light" ? themeMapping.lightModeNv : themeMapping.darkModeNv;
232
- const elevationOffset = elevationOffsets[elevation];
233
- const backgroundNv = Math.max(0, Math.min(1, baseNv + elevationOffset));
347
+ const neutralDefaults = NEUTRAL_DEFAULTS[mode];
348
+ const toEngineNv = (nv) => mode === "light" ? 1 - nv : nv;
349
+ const bgElevatedNorm = mode === "light" ? tokenOverrides?.backgroundElevated : tokenOverrides?.backgroundElevatedDark;
350
+ const bgDefaultNorm = mode === "light" ? tokenOverrides?.backgroundDefault : tokenOverrides?.backgroundDefaultDark;
351
+ const bgSunkenNorm = mode === "light" ? tokenOverrides?.backgroundSunken : tokenOverrides?.backgroundSunkenDark;
352
+ const textPrimaryNorm = mode === "light" ? tokenOverrides?.textPrimaryNormalized : tokenOverrides?.textPrimaryNormalizedDark;
353
+ const textSecondaryNorm = mode === "light" ? tokenOverrides?.textSecondaryNormalized : tokenOverrides?.textSecondaryNormalizedDark;
354
+ const textTertiaryNorm = mode === "light" ? tokenOverrides?.textTertiaryNormalized : tokenOverrides?.textTertiaryNormalizedDark;
355
+ const textDisabledNorm = mode === "light" ? tokenOverrides?.textDisabledNormalized : tokenOverrides?.textDisabledNormalizedDark;
356
+ const bgNormalized = elevation === 2 ? bgElevatedNorm ?? neutralDefaults.background.elevated : elevation === 1 ? bgDefaultNorm ?? neutralDefaults.background.ground : bgSunkenNorm ?? neutralDefaults.background.sunken;
357
+ const backgroundNv = clamp(toEngineNv(bgNormalized));
358
+ const elevatedNv = clamp(toEngineNv(bgElevatedNorm ?? neutralDefaults.background.elevated));
359
+ const sunkenNv = clamp(toEngineNv(bgSunkenNorm ?? neutralDefaults.background.sunken));
360
+ const elevationDelta = backgroundNv - elevatedNv;
234
361
  const effectiveTextMode = backgroundNv >= 0.5 ? "light" : "dark";
235
362
  const background = getColor(
236
363
  palette.hue,
@@ -240,7 +367,6 @@ function computeTokens(config, mode, themeMapping, elevation, elevationOffsets,
240
367
  palette.desaturation,
241
368
  palette.paletteHueGrading
242
369
  );
243
- const elevatedNv = Math.max(0, Math.min(1, baseNv + elevationOffsets[2]));
244
370
  const backgroundElevated = getColor(
245
371
  palette.hue,
246
372
  palette.saturation,
@@ -249,7 +375,6 @@ function computeTokens(config, mode, themeMapping, elevation, elevationOffsets,
249
375
  palette.desaturation,
250
376
  palette.paletteHueGrading
251
377
  );
252
- const sunkenNv = Math.max(0, Math.min(1, baseNv + elevationOffsets[0]));
253
378
  const backgroundSunken = getColor(
254
379
  palette.hue,
255
380
  palette.saturation,
@@ -258,142 +383,148 @@ function computeTokens(config, mode, themeMapping, elevation, elevationOffsets,
258
383
  palette.desaturation,
259
384
  palette.paletteHueGrading
260
385
  );
261
- const textPrimary = getColorByContrast(
386
+ const INTERACTIVE_COMPONENT_OFFSET = mode === "light" ? tokenOverrides?.interactiveComponentOffset ?? neutralDefaults.action.enabled : tokenOverrides?.interactiveComponentOffsetDark ?? neutralDefaults.action.enabled;
387
+ const HOVER_SHIFT = mode === "light" ? tokenOverrides?.hoverShift ?? neutralDefaults.action.hovered : tokenOverrides?.hoverShiftDark ?? neutralDefaults.action.hovered;
388
+ const ACTIVE_SHIFT = mode === "light" ? tokenOverrides?.activeShift ?? neutralDefaults.action.pressed : tokenOverrides?.activeShiftDark ?? neutralDefaults.action.pressed;
389
+ const BORDER_OFFSET = mode === "light" ? tokenOverrides?.borderOffset ?? neutralDefaults.border.enabled : tokenOverrides?.borderOffsetDark ?? neutralDefaults.border.enabled;
390
+ const interactiveComponentNv = clamp(backgroundNv + (effectiveTextMode === "light" ? -INTERACTIVE_COMPONENT_OFFSET : INTERACTIVE_COMPONENT_OFFSET));
391
+ const backgroundInteractive = getColor(
262
392
  palette.hue,
263
393
  palette.saturation,
264
394
  dynamicRange,
265
- 4.5,
266
- effectiveTextMode,
395
+ interactiveComponentNv,
267
396
  palette.desaturation,
268
- palette.paletteHueGrading,
269
- background
397
+ palette.paletteHueGrading
270
398
  );
271
- const textSecondary = getColorByContrast(
399
+ const neutralHoverNv = clamp(interactiveComponentNv + (effectiveTextMode === "light" ? -HOVER_SHIFT : HOVER_SHIFT));
400
+ const backgroundInteractiveHover = getColor(
272
401
  palette.hue,
273
402
  palette.saturation,
274
403
  dynamicRange,
275
- 3,
276
- effectiveTextMode,
404
+ neutralHoverNv,
277
405
  palette.desaturation,
278
- palette.paletteHueGrading,
279
- background
406
+ palette.paletteHueGrading
280
407
  );
281
- const accentPalette = palettes[1];
282
- if (!accentPalette) {
283
- throw new Error("Accent palette (index 1) not found");
284
- }
285
- const resolveKeyNv = (p) => mode === "dark" ? p.keyNormalizedValueDark : p.keyNormalizedValue;
286
- const accentKeyNv = resolveKeyNv(accentPalette);
287
- const interactive = accentKeyNv !== void 0 ? getColor(
288
- accentPalette.hue,
289
- accentPalette.saturation,
408
+ const neutralActiveNv = clamp(interactiveComponentNv + (effectiveTextMode === "light" ? -ACTIVE_SHIFT : ACTIVE_SHIFT));
409
+ const backgroundInteractiveActive = getColor(
410
+ palette.hue,
411
+ palette.saturation,
290
412
  dynamicRange,
291
- accentKeyNv,
292
- accentPalette.desaturation,
293
- accentPalette.paletteHueGrading
294
- ) : getColorByContrast(
295
- accentPalette.hue,
296
- accentPalette.saturation,
413
+ neutralActiveNv,
414
+ palette.desaturation,
415
+ palette.paletteHueGrading
416
+ );
417
+ const textToEngineNv = (nv) => effectiveTextMode === "light" ? 1 - nv : nv;
418
+ const textPrimary = getColor(
419
+ palette.hue,
420
+ palette.saturation,
297
421
  dynamicRange,
298
- 4.5,
299
- effectiveTextMode,
300
- accentPalette.desaturation,
301
- accentPalette.paletteHueGrading,
302
- background
422
+ clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary) + elevationDelta),
423
+ palette.desaturation,
424
+ palette.paletteHueGrading
303
425
  );
304
- const interactiveNv = accentKeyNv ?? (effectiveTextMode === "light" ? 0.3 : 0.7);
305
- const interactiveHover = getColor(
306
- accentPalette.hue,
307
- accentPalette.saturation,
426
+ const textSecondary = getColor(
427
+ palette.hue,
428
+ palette.saturation,
308
429
  dynamicRange,
309
- interactiveNv + (effectiveTextMode === "light" ? -0.05 : 0.05),
310
- accentPalette.desaturation,
311
- accentPalette.paletteHueGrading
430
+ clamp(textToEngineNv(textSecondaryNorm ?? neutralDefaults.text.secondary) + elevationDelta),
431
+ palette.desaturation,
432
+ palette.paletteHueGrading
312
433
  );
313
- const interactiveActive = getColor(
314
- accentPalette.hue,
315
- accentPalette.saturation,
434
+ const textTertiary = getColor(
435
+ palette.hue,
436
+ palette.saturation,
316
437
  dynamicRange,
317
- interactiveNv + (effectiveTextMode === "light" ? -0.1 : 0.1),
318
- accentPalette.desaturation,
319
- accentPalette.paletteHueGrading
438
+ clamp(textToEngineNv(textTertiaryNorm ?? neutralDefaults.text.tertiary) + elevationDelta),
439
+ palette.desaturation,
440
+ palette.paletteHueGrading
441
+ );
442
+ const textDisabled = getColor(
443
+ palette.hue,
444
+ palette.saturation,
445
+ dynamicRange,
446
+ clamp(textToEngineNv(textDisabledNorm ?? neutralDefaults.text.disabled) + elevationDelta),
447
+ palette.desaturation,
448
+ palette.paletteHueGrading
320
449
  );
321
- const borderNv = effectiveTextMode === "light" ? backgroundNv - 0.1 : backgroundNv + 0.1;
450
+ const borderNv = effectiveTextMode === "light" ? backgroundNv - BORDER_OFFSET : backgroundNv + BORDER_OFFSET;
322
451
  const border = getColor(
323
452
  palette.hue,
324
453
  palette.saturation,
325
454
  dynamicRange,
326
- Math.max(0, Math.min(1, borderNv)),
455
+ clamp(borderNv),
327
456
  palette.desaturation,
328
457
  palette.paletteHueGrading
329
458
  );
459
+ const autoAccentNv = clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary));
460
+ const accentPalette = palettes[1];
461
+ if (!accentPalette) {
462
+ throw new Error("Accent palette (index 1) not found");
463
+ }
464
+ const accent = computePaletteTokens(
465
+ accentPalette,
466
+ ACCENT_DEFAULTS,
467
+ mode,
468
+ elevation,
469
+ dynamicRange,
470
+ elevationDelta,
471
+ effectiveTextMode,
472
+ autoAccentNv,
473
+ textPrimary,
474
+ backgroundElevated
475
+ );
330
476
  const successPalette = palettes[2];
331
477
  const warningPalette = palettes[3];
332
478
  const errorPalette = palettes[4];
333
- const successKeyNv = successPalette ? resolveKeyNv(successPalette) : void 0;
334
- const success = successPalette ? successKeyNv !== void 0 ? getColor(
335
- successPalette.hue,
336
- successPalette.saturation,
479
+ const success = successPalette ? computePaletteTokens(
480
+ successPalette,
481
+ SUCCESS_DEFAULTS,
482
+ mode,
483
+ elevation,
337
484
  dynamicRange,
338
- successKeyNv,
339
- successPalette.desaturation,
340
- successPalette.paletteHueGrading
341
- ) : getColorByContrast(
342
- successPalette.hue,
343
- successPalette.saturation,
344
- dynamicRange,
345
- 4.5,
485
+ elevationDelta,
346
486
  effectiveTextMode,
347
- successPalette.desaturation,
348
- successPalette.paletteHueGrading,
349
- background
350
- ) : interactive;
351
- const warningKeyNv = warningPalette ? resolveKeyNv(warningPalette) : void 0;
352
- const warning = warningPalette ? warningKeyNv !== void 0 ? getColor(
353
- warningPalette.hue,
354
- warningPalette.saturation,
355
- dynamicRange,
356
- warningKeyNv,
357
- warningPalette.desaturation,
358
- warningPalette.paletteHueGrading
359
- ) : getColorByContrast(
360
- warningPalette.hue,
361
- warningPalette.saturation,
487
+ autoAccentNv,
488
+ textPrimary,
489
+ backgroundElevated
490
+ ) : accent;
491
+ const warning = warningPalette ? computePaletteTokens(
492
+ warningPalette,
493
+ WARNING_DEFAULTS,
494
+ mode,
495
+ elevation,
362
496
  dynamicRange,
363
- 4.5,
497
+ elevationDelta,
364
498
  effectiveTextMode,
365
- warningPalette.desaturation,
366
- warningPalette.paletteHueGrading,
367
- background
368
- ) : interactive;
369
- const errorKeyNv = errorPalette ? resolveKeyNv(errorPalette) : void 0;
370
- const error = errorPalette ? errorKeyNv !== void 0 ? getColor(
371
- errorPalette.hue,
372
- errorPalette.saturation,
373
- dynamicRange,
374
- errorKeyNv,
375
- errorPalette.desaturation,
376
- errorPalette.paletteHueGrading
377
- ) : getColorByContrast(
378
- errorPalette.hue,
379
- errorPalette.saturation,
499
+ autoAccentNv,
500
+ textPrimary,
501
+ backgroundElevated
502
+ ) : accent;
503
+ const error = errorPalette ? computePaletteTokens(
504
+ errorPalette,
505
+ ERROR_DEFAULTS,
506
+ mode,
507
+ elevation,
380
508
  dynamicRange,
381
- 4.5,
509
+ elevationDelta,
382
510
  effectiveTextMode,
383
- errorPalette.desaturation,
384
- errorPalette.paletteHueGrading,
385
- background
386
- ) : interactive;
511
+ autoAccentNv,
512
+ textPrimary,
513
+ backgroundElevated
514
+ ) : accent;
387
515
  return {
388
516
  background,
389
517
  backgroundElevated,
390
518
  backgroundSunken,
519
+ backgroundInteractive,
520
+ backgroundInteractiveHover,
521
+ backgroundInteractiveActive,
391
522
  textPrimary,
392
523
  textSecondary,
393
- interactive,
394
- interactiveHover,
395
- interactiveActive,
524
+ textTertiary,
525
+ textDisabled,
396
526
  border,
527
+ accent,
397
528
  success,
398
529
  warning,
399
530
  error,
@@ -419,119 +550,222 @@ function computeTokens(config, mode, themeMapping, elevation, elevationOffsets,
419
550
 
420
551
  // src/tokens/useTokens.ts
421
552
  function useTokens(elevation) {
422
- const { config, mode, theme: providerTheme } = useNewtoneTheme();
553
+ const { config, mode } = useNewtoneTheme();
423
554
  const frameCtx = useFrameContext();
424
- const resolvedTheme = frameCtx?.theme ?? providerTheme;
425
555
  const resolvedElevation = elevation ?? frameCtx?.elevation ?? 1;
556
+ const canReuse = frameCtx !== null && elevation === void 0 && frameCtx.elevation === resolvedElevation;
426
557
  return useMemo(() => {
427
- const themeMapping = config.themes[resolvedTheme];
428
- return computeTokens(
558
+ if (canReuse) {
559
+ return { ...frameCtx.tokens, elevation: resolvedElevation };
560
+ }
561
+ const tokens = computeTokens(
429
562
  config.colorSystem,
430
563
  mode,
431
- themeMapping,
432
564
  resolvedElevation,
433
- config.elevation.offsets,
434
565
  config.spacing,
435
566
  config.radius,
436
567
  config.typography,
437
- config.icons
568
+ config.icons,
569
+ config.tokenOverrides
438
570
  );
439
- }, [config, mode, resolvedTheme, resolvedElevation]);
571
+ return { ...tokens, elevation: resolvedElevation };
572
+ }, [config, mode, resolvedElevation, canReuse, frameCtx?.tokens]);
573
+ }
574
+ function computeButtonPadding(size, hasIcon, hasText, iconPosition) {
575
+ const basePadding = {
576
+ sm: 8,
577
+ md: 12,
578
+ lg: 16
579
+ };
580
+ const base = basePadding[size];
581
+ const textExtra = 8;
582
+ if (!hasText && hasIcon) {
583
+ return {
584
+ paddingLeft: base,
585
+ paddingRight: base,
586
+ paddingTop: base,
587
+ paddingBottom: base
588
+ };
589
+ }
590
+ if (hasText && !hasIcon) {
591
+ return {
592
+ paddingLeft: base + textExtra,
593
+ paddingRight: base + textExtra,
594
+ paddingTop: base,
595
+ paddingBottom: base
596
+ };
597
+ }
598
+ if (hasText && hasIcon) {
599
+ if (iconPosition === "left") {
600
+ return {
601
+ paddingLeft: base,
602
+ paddingRight: base + textExtra,
603
+ paddingTop: base,
604
+ paddingBottom: base
605
+ };
606
+ } else {
607
+ return {
608
+ paddingLeft: base + textExtra,
609
+ paddingRight: base,
610
+ paddingTop: base,
611
+ paddingBottom: base
612
+ };
613
+ }
614
+ }
615
+ return {
616
+ paddingLeft: base,
617
+ paddingRight: base,
618
+ paddingTop: base,
619
+ paddingBottom: base
620
+ };
621
+ }
622
+ function getPaletteTokens(semantic, tokens) {
623
+ switch (semantic) {
624
+ case "accent":
625
+ return tokens.accent;
626
+ case "success":
627
+ return tokens.success;
628
+ case "error":
629
+ return tokens.error;
630
+ case "warning":
631
+ return tokens.warning;
632
+ default:
633
+ return void 0;
634
+ }
440
635
  }
441
- function getSizeConfig(tokens) {
636
+ function getButtonConfig(variant, semantic, size, disabled, tokens) {
637
+ const sizeConfig = getSizeConfig(size, tokens);
638
+ const variantColors = getVariantColors(variant, semantic, disabled, tokens);
442
639
  return {
640
+ variantColors,
641
+ sizeTokens: {
642
+ padding: sizeConfig.padding,
643
+ gap: sizeConfig.gap,
644
+ borderRadius: sizeConfig.borderRadius,
645
+ textSize: sizeConfig.textSize,
646
+ iconSize: sizeConfig.iconSize
647
+ }
648
+ };
649
+ }
650
+ function getSizeConfig(size, tokens) {
651
+ const configs = {
443
652
  sm: {
444
- paddingVertical: tokens.spacing["04"],
445
- paddingHorizontal: tokens.spacing["12"],
446
- fontSize: tokens.typography.size.sm,
447
- borderRadius: tokens.radius.sm,
448
- gap: tokens.spacing["04"],
449
- iconSize: tokens.typography.size.sm
653
+ padding: 8,
654
+ gap: tokens.spacing["08"],
655
+ borderRadius: 8,
656
+ textSize: "base",
657
+ // 16px
658
+ iconSize: 24
450
659
  },
451
660
  md: {
452
- paddingVertical: tokens.spacing["08"],
453
- paddingHorizontal: tokens.spacing["16"],
454
- fontSize: tokens.typography.size.base,
455
- borderRadius: tokens.radius.md,
661
+ padding: 12,
456
662
  gap: tokens.spacing["08"],
457
- iconSize: tokens.typography.size.base
663
+ borderRadius: 12,
664
+ textSize: "base",
665
+ // 16px
666
+ iconSize: 24
458
667
  },
459
668
  lg: {
460
- paddingVertical: tokens.spacing["12"],
461
- paddingHorizontal: tokens.spacing["24"],
462
- fontSize: tokens.typography.size.base,
463
- borderRadius: tokens.radius.lg,
669
+ padding: 16,
464
670
  gap: tokens.spacing["08"],
465
- iconSize: tokens.typography.size.base
671
+ borderRadius: 16,
672
+ textSize: "base",
673
+ // 16px
674
+ iconSize: 24
466
675
  }
467
676
  };
677
+ return configs[size];
468
678
  }
469
- function getButtonStyles(tokens, variant, size, disabled, isIconOnly) {
470
- const sizeConfig = getSizeConfig(tokens)[size];
471
- const base = {
472
- paddingVertical: sizeConfig.paddingVertical,
473
- paddingHorizontal: isIconOnly ? sizeConfig.paddingVertical : sizeConfig.paddingHorizontal,
474
- borderRadius: sizeConfig.borderRadius,
475
- alignItems: "center",
476
- justifyContent: "center",
477
- flexDirection: "row",
478
- gap: sizeConfig.gap
479
- };
480
- let backgroundColor;
481
- let textColor;
482
- let borderColor;
483
- let borderWidth = 0;
484
- switch (variant) {
485
- case "primary":
486
- backgroundColor = srgbToHex(tokens.interactive.srgb);
487
- textColor = srgbToHex(tokens.background.srgb);
488
- break;
489
- case "secondary":
490
- backgroundColor = srgbToHex(tokens.backgroundElevated.srgb);
491
- textColor = srgbToHex(tokens.textPrimary.srgb);
492
- break;
493
- case "outline":
494
- backgroundColor = "transparent";
495
- textColor = srgbToHex(tokens.interactive.srgb);
496
- borderColor = srgbToHex(tokens.border.srgb);
497
- borderWidth = 1;
498
- break;
499
- case "ghost":
500
- backgroundColor = "transparent";
501
- textColor = srgbToHex(tokens.interactive.srgb);
502
- break;
679
+ function getVariantColors(variant, semantic, disabled, tokens) {
680
+ if (disabled) {
681
+ const baseColors = getVariantColorsForState(variant, semantic, tokens);
682
+ const disabledBg = srgbToHex(tokens.backgroundSunken.srgb);
683
+ return {
684
+ ...baseColors,
685
+ bg: disabledBg,
686
+ hoveredBg: disabledBg,
687
+ pressedBg: disabledBg,
688
+ textColor: srgbToHex(tokens.textSecondary.srgb),
689
+ iconColor: srgbToHex(tokens.textSecondary.srgb)
690
+ };
691
+ }
692
+ return getVariantColorsForState(variant, semantic, tokens);
693
+ }
694
+ function getVariantColorsForState(variant, semantic, tokens) {
695
+ const paletteTokens = getPaletteTokens(semantic, tokens);
696
+ if (variant === "primary") {
697
+ if (semantic === "neutral") {
698
+ return {
699
+ bg: srgbToHex(tokens.backgroundInteractive.srgb),
700
+ hoveredBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
701
+ pressedBg: srgbToHex(tokens.backgroundInteractiveActive.srgb),
702
+ textColor: srgbToHex(tokens.textPrimary.srgb),
703
+ iconColor: srgbToHex(tokens.textPrimary.srgb),
704
+ borderWidth: 1,
705
+ borderColor: "transparent"
706
+ };
707
+ }
708
+ return {
709
+ bg: srgbToHex(paletteTokens.fill.srgb),
710
+ hoveredBg: srgbToHex(paletteTokens.fillHover.srgb),
711
+ pressedBg: srgbToHex(paletteTokens.fillActive.srgb),
712
+ textColor: srgbToHex(paletteTokens.onFill.srgb),
713
+ iconColor: srgbToHex(paletteTokens.onFill.srgb),
714
+ borderWidth: 1,
715
+ borderColor: "transparent"
716
+ };
717
+ }
718
+ if (variant === "secondary") {
719
+ if (semantic === "neutral") {
720
+ return {
721
+ bg: "transparent",
722
+ hoveredBg: srgbToHex(tokens.backgroundInteractive.srgb),
723
+ pressedBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
724
+ textColor: srgbToHex(tokens.textPrimary.srgb),
725
+ iconColor: srgbToHex(tokens.textPrimary.srgb),
726
+ borderWidth: 1,
727
+ borderColor: srgbToHex(tokens.border.srgb)
728
+ };
729
+ }
730
+ return {
731
+ bg: srgbToHex(paletteTokens.background.srgb),
732
+ hoveredBg: srgbToHex(paletteTokens.backgroundInteractive.srgb),
733
+ pressedBg: srgbToHex(paletteTokens.backgroundInteractiveHover.srgb),
734
+ textColor: srgbToHex(paletteTokens.fill.srgb),
735
+ iconColor: srgbToHex(paletteTokens.fill.srgb),
736
+ borderWidth: 1,
737
+ borderColor: "transparent"
738
+ };
739
+ }
740
+ if (variant === "tertiary") {
741
+ if (semantic === "neutral") {
742
+ return {
743
+ bg: "transparent",
744
+ hoveredBg: srgbToHex(tokens.backgroundInteractive.srgb),
745
+ pressedBg: srgbToHex(tokens.backgroundInteractiveHover.srgb),
746
+ textColor: srgbToHex(tokens.textPrimary.srgb),
747
+ iconColor: srgbToHex(tokens.textPrimary.srgb),
748
+ borderWidth: 1,
749
+ borderColor: "transparent"
750
+ };
751
+ }
752
+ return {
753
+ bg: "transparent",
754
+ hoveredBg: srgbToHex(paletteTokens.background.srgb),
755
+ pressedBg: srgbToHex(paletteTokens.backgroundInteractive.srgb),
756
+ textColor: srgbToHex(paletteTokens.fill.srgb),
757
+ iconColor: srgbToHex(paletteTokens.fill.srgb),
758
+ borderWidth: 1,
759
+ borderColor: "transparent"
760
+ };
503
761
  }
504
- const resolvedTextColor = disabled ? srgbToHex(tokens.textSecondary.srgb) : textColor;
505
762
  return {
506
- iconColor: resolvedTextColor,
507
- iconSize: sizeConfig.iconSize,
508
- styles: StyleSheet.create({
509
- base: {
510
- ...base,
511
- backgroundColor: disabled ? srgbToHex(tokens.backgroundSunken.srgb) : backgroundColor,
512
- borderWidth,
513
- ...borderColor && { borderColor }
514
- },
515
- pressed: {
516
- backgroundColor: variant === "primary" ? srgbToHex(tokens.interactiveActive.srgb) : variant === "secondary" ? srgbToHex(tokens.backgroundSunken.srgb) : "transparent",
517
- opacity: variant === "ghost" || variant === "outline" ? 0.7 : 1
518
- },
519
- disabled: {
520
- opacity: 0.4
521
- },
522
- text: {
523
- fontFamily: tokens.typography.fonts.default,
524
- fontSize: sizeConfig.fontSize,
525
- fontWeight: tokens.typography.weight.semibold,
526
- color: resolvedTextColor
527
- },
528
- textPressed: {
529
- // Color changes handled by parent opacity
530
- },
531
- textDisabled: {
532
- // Color already set in text style via disabled check
533
- }
534
- })
763
+ bg: "transparent",
764
+ hoveredBg: "transparent",
765
+ pressedBg: "transparent",
766
+ textColor: srgbToHex(tokens.textPrimary.srgb),
767
+ iconColor: srgbToHex(tokens.textPrimary.srgb),
768
+ borderWidth: 0
535
769
  };
536
770
  }
537
771
  function Icon({
@@ -553,13 +787,25 @@ function Icon({
553
787
  const tokens = useTokens(elevation);
554
788
  const iconStyle = useMemo(() => {
555
789
  const fontSize = size ?? tokens.typography.size.base;
556
- const opsz = opticalSize ?? fontSize;
790
+ const getOpticalSize = (size2) => {
791
+ if (size2 <= 22) return 20;
792
+ if (size2 <= 32) return 24;
793
+ if (size2 <= 44) return 40;
794
+ return 48;
795
+ };
796
+ const opsz = opticalSize ?? getOpticalSize(fontSize);
557
797
  const iconColor = color ?? srgbToHex(tokens.textPrimary.srgb);
558
798
  const fontFamily = `Material Symbols ${tokens.icons.variant.charAt(0).toUpperCase() + tokens.icons.variant.slice(1)}`;
559
799
  const fontVariationSettings = `'FILL' ${fill}, 'wght' ${tokens.icons.weight}, 'GRAD' ${tokens.icons.grade}, 'opsz' ${opsz}`;
560
800
  return {
561
801
  fontFamily,
562
802
  fontSize,
803
+ width: fontSize,
804
+ // Explicit width ensures square rendering
805
+ height: fontSize,
806
+ // Explicit height ensures square rendering
807
+ lineHeight: fontSize,
808
+ // Prevent text line-height from affecting total height
563
809
  color: iconColor,
564
810
  userSelect: "none",
565
811
  // web-only: prevents users from selecting the icon as text
@@ -568,7 +814,7 @@ function Icon({
568
814
  ...style
569
815
  };
570
816
  }, [tokens, size, opticalSize, fill, color, style]);
571
- return /* @__PURE__ */ React11.createElement(
817
+ return /* @__PURE__ */ React13.createElement(
572
818
  Text,
573
819
  {
574
820
  ref,
@@ -582,121 +828,72 @@ function Icon({
582
828
  name
583
829
  );
584
830
  }
585
-
586
- // src/Button/Button.tsx
587
- function Button({
588
- children,
589
- icon,
590
- iconPosition = "left",
591
- variant = "primary",
592
- size = "md",
593
- disabled = false,
594
- style,
595
- textStyle,
596
- ...pressableProps
597
- }) {
598
- const tokens = useTokens(1);
599
- const isIconOnly = !!icon && !children;
600
- const { styles, iconColor, iconSize } = React11.useMemo(
601
- () => getButtonStyles(tokens, variant, size, disabled, isIconOnly),
602
- [tokens, variant, size, disabled, isIconOnly]
603
- );
604
- const renderIcon = () => /* @__PURE__ */ React11.createElement(Icon, { name: icon, size: iconSize, color: iconColor });
605
- return /* @__PURE__ */ React11.createElement(
606
- Pressable,
607
- {
608
- style: ({ pressed }) => [
609
- styles.base,
610
- pressed && !disabled && styles.pressed,
611
- disabled && styles.disabled,
612
- ...Array.isArray(style) ? style : [style]
613
- ],
614
- disabled,
615
- ...pressableProps
616
- },
617
- ({ pressed }) => /* @__PURE__ */ React11.createElement(React11.Fragment, null, icon && iconPosition === "left" && renderIcon(), children != null && /* @__PURE__ */ React11.createElement(
618
- Text,
619
- {
620
- style: [
621
- styles.text,
622
- pressed && !disabled && styles.textPressed,
623
- disabled && styles.textDisabled,
624
- ...Array.isArray(textStyle) ? textStyle : [textStyle]
625
- ]
626
- },
627
- children
628
- ), icon && iconPosition === "right" && renderIcon())
629
- );
630
- }
631
- function getCardStyles(tokens, disabled) {
632
- return StyleSheet.create({
633
- container: {
634
- backgroundColor: srgbToHex(tokens.background.srgb),
635
- borderWidth: 1,
636
- borderColor: srgbToHex(tokens.border.srgb),
637
- borderRadius: tokens.radius.lg,
638
- padding: tokens.spacing["16"],
639
- opacity: disabled ? 0.5 : 1
640
- }
641
- });
831
+ function resolveTextColor(color, tokens) {
832
+ switch (color) {
833
+ case "primary":
834
+ return srgbToHex(tokens.textPrimary.srgb);
835
+ case "secondary":
836
+ return srgbToHex(tokens.textSecondary.srgb);
837
+ case "tertiary":
838
+ return srgbToHex(tokens.textTertiary.srgb);
839
+ case "disabled":
840
+ return srgbToHex(tokens.textDisabled.srgb);
841
+ case "accent":
842
+ return srgbToHex(tokens.accent.fill.srgb);
843
+ case "success":
844
+ return srgbToHex(tokens.success.fill.srgb);
845
+ case "warning":
846
+ return srgbToHex(tokens.warning.fill.srgb);
847
+ case "error":
848
+ return srgbToHex(tokens.error.fill.srgb);
849
+ }
642
850
  }
643
-
644
- // src/Card/Card.tsx
645
- function Card({
851
+ function Text2({
646
852
  children,
853
+ size = "base",
854
+ weight = "regular",
855
+ color = "primary",
856
+ font = "default",
857
+ lineHeight = "normal",
858
+ align,
859
+ numberOfLines,
647
860
  elevation = 1,
648
861
  style,
649
- disabled = false
862
+ // Accessibility
863
+ accessibilityRole,
864
+ // Testing & platform
865
+ testID,
866
+ nativeID,
867
+ ref
650
868
  }) {
651
869
  const tokens = useTokens(elevation);
652
- const styles = React11.useMemo(
653
- () => getCardStyles(tokens, disabled),
654
- [tokens, disabled]
870
+ const resolvedStyle = useMemo(() => {
871
+ const fontSize = tokens.typography.size[size];
872
+ return {
873
+ // Font family from the theme (e.g. 'default' → 'Inter', 'mono' → 'JetBrains Mono').
874
+ fontFamily: tokens.typography.fonts[font],
875
+ fontSize,
876
+ // Font weight is stored as a number (e.g. 400, 600) but React Native expects a string.
877
+ fontWeight: String(tokens.typography.weight[weight]),
878
+ // Convert the theme color from internal sRGB format to a hex string (e.g. '#1a1a1a').
879
+ color: resolveTextColor(color, tokens),
880
+ // Line height = font size × multiplier (e.g. 16px × 1.5 = 24px line height).
881
+ lineHeight: fontSize * tokens.typography.lineHeight[lineHeight],
882
+ textAlign: align
883
+ };
884
+ }, [tokens, size, weight, color, font, lineHeight, align]);
885
+ return /* @__PURE__ */ React13.createElement(
886
+ Text,
887
+ {
888
+ ref,
889
+ testID,
890
+ nativeID,
891
+ accessibilityRole,
892
+ style: style ? [resolvedStyle, ...Array.isArray(style) ? style : [style]] : resolvedStyle,
893
+ numberOfLines
894
+ },
895
+ children
655
896
  );
656
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
657
- }
658
- var hadKeyboardEvent = false;
659
- var isListenerSetup = false;
660
- function setupModality() {
661
- if (isListenerSetup || typeof document === "undefined") return;
662
- isListenerSetup = true;
663
- const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
664
- "Tab",
665
- "ArrowUp",
666
- "ArrowDown",
667
- "ArrowLeft",
668
- "ArrowRight",
669
- "Enter",
670
- " ",
671
- "Escape"
672
- ]);
673
- document.addEventListener("keydown", (e) => {
674
- if (NAVIGATION_KEYS.has(e.key)) {
675
- hadKeyboardEvent = true;
676
- }
677
- }, true);
678
- document.addEventListener("pointerdown", () => {
679
- hadKeyboardEvent = false;
680
- }, true);
681
- document.addEventListener("mousedown", () => {
682
- hadKeyboardEvent = false;
683
- }, true);
684
- }
685
- function useFocusVisible() {
686
- const [isFocusVisible, setIsFocusVisible] = useState(false);
687
- useEffect(() => {
688
- setupModality();
689
- }, []);
690
- const onFocus = useCallback(() => {
691
- if (hadKeyboardEvent) {
692
- setIsFocusVisible(true);
693
- }
694
- }, []);
695
- const onBlur = useCallback(() => {
696
- setIsFocusVisible(false);
697
- }, []);
698
- const focusProps = { onFocus, onBlur };
699
- return { isFocusVisible, focusProps };
700
897
  }
701
898
 
702
899
  // src/primitives/Frame/Frame.utils.ts
@@ -793,14 +990,260 @@ function resolveAlignment(align) {
793
990
  function resolveJustification(justify) {
794
991
  return JUSTIFY_MAP[justify];
795
992
  }
796
- function resolveFlexDirection(direction, reverse) {
797
- if (direction === "horizontal") {
798
- return reverse ? "row-reverse" : "row";
799
- }
800
- return reverse ? "column-reverse" : "column";
993
+ function resolveFlexDirection(direction, reverse) {
994
+ if (direction === "horizontal") {
995
+ return reverse ? "row-reverse" : "row";
996
+ }
997
+ return reverse ? "column-reverse" : "column";
998
+ }
999
+
1000
+ // src/primitives/Wrapper/Wrapper.styles.ts
1001
+ function getWrapperStyles(input) {
1002
+ const {
1003
+ tokens,
1004
+ direction = "vertical",
1005
+ wrap = false,
1006
+ reverse = false,
1007
+ align,
1008
+ justify,
1009
+ padding,
1010
+ gap,
1011
+ width,
1012
+ height,
1013
+ minWidth,
1014
+ maxWidth,
1015
+ minHeight,
1016
+ maxHeight
1017
+ } = input;
1018
+ const container = {};
1019
+ container.flexDirection = resolveFlexDirection(direction, reverse);
1020
+ if (wrap) container.flexWrap = "wrap";
1021
+ if (align) container.alignItems = resolveAlignment(align);
1022
+ if (justify) container.justifyContent = resolveJustification(justify);
1023
+ if (padding !== void 0) {
1024
+ const p = resolvePadding(padding, tokens);
1025
+ container.paddingTop = p.top;
1026
+ container.paddingRight = p.right;
1027
+ container.paddingBottom = p.bottom;
1028
+ container.paddingLeft = p.left;
1029
+ }
1030
+ if (gap !== void 0) {
1031
+ const g = resolveGap(gap, tokens);
1032
+ container.rowGap = g.rowGap;
1033
+ container.columnGap = g.columnGap;
1034
+ }
1035
+ Object.assign(container, resolveSizing(width, height));
1036
+ if (minWidth !== void 0) container.minWidth = minWidth;
1037
+ if (maxWidth !== void 0) container.maxWidth = maxWidth;
1038
+ if (minHeight !== void 0) container.minHeight = minHeight;
1039
+ if (maxHeight !== void 0) container.maxHeight = maxHeight;
1040
+ return StyleSheet.create({ c: container }).c;
1041
+ }
1042
+
1043
+ // src/primitives/Wrapper/Wrapper.tsx
1044
+ function Wrapper({
1045
+ children,
1046
+ direction,
1047
+ wrap,
1048
+ reverse,
1049
+ align,
1050
+ justify,
1051
+ padding,
1052
+ gap,
1053
+ width,
1054
+ height,
1055
+ minWidth,
1056
+ maxWidth,
1057
+ minHeight,
1058
+ maxHeight,
1059
+ style,
1060
+ // Testing & platform
1061
+ testID,
1062
+ nativeID,
1063
+ ref
1064
+ }) {
1065
+ const tokens = useTokens(1);
1066
+ const containerStyle = useMemo(
1067
+ () => getWrapperStyles({
1068
+ tokens,
1069
+ direction,
1070
+ wrap,
1071
+ reverse,
1072
+ align,
1073
+ justify,
1074
+ padding,
1075
+ gap,
1076
+ width,
1077
+ height,
1078
+ minWidth,
1079
+ maxWidth,
1080
+ minHeight,
1081
+ maxHeight
1082
+ }),
1083
+ [
1084
+ tokens,
1085
+ direction,
1086
+ wrap,
1087
+ reverse,
1088
+ align,
1089
+ justify,
1090
+ padding,
1091
+ gap,
1092
+ width,
1093
+ height,
1094
+ minWidth,
1095
+ maxWidth,
1096
+ minHeight,
1097
+ maxHeight
1098
+ ]
1099
+ );
1100
+ const userStyles = Array.isArray(style) ? style : style ? [style] : [];
1101
+ return /* @__PURE__ */ React13.createElement(
1102
+ View,
1103
+ {
1104
+ ref,
1105
+ testID,
1106
+ nativeID,
1107
+ accessibilityRole: "none",
1108
+ style: [containerStyle, ...userStyles]
1109
+ },
1110
+ children
1111
+ );
1112
+ }
1113
+
1114
+ // src/composites/actions/Button/Button.tsx
1115
+ function Button({
1116
+ children,
1117
+ icon,
1118
+ iconPosition = "left",
1119
+ variant = "primary",
1120
+ semantic = "neutral",
1121
+ size = "md",
1122
+ disabled = false,
1123
+ style,
1124
+ textStyle,
1125
+ ...pressableProps
1126
+ }) {
1127
+ const tokens = useTokens();
1128
+ const { variantColors, sizeTokens } = React13.useMemo(
1129
+ () => getButtonConfig(variant, semantic, size, disabled, tokens),
1130
+ [variant, semantic, size, disabled, tokens]
1131
+ );
1132
+ const padding = React13.useMemo(
1133
+ () => computeButtonPadding(size, !!icon, !!children, iconPosition),
1134
+ [size, icon, children, iconPosition]
1135
+ );
1136
+ return /* @__PURE__ */ React13.createElement(Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1137
+ // Wrapper handles layout: direction, gap, alignment (padding via style)
1138
+ /* @__PURE__ */ React13.createElement(
1139
+ Wrapper,
1140
+ {
1141
+ direction: "horizontal",
1142
+ align: "center",
1143
+ justify: "center",
1144
+ gap: sizeTokens.gap,
1145
+ style: [
1146
+ {
1147
+ ...padding,
1148
+ // Asymmetric horizontal padding for text optical balance
1149
+ backgroundColor: pressed && !disabled ? variantColors.pressedBg : hovered && !disabled ? variantColors.hoveredBg : variantColors.bg,
1150
+ borderRadius: sizeTokens.borderRadius,
1151
+ borderWidth: variantColors.borderWidth,
1152
+ // Always 1 for consistent sizing
1153
+ borderColor: variantColors.borderColor || "transparent",
1154
+ opacity: disabled ? 0.4 : 1
1155
+ },
1156
+ ...Array.isArray(style) ? style : style ? [style] : []
1157
+ ]
1158
+ },
1159
+ icon && iconPosition === "left" && /* @__PURE__ */ React13.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1160
+ children && // Text primitive with semantic props + color style override
1161
+ /* @__PURE__ */ React13.createElement(
1162
+ Text2,
1163
+ {
1164
+ size: sizeTokens.textSize,
1165
+ weight: "semibold",
1166
+ style: [
1167
+ { color: variantColors.textColor },
1168
+ ...Array.isArray(textStyle) ? textStyle : textStyle ? [textStyle] : []
1169
+ ]
1170
+ },
1171
+ children
1172
+ ),
1173
+ icon && iconPosition === "right" && /* @__PURE__ */ React13.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1174
+ )
1175
+ ));
1176
+ }
1177
+ function getCardStyles(tokens, disabled) {
1178
+ return StyleSheet.create({
1179
+ container: {
1180
+ backgroundColor: srgbToHex(tokens.background.srgb),
1181
+ borderWidth: 1,
1182
+ borderColor: srgbToHex(tokens.border.srgb),
1183
+ borderRadius: tokens.radius.lg,
1184
+ padding: tokens.spacing["16"],
1185
+ opacity: disabled ? 0.5 : 1
1186
+ }
1187
+ });
1188
+ }
1189
+
1190
+ // src/composites/layout/Card/Card.tsx
1191
+ function Card({
1192
+ children,
1193
+ elevation = 1,
1194
+ style,
1195
+ disabled = false
1196
+ }) {
1197
+ const tokens = useTokens(elevation);
1198
+ const styles = React13.useMemo(
1199
+ () => getCardStyles(tokens, disabled),
1200
+ [tokens, disabled]
1201
+ );
1202
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1203
+ }
1204
+ var hadKeyboardEvent = false;
1205
+ var isListenerSetup = false;
1206
+ function setupModality() {
1207
+ if (isListenerSetup || typeof document === "undefined") return;
1208
+ isListenerSetup = true;
1209
+ const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
1210
+ "Tab",
1211
+ "ArrowUp",
1212
+ "ArrowDown",
1213
+ "ArrowLeft",
1214
+ "ArrowRight",
1215
+ "Enter",
1216
+ " ",
1217
+ "Escape"
1218
+ ]);
1219
+ document.addEventListener("keydown", (e) => {
1220
+ if (NAVIGATION_KEYS.has(e.key)) {
1221
+ hadKeyboardEvent = true;
1222
+ }
1223
+ }, true);
1224
+ document.addEventListener("pointerdown", () => {
1225
+ hadKeyboardEvent = false;
1226
+ }, true);
1227
+ document.addEventListener("mousedown", () => {
1228
+ hadKeyboardEvent = false;
1229
+ }, true);
1230
+ }
1231
+ function useFocusVisible() {
1232
+ const [isFocusVisible, setIsFocusVisible] = useState(false);
1233
+ useEffect(() => {
1234
+ setupModality();
1235
+ }, []);
1236
+ const onFocus = useCallback(() => {
1237
+ if (hadKeyboardEvent) {
1238
+ setIsFocusVisible(true);
1239
+ }
1240
+ }, []);
1241
+ const onBlur = useCallback(() => {
1242
+ setIsFocusVisible(false);
1243
+ }, []);
1244
+ const focusProps = { onFocus, onBlur };
1245
+ return { isFocusVisible, focusProps };
801
1246
  }
802
-
803
- // src/primitives/Frame/Frame.styles.ts
804
1247
  function getFrameStyles(input) {
805
1248
  const {
806
1249
  tokens,
@@ -907,9 +1350,9 @@ function getFrameStyles(input) {
907
1350
 
908
1351
  // src/primitives/Frame/Frame.tsx
909
1352
  function wrapTextChildren(children, textStyle) {
910
- return React11.Children.map(children, (child) => {
1353
+ return React13.Children.map(children, (child) => {
911
1354
  if (typeof child === "string" || typeof child === "number") {
912
- return /* @__PURE__ */ React11.createElement(Text, { style: textStyle }, child);
1355
+ return /* @__PURE__ */ React13.createElement(Text, { style: textStyle }, child);
913
1356
  }
914
1357
  return child;
915
1358
  });
@@ -921,8 +1364,7 @@ function toElevationLevel(frameElevation) {
921
1364
  }
922
1365
  function Frame({
923
1366
  children,
924
- // Theme & elevation
925
- theme,
1367
+ // Elevation
926
1368
  elevation,
927
1369
  // Layout
928
1370
  layout,
@@ -961,25 +1403,22 @@ function Frame({
961
1403
  // Style override
962
1404
  style
963
1405
  }) {
964
- const { config, mode, theme: providerTheme } = useNewtoneTheme();
1406
+ const { config, mode } = useNewtoneTheme();
965
1407
  const parentFrameCtx = useFrameContext();
966
- const resolvedTheme = theme ?? parentFrameCtx?.theme ?? providerTheme;
967
1408
  const resolvedFrameElevation = elevation ?? 0;
968
1409
  const resolvedElevation = elevation !== void 0 ? toElevationLevel(elevation) : parentFrameCtx?.elevation ?? 1;
969
1410
  const tokens = useMemo(() => {
970
- const themeMapping = config.themes[resolvedTheme];
971
1411
  return computeTokens(
972
1412
  config.colorSystem,
973
1413
  mode,
974
- themeMapping,
975
1414
  resolvedElevation,
976
- config.elevation.offsets,
977
1415
  config.spacing,
978
1416
  config.radius,
979
1417
  config.typography,
980
- config.icons
1418
+ config.icons,
1419
+ config.tokenOverrides
981
1420
  );
982
- }, [config, mode, resolvedTheme, resolvedElevation]);
1421
+ }, [config, mode, resolvedElevation]);
983
1422
  const styles = useMemo(
984
1423
  () => getFrameStyles({
985
1424
  tokens,
@@ -1029,8 +1468,8 @@ function Frame({
1029
1468
  ]
1030
1469
  );
1031
1470
  const contextValue = useMemo(
1032
- () => ({ theme: resolvedTheme, elevation: resolvedElevation }),
1033
- [resolvedTheme, resolvedElevation]
1471
+ () => ({ elevation: resolvedElevation, tokens }),
1472
+ [resolvedElevation, tokens]
1034
1473
  );
1035
1474
  const webOverrides = [];
1036
1475
  if (styles.gridWebStyle) {
@@ -1045,7 +1484,7 @@ function Frame({
1045
1484
  const focusRingStyle = isFocusVisible && !disabled ? {
1046
1485
  outlineWidth: 2,
1047
1486
  outlineStyle: "solid",
1048
- outlineColor: srgbToHex(tokens.interactive.srgb),
1487
+ outlineColor: srgbToHex(tokens.accent.fill.srgb),
1049
1488
  outlineOffset: 2
1050
1489
  } : void 0;
1051
1490
  const webFocusProps = isInteractive ? focusProps : {};
@@ -1062,10 +1501,10 @@ function Frame({
1062
1501
  () => wrapTextChildren(children, textStyle),
1063
1502
  [children, textStyle]
1064
1503
  );
1065
- return /* @__PURE__ */ React11.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1504
+ return /* @__PURE__ */ React13.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1066
1505
  // Pressable handles taps. When href is set, react-native-web renders
1067
1506
  // it as an <a> tag so it works like a regular link on the web.
1068
- /* @__PURE__ */ React11.createElement(
1507
+ /* @__PURE__ */ React13.createElement(
1069
1508
  Pressable,
1070
1509
  {
1071
1510
  ref,
@@ -1090,7 +1529,7 @@ function Frame({
1090
1529
  )
1091
1530
  ) : (
1092
1531
  // Non-interactive Frame: just a plain View with no tap handling.
1093
- /* @__PURE__ */ React11.createElement(
1532
+ /* @__PURE__ */ React13.createElement(
1094
1533
  View,
1095
1534
  {
1096
1535
  ref,
@@ -1136,11 +1575,11 @@ function TextInput({
1136
1575
  ...textInputProps
1137
1576
  }) {
1138
1577
  const tokens = useTokens(1);
1139
- const styles = React11.useMemo(
1578
+ const styles = React13.useMemo(
1140
1579
  () => getTextInputStyles(tokens, disabled),
1141
1580
  [tokens, disabled]
1142
1581
  );
1143
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React11.createElement(
1582
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
1144
1583
  TextInput$1,
1145
1584
  {
1146
1585
  style: styles.input,
@@ -1177,7 +1616,7 @@ function getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpe
1177
1616
  });
1178
1617
  }
1179
1618
 
1180
- // src/Popover/Popover.tsx
1619
+ // src/composites/overlays/Popover/Popover.tsx
1181
1620
  var openPopovers = /* @__PURE__ */ new Set();
1182
1621
  function Popover({
1183
1622
  isOpen,
@@ -1243,15 +1682,15 @@ function Popover({
1243
1682
  [styles.content, contentStyle]
1244
1683
  );
1245
1684
  const webProps = { onKeyDown: handleKeyDown };
1246
- return /* @__PURE__ */ React11.createElement(
1685
+ return /* @__PURE__ */ React13.createElement(
1247
1686
  View,
1248
1687
  {
1249
1688
  ref: containerRef,
1250
1689
  style: containerStyles,
1251
1690
  ...webProps
1252
1691
  },
1253
- /* @__PURE__ */ React11.createElement(View, { onLayout: onTriggerLayout }, trigger),
1254
- isOpen && /* @__PURE__ */ React11.createElement(View, { style: mergedContentStyles }, children)
1692
+ /* @__PURE__ */ React13.createElement(View, { onLayout: onTriggerLayout }, trigger),
1693
+ isOpen && /* @__PURE__ */ React13.createElement(View, { style: mergedContentStyles }, children)
1255
1694
  );
1256
1695
  }
1257
1696
  function usePopover(options) {
@@ -1274,7 +1713,7 @@ function usePopover(options) {
1274
1713
  return { isOpen, open, close, toggle };
1275
1714
  }
1276
1715
 
1277
- // src/Select/Select.types.ts
1716
+ // src/composites/form-controls/Select/Select.types.ts
1278
1717
  function isOptionGroup(item) {
1279
1718
  return "options" in item;
1280
1719
  }
@@ -1448,7 +1887,7 @@ function SelectOptionRow({
1448
1887
  const paddingHorizontal = size === "sm" ? tokens.spacing["08"] : tokens.spacing["12"];
1449
1888
  const fontSize = size === "sm" ? tokens.typography.size.sm : tokens.typography.size.base;
1450
1889
  if (renderOption) {
1451
- return /* @__PURE__ */ React11.createElement(
1890
+ return /* @__PURE__ */ React13.createElement(
1452
1891
  Pressable,
1453
1892
  {
1454
1893
  onPress: option.disabled ? void 0 : onSelect,
@@ -1459,7 +1898,7 @@ function SelectOptionRow({
1459
1898
  renderOption(option, { isSelected, isFocused })
1460
1899
  );
1461
1900
  }
1462
- return /* @__PURE__ */ React11.createElement(
1901
+ return /* @__PURE__ */ React13.createElement(
1463
1902
  Pressable,
1464
1903
  {
1465
1904
  onPress: option.disabled ? void 0 : onSelect,
@@ -1488,7 +1927,7 @@ function SelectOptionRow({
1488
1927
  }
1489
1928
  ]
1490
1929
  },
1491
- /* @__PURE__ */ React11.createElement(
1930
+ /* @__PURE__ */ React13.createElement(
1492
1931
  Text,
1493
1932
  {
1494
1933
  style: [
@@ -1500,7 +1939,7 @@ function SelectOptionRow({
1500
1939
  },
1501
1940
  isSelected && {
1502
1941
  fontWeight: tokens.typography.weight.semibold,
1503
- color: srgbToHex(tokens.interactive.srgb)
1942
+ color: srgbToHex(tokens.accent.fill.srgb)
1504
1943
  },
1505
1944
  option.disabled && {
1506
1945
  color: srgbToHex(tokens.textSecondary.srgb)
@@ -1510,12 +1949,12 @@ function SelectOptionRow({
1510
1949
  },
1511
1950
  option.label
1512
1951
  ),
1513
- isSelected && /* @__PURE__ */ React11.createElement(View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React11.createElement(
1952
+ isSelected && /* @__PURE__ */ React13.createElement(View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React13.createElement(
1514
1953
  Icon,
1515
1954
  {
1516
1955
  name: "check",
1517
1956
  size: fontSize,
1518
- color: srgbToHex(tokens.interactive.srgb)
1957
+ color: srgbToHex(tokens.accent.fill.srgb)
1519
1958
  }
1520
1959
  ))
1521
1960
  );
@@ -1565,7 +2004,7 @@ function Select({
1565
2004
  const displayLabel = selectedOption?.label ?? placeholder ?? value;
1566
2005
  const iconColor = disabled ? srgbToHex(tokens.textSecondary.srgb) : srgbToHex(tokens.textPrimary.srgb);
1567
2006
  const triggerWebProps = { onKeyDown: handleKeyDown };
1568
- const trigger = /* @__PURE__ */ React11.createElement(
2007
+ const trigger = /* @__PURE__ */ React13.createElement(
1569
2008
  Pressable,
1570
2009
  {
1571
2010
  onPress: disabled ? void 0 : toggle,
@@ -1575,8 +2014,8 @@ function Select({
1575
2014
  ...triggerWebProps,
1576
2015
  style: styles.trigger
1577
2016
  },
1578
- renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React11.createElement(Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
1579
- /* @__PURE__ */ React11.createElement(View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React11.createElement(
2017
+ renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React13.createElement(Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
2018
+ /* @__PURE__ */ React13.createElement(View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React13.createElement(
1580
2019
  Icon,
1581
2020
  {
1582
2021
  name: isOpen ? "expand_less" : "expand_more",
@@ -1585,14 +2024,14 @@ function Select({
1585
2024
  }
1586
2025
  ))
1587
2026
  );
1588
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React11.createElement(
2027
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
1589
2028
  Popover,
1590
2029
  {
1591
2030
  isOpen: isOpen && !disabled,
1592
2031
  onClose: close,
1593
2032
  trigger
1594
2033
  },
1595
- /* @__PURE__ */ React11.createElement(
2034
+ /* @__PURE__ */ React13.createElement(
1596
2035
  ScrollView,
1597
2036
  {
1598
2037
  bounces: false,
@@ -1601,7 +2040,7 @@ function Select({
1601
2040
  },
1602
2041
  options.map((item) => {
1603
2042
  if (isOptionGroup(item)) {
1604
- return /* @__PURE__ */ React11.createElement(View, { key: item.label }, /* @__PURE__ */ React11.createElement(Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React11.createElement(
2043
+ return /* @__PURE__ */ React13.createElement(View, { key: item.label }, /* @__PURE__ */ React13.createElement(Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React13.createElement(
1605
2044
  SelectOptionRow,
1606
2045
  {
1607
2046
  key: opt.value,
@@ -1617,7 +2056,7 @@ function Select({
1617
2056
  }
1618
2057
  )));
1619
2058
  }
1620
- return /* @__PURE__ */ React11.createElement(
2059
+ return /* @__PURE__ */ React13.createElement(
1621
2060
  SelectOptionRow,
1622
2061
  {
1623
2062
  key: item.value,
@@ -1658,7 +2097,7 @@ function getToggleStyles(tokens, value, disabled) {
1658
2097
  width: TRACK_WIDTH,
1659
2098
  height: TRACK_HEIGHT,
1660
2099
  borderRadius: TRACK_HEIGHT / 2,
1661
- backgroundColor: value ? srgbToHex(tokens.interactive.srgb) : srgbToHex(tokens.border.srgb),
2100
+ backgroundColor: value ? srgbToHex(tokens.accent.fill.srgb) : srgbToHex(tokens.border.srgb),
1662
2101
  justifyContent: "center",
1663
2102
  paddingHorizontal: THUMB_OFFSET
1664
2103
  },
@@ -1672,7 +2111,7 @@ function getToggleStyles(tokens, value, disabled) {
1672
2111
  });
1673
2112
  }
1674
2113
 
1675
- // src/Toggle/Toggle.tsx
2114
+ // src/composites/form-controls/Toggle/Toggle.tsx
1676
2115
  function Toggle({
1677
2116
  value,
1678
2117
  onValueChange,
@@ -1681,16 +2120,16 @@ function Toggle({
1681
2120
  style
1682
2121
  }) {
1683
2122
  const tokens = useTokens(1);
1684
- const styles = React11.useMemo(
2123
+ const styles = React13.useMemo(
1685
2124
  () => getToggleStyles(tokens, value, disabled),
1686
2125
  [tokens, value, disabled]
1687
2126
  );
1688
- const handlePress = React11.useCallback(() => {
2127
+ const handlePress = React13.useCallback(() => {
1689
2128
  if (!disabled) {
1690
2129
  onValueChange(!value);
1691
2130
  }
1692
2131
  }, [disabled, value, onValueChange]);
1693
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React11.createElement(
2132
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), /* @__PURE__ */ React13.createElement(
1694
2133
  Pressable,
1695
2134
  {
1696
2135
  onPress: handlePress,
@@ -1698,7 +2137,7 @@ function Toggle({
1698
2137
  accessibilityRole: "switch",
1699
2138
  accessibilityState: { checked: value, disabled }
1700
2139
  },
1701
- /* @__PURE__ */ React11.createElement(View, { style: styles.track }, /* @__PURE__ */ React11.createElement(View, { style: styles.thumb }))
2140
+ /* @__PURE__ */ React13.createElement(View, { style: styles.track }, /* @__PURE__ */ React13.createElement(View, { style: styles.thumb }))
1702
2141
  ));
1703
2142
  }
1704
2143
  var TRACK_HEIGHT2 = 6;
@@ -1758,19 +2197,19 @@ function getSliderStyles(tokens, disabled) {
1758
2197
  left: 0,
1759
2198
  height: TRACK_HEIGHT2,
1760
2199
  borderRadius: TRACK_HEIGHT2 / 2,
1761
- backgroundColor: srgbToHex(tokens.interactive.srgb)
2200
+ backgroundColor: srgbToHex(tokens.accent.fill.srgb)
1762
2201
  },
1763
2202
  thumb: {
1764
2203
  position: "absolute",
1765
2204
  width: THUMB_SIZE2,
1766
2205
  height: THUMB_SIZE2,
1767
2206
  borderRadius: THUMB_SIZE2 / 2,
1768
- backgroundColor: srgbToHex(tokens.interactive.srgb)
2207
+ backgroundColor: srgbToHex(tokens.accent.fill.srgb)
1769
2208
  }
1770
2209
  });
1771
2210
  }
1772
2211
 
1773
- // src/Slider/Slider.tsx
2212
+ // src/composites/range-inputs/Slider/Slider.tsx
1774
2213
  function Slider({
1775
2214
  value,
1776
2215
  onValueChange,
@@ -1784,41 +2223,41 @@ function Slider({
1784
2223
  style
1785
2224
  }) {
1786
2225
  const tokens = useTokens(1);
1787
- const styles = React11.useMemo(
2226
+ const styles = React13.useMemo(
1788
2227
  () => getSliderStyles(tokens, disabled),
1789
2228
  [tokens, disabled]
1790
2229
  );
1791
- const trackRef = React11.useRef(null);
1792
- const trackWidth = React11.useRef(0);
1793
- const trackPageX = React11.useRef(0);
1794
- const onValueChangeRef = React11.useRef(onValueChange);
1795
- const minRef = React11.useRef(min);
1796
- const maxRef = React11.useRef(max);
1797
- const stepRef = React11.useRef(step);
1798
- const disabledRef = React11.useRef(disabled);
1799
- React11.useEffect(() => {
2230
+ const trackRef = React13.useRef(null);
2231
+ const trackWidth = React13.useRef(0);
2232
+ const trackPageX = React13.useRef(0);
2233
+ const onValueChangeRef = React13.useRef(onValueChange);
2234
+ const minRef = React13.useRef(min);
2235
+ const maxRef = React13.useRef(max);
2236
+ const stepRef = React13.useRef(step);
2237
+ const disabledRef = React13.useRef(disabled);
2238
+ React13.useEffect(() => {
1800
2239
  onValueChangeRef.current = onValueChange;
1801
2240
  }, [onValueChange]);
1802
- React11.useEffect(() => {
2241
+ React13.useEffect(() => {
1803
2242
  minRef.current = min;
1804
2243
  }, [min]);
1805
- React11.useEffect(() => {
2244
+ React13.useEffect(() => {
1806
2245
  maxRef.current = max;
1807
2246
  }, [max]);
1808
- React11.useEffect(() => {
2247
+ React13.useEffect(() => {
1809
2248
  stepRef.current = step;
1810
2249
  }, [step]);
1811
- React11.useEffect(() => {
2250
+ React13.useEffect(() => {
1812
2251
  disabledRef.current = disabled;
1813
2252
  }, [disabled]);
1814
- const computeValue = React11.useCallback((pageX) => {
2253
+ const computeValue = React13.useCallback((pageX) => {
1815
2254
  const localX = pageX - trackPageX.current;
1816
2255
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
1817
2256
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
1818
2257
  const stepped = Math.round(raw / stepRef.current) * stepRef.current;
1819
2258
  return Math.min(maxRef.current, Math.max(minRef.current, stepped));
1820
2259
  }, []);
1821
- const panResponder = React11.useRef(
2260
+ const panResponder = React13.useRef(
1822
2261
  PanResponder.create({
1823
2262
  onStartShouldSetPanResponder: () => !disabledRef.current,
1824
2263
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -1834,7 +2273,7 @@ function Slider({
1834
2273
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE2);
1835
2274
  const thumbLeft = ratio * usableWidth;
1836
2275
  const fillWidth = thumbLeft + THUMB_SIZE2 / 2;
1837
- const handleValueTextSubmit = React11.useCallback(
2276
+ const handleValueTextSubmit = React13.useCallback(
1838
2277
  (text) => {
1839
2278
  const raw = Number(text);
1840
2279
  if (!Number.isNaN(raw)) {
@@ -1843,12 +2282,12 @@ function Slider({
1843
2282
  },
1844
2283
  [onValueChange, min, max]
1845
2284
  );
1846
- const [editText, setEditText] = React11.useState(String(value));
1847
- React11.useEffect(() => {
2285
+ const [editText, setEditText] = React13.useState(String(value));
2286
+ React13.useEffect(() => {
1848
2287
  setEditText(String(value));
1849
2288
  }, [value]);
1850
2289
  const showLabel = label || showValue || editableValue;
1851
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React11.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React11.createElement(
2290
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13.createElement(
1852
2291
  TextInput$1,
1853
2292
  {
1854
2293
  style: styles.valueInput,
@@ -1860,7 +2299,7 @@ function Slider({
1860
2299
  selectTextOnFocus: true,
1861
2300
  editable: !disabled
1862
2301
  }
1863
- ) : showValue && /* @__PURE__ */ React11.createElement(Text, { style: styles.value }, value)), /* @__PURE__ */ React11.createElement(
2302
+ ) : showValue && /* @__PURE__ */ React13.createElement(Text, { style: styles.value }, value)), /* @__PURE__ */ React13.createElement(
1864
2303
  View,
1865
2304
  {
1866
2305
  ref: trackRef,
@@ -1873,9 +2312,9 @@ function Slider({
1873
2312
  },
1874
2313
  ...panResponder.panHandlers
1875
2314
  },
1876
- /* @__PURE__ */ React11.createElement(View, { style: styles.trackRail }),
1877
- /* @__PURE__ */ React11.createElement(View, { style: [styles.trackFill, { width: fillWidth }] }),
1878
- /* @__PURE__ */ React11.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2315
+ /* @__PURE__ */ React13.createElement(View, { style: styles.trackRail }),
2316
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.trackFill, { width: fillWidth }] }),
2317
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
1879
2318
  ));
1880
2319
  }
1881
2320
  var TRACK_HEIGHT3 = 22;
@@ -1985,7 +2424,7 @@ function getHueSliderStyles(tokens, disabled) {
1985
2424
  });
1986
2425
  }
1987
2426
 
1988
- // src/HueSlider/HueSlider.tsx
2427
+ // src/composites/range-inputs/HueSlider/HueSlider.tsx
1989
2428
  function HueSlider({
1990
2429
  value,
1991
2430
  onValueChange,
@@ -1998,41 +2437,41 @@ function HueSlider({
1998
2437
  style
1999
2438
  }) {
2000
2439
  const tokens = useTokens(1);
2001
- const styles = React11.useMemo(
2440
+ const styles = React13.useMemo(
2002
2441
  () => getHueSliderStyles(tokens, disabled),
2003
2442
  [tokens, disabled]
2004
2443
  );
2005
- const segments = React11.useMemo(
2444
+ const segments = React13.useMemo(
2006
2445
  () => buildHueSegments(min, max),
2007
2446
  [min, max]
2008
2447
  );
2009
- const trackRef = React11.useRef(null);
2010
- const trackWidth = React11.useRef(0);
2011
- const trackPageX = React11.useRef(0);
2012
- const onValueChangeRef = React11.useRef(onValueChange);
2013
- const minRef = React11.useRef(min);
2014
- const maxRef = React11.useRef(max);
2015
- const disabledRef = React11.useRef(disabled);
2016
- React11.useEffect(() => {
2448
+ const trackRef = React13.useRef(null);
2449
+ const trackWidth = React13.useRef(0);
2450
+ const trackPageX = React13.useRef(0);
2451
+ const onValueChangeRef = React13.useRef(onValueChange);
2452
+ const minRef = React13.useRef(min);
2453
+ const maxRef = React13.useRef(max);
2454
+ const disabledRef = React13.useRef(disabled);
2455
+ React13.useEffect(() => {
2017
2456
  onValueChangeRef.current = onValueChange;
2018
2457
  }, [onValueChange]);
2019
- React11.useEffect(() => {
2458
+ React13.useEffect(() => {
2020
2459
  minRef.current = min;
2021
2460
  }, [min]);
2022
- React11.useEffect(() => {
2461
+ React13.useEffect(() => {
2023
2462
  maxRef.current = max;
2024
2463
  }, [max]);
2025
- React11.useEffect(() => {
2464
+ React13.useEffect(() => {
2026
2465
  disabledRef.current = disabled;
2027
2466
  }, [disabled]);
2028
- const computeHue = React11.useCallback((pageX) => {
2467
+ const computeHue = React13.useCallback((pageX) => {
2029
2468
  const localX = pageX - trackPageX.current;
2030
2469
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2031
2470
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2032
2471
  const stepped = Math.round(raw);
2033
2472
  return (stepped % 360 + 360) % 360;
2034
2473
  }, []);
2035
- const panResponder = React11.useRef(
2474
+ const panResponder = React13.useRef(
2036
2475
  PanResponder.create({
2037
2476
  onStartShouldSetPanResponder: () => !disabledRef.current,
2038
2477
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2048,7 +2487,7 @@ function HueSlider({
2048
2487
  const ratio = max > min ? (sliderValue - min) / (max - min) : 0;
2049
2488
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE3);
2050
2489
  const thumbLeft = ratio * usableWidth;
2051
- const handleValueTextSubmit = React11.useCallback(
2490
+ const handleValueTextSubmit = React13.useCallback(
2052
2491
  (text) => {
2053
2492
  const raw = Number(text);
2054
2493
  if (!Number.isNaN(raw)) {
@@ -2057,12 +2496,12 @@ function HueSlider({
2057
2496
  },
2058
2497
  [onValueChange]
2059
2498
  );
2060
- const [editText, setEditText] = React11.useState(String(value));
2061
- React11.useEffect(() => {
2499
+ const [editText, setEditText] = React13.useState(String(value));
2500
+ React13.useEffect(() => {
2062
2501
  setEditText(String(value));
2063
2502
  }, [value]);
2064
2503
  const showLabel = label || showValue || editableValue;
2065
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React11.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React11.createElement(
2504
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, label && /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13.createElement(
2066
2505
  TextInput$1,
2067
2506
  {
2068
2507
  style: styles.valueInput,
@@ -2074,7 +2513,7 @@ function HueSlider({
2074
2513
  selectTextOnFocus: true,
2075
2514
  editable: !disabled
2076
2515
  }
2077
- ) : showValue && /* @__PURE__ */ React11.createElement(Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React11.createElement(
2516
+ ) : showValue && /* @__PURE__ */ React13.createElement(Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React13.createElement(
2078
2517
  View,
2079
2518
  {
2080
2519
  ref: trackRef,
@@ -2087,8 +2526,8 @@ function HueSlider({
2087
2526
  },
2088
2527
  ...panResponder.panHandlers
2089
2528
  },
2090
- /* @__PURE__ */ React11.createElement(View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React11.createElement(View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2091
- /* @__PURE__ */ React11.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2529
+ /* @__PURE__ */ React13.createElement(View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React13.createElement(View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2530
+ /* @__PURE__ */ React13.createElement(View, { style: [styles.thumb, { left: thumbLeft }] })
2092
2531
  ));
2093
2532
  }
2094
2533
  var TRACK_HEIGHT4 = 22;
@@ -2135,295 +2574,131 @@ function getColorScaleSliderStyles(tokens, disabled) {
2135
2574
  backgroundColor: "#ffffff",
2136
2575
  borderWidth: 2,
2137
2576
  borderColor: srgbToHex(tokens.border.srgb)
2138
- },
2139
- warning: {
2140
- fontFamily: tokens.typography.fonts.default,
2141
- fontSize: tokens.typography.size.xs,
2142
- fontWeight: tokens.typography.weight.medium,
2143
- color: srgbToHex(tokens.error.srgb)
2144
- }
2145
- });
2146
- }
2147
-
2148
- // src/ColorScaleSlider/ColorScaleSlider.tsx
2149
- function ColorScaleSlider({
2150
- colors,
2151
- value,
2152
- onValueChange,
2153
- label,
2154
- warning,
2155
- trimEnds = false,
2156
- snap = false,
2157
- disabled = false,
2158
- animateValue = false,
2159
- style
2160
- }) {
2161
- const tokens = useTokens(1);
2162
- const styles = React11.useMemo(
2163
- () => getColorScaleSliderStyles(tokens, disabled),
2164
- [tokens, disabled]
2165
- );
2166
- const trackRef = React11.useRef(null);
2167
- const trackWidth = React11.useRef(0);
2168
- const trackPageX = React11.useRef(0);
2169
- const isDragging = React11.useRef(false);
2170
- const thumbAnim = React11.useRef(new Animated.Value(0)).current;
2171
- const onValueChangeRef = React11.useRef(onValueChange);
2172
- const disabledRef = React11.useRef(disabled);
2173
- const colorsLengthRef = React11.useRef(colors.length);
2174
- const trimEndsRef = React11.useRef(trimEnds);
2175
- const snapRef = React11.useRef(snap);
2176
- React11.useEffect(() => {
2177
- onValueChangeRef.current = onValueChange;
2178
- }, [onValueChange]);
2179
- React11.useEffect(() => {
2180
- disabledRef.current = disabled;
2181
- }, [disabled]);
2182
- React11.useEffect(() => {
2183
- colorsLengthRef.current = colors.length;
2184
- }, [colors.length]);
2185
- React11.useEffect(() => {
2186
- trimEndsRef.current = trimEnds;
2187
- }, [trimEnds]);
2188
- React11.useEffect(() => {
2189
- snapRef.current = snap;
2190
- }, [snap]);
2191
- const computeNv = React11.useCallback((pageX) => {
2192
- const localX = pageX - trackPageX.current;
2193
- const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2194
- const totalSteps2 = colorsLengthRef.current - 1;
2195
- const minNV2 = trimEndsRef.current ? 1 / totalSteps2 : 0;
2196
- const maxNV2 = trimEndsRef.current ? 1 - 1 / totalSteps2 : 1;
2197
- const range2 = maxNV2 - minNV2;
2198
- let nv = maxNV2 - ratio2 * range2;
2199
- if (snapRef.current && totalSteps2 > 0) {
2200
- const stepNv = 1 / totalSteps2;
2201
- nv = Math.round(nv / stepNv) * stepNv;
2202
- nv = Math.min(maxNV2, Math.max(minNV2, nv));
2203
- }
2204
- return nv;
2205
- }, []);
2206
- const panResponder = React11.useRef(
2207
- PanResponder.create({
2208
- onStartShouldSetPanResponder: () => !disabledRef.current,
2209
- onMoveShouldSetPanResponder: () => !disabledRef.current,
2210
- onPanResponderGrant: (evt) => {
2211
- isDragging.current = true;
2212
- onValueChangeRef.current(computeNv(evt.nativeEvent.pageX));
2213
- },
2214
- onPanResponderMove: (_evt, gestureState) => {
2215
- onValueChangeRef.current(computeNv(gestureState.moveX));
2216
- },
2217
- onPanResponderRelease: () => {
2218
- isDragging.current = false;
2219
- },
2220
- onPanResponderTerminate: () => {
2221
- isDragging.current = false;
2222
- }
2223
- })
2224
- ).current;
2225
- const visibleColors = trimEnds ? colors.slice(1, -1) : colors;
2226
- const totalSteps = colors.length - 1;
2227
- const minNV = trimEnds ? 1 / totalSteps : 0;
2228
- const maxNV = trimEnds ? 1 - 1 / totalSteps : 1;
2229
- const range = maxNV - minNV;
2230
- const clampedValue = value !== void 0 ? Math.min(maxNV, Math.max(minNV, value)) : (maxNV + minNV) / 2;
2231
- const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
2232
- const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE4);
2233
- const thumbLeft = ratio * usableWidth;
2234
- React11.useEffect(() => {
2235
- if (isDragging.current || !animateValue) {
2236
- thumbAnim.setValue(thumbLeft);
2237
- } else {
2238
- Animated.timing(thumbAnim, {
2239
- toValue: thumbLeft,
2240
- duration: 300,
2241
- useNativeDriver: false
2242
- }).start();
2243
- }
2244
- }, [thumbLeft, animateValue, thumbAnim]);
2245
- return /* @__PURE__ */ React11.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React11.createElement(View, { style: styles.labelRow }, /* @__PURE__ */ React11.createElement(Text, { style: styles.label }, label)), /* @__PURE__ */ React11.createElement(
2246
- View,
2247
- {
2248
- ref: trackRef,
2249
- style: styles.trackContainer,
2250
- onLayout: (e) => {
2251
- trackWidth.current = e.nativeEvent.layout.width;
2252
- const newUsableWidth = Math.max(0, e.nativeEvent.layout.width - THUMB_SIZE4);
2253
- thumbAnim.setValue(ratio * newUsableWidth);
2254
- trackRef.current?.measure((_x, _y, _w, _h, pageX) => {
2255
- if (pageX != null) trackPageX.current = pageX;
2256
- });
2257
- },
2258
- ...panResponder.panHandlers
2259
- },
2260
- /* @__PURE__ */ React11.createElement(View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React11.createElement(View, { key: i, style: [styles.segment, { backgroundColor: srgbToHex(color.srgb) }] }))),
2261
- /* @__PURE__ */ React11.createElement(Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2262
- ), warning && /* @__PURE__ */ React11.createElement(Text, { style: styles.warning }, warning));
2263
- }
2264
- function getWrapperStyles(input) {
2265
- const {
2266
- tokens,
2267
- direction = "vertical",
2268
- wrap = false,
2269
- reverse = false,
2270
- align,
2271
- justify,
2272
- padding,
2273
- gap,
2274
- width,
2275
- height,
2276
- minWidth,
2277
- maxWidth,
2278
- minHeight,
2279
- maxHeight
2280
- } = input;
2281
- const container = {};
2282
- container.flexDirection = resolveFlexDirection(direction, reverse);
2283
- if (wrap) container.flexWrap = "wrap";
2284
- if (align) container.alignItems = resolveAlignment(align);
2285
- if (justify) container.justifyContent = resolveJustification(justify);
2286
- if (padding !== void 0) {
2287
- const p = resolvePadding(padding, tokens);
2288
- container.paddingTop = p.top;
2289
- container.paddingRight = p.right;
2290
- container.paddingBottom = p.bottom;
2291
- container.paddingLeft = p.left;
2292
- }
2293
- if (gap !== void 0) {
2294
- const g = resolveGap(gap, tokens);
2295
- container.rowGap = g.rowGap;
2296
- container.columnGap = g.columnGap;
2297
- }
2298
- Object.assign(container, resolveSizing(width, height));
2299
- if (minWidth !== void 0) container.minWidth = minWidth;
2300
- if (maxWidth !== void 0) container.maxWidth = maxWidth;
2301
- if (minHeight !== void 0) container.minHeight = minHeight;
2302
- if (maxHeight !== void 0) container.maxHeight = maxHeight;
2303
- return StyleSheet.create({ c: container }).c;
2304
- }
2305
-
2306
- // src/primitives/Wrapper/Wrapper.tsx
2307
- function Wrapper({
2308
- children,
2309
- direction,
2310
- wrap,
2311
- reverse,
2312
- align,
2313
- justify,
2314
- padding,
2315
- gap,
2316
- width,
2317
- height,
2318
- minWidth,
2319
- maxWidth,
2320
- minHeight,
2321
- maxHeight,
2322
- style,
2323
- // Testing & platform
2324
- testID,
2325
- nativeID,
2326
- ref
2327
- }) {
2328
- const tokens = useTokens(1);
2329
- const containerStyle = useMemo(
2330
- () => getWrapperStyles({
2331
- tokens,
2332
- direction,
2333
- wrap,
2334
- reverse,
2335
- align,
2336
- justify,
2337
- padding,
2338
- gap,
2339
- width,
2340
- height,
2341
- minWidth,
2342
- maxWidth,
2343
- minHeight,
2344
- maxHeight
2345
- }),
2346
- [
2347
- tokens,
2348
- direction,
2349
- wrap,
2350
- reverse,
2351
- align,
2352
- justify,
2353
- padding,
2354
- gap,
2355
- width,
2356
- height,
2357
- minWidth,
2358
- maxWidth,
2359
- minHeight,
2360
- maxHeight
2361
- ]
2362
- );
2363
- const userStyles = Array.isArray(style) ? style : style ? [style] : [];
2364
- return /* @__PURE__ */ React11.createElement(
2365
- View,
2366
- {
2367
- ref,
2368
- testID,
2369
- nativeID,
2370
- accessibilityRole: "none",
2371
- style: [containerStyle, ...userStyles]
2372
- },
2373
- children
2374
- );
2375
- }
2376
- var COLOR_MAP = {
2377
- primary: "textPrimary",
2378
- secondary: "textSecondary",
2379
- interactive: "interactive"
2380
- };
2381
- function Text11({
2382
- children,
2383
- size = "base",
2384
- weight = "regular",
2385
- color = "primary",
2386
- font = "default",
2387
- lineHeight = "normal",
2388
- align,
2389
- numberOfLines,
2390
- elevation = 1,
2391
- style,
2392
- // Accessibility
2393
- accessibilityRole,
2394
- // Testing & platform
2395
- testID,
2396
- nativeID,
2397
- ref
2577
+ },
2578
+ warning: {
2579
+ fontFamily: tokens.typography.fonts.default,
2580
+ fontSize: tokens.typography.size.xs,
2581
+ fontWeight: tokens.typography.weight.medium,
2582
+ color: srgbToHex(tokens.error.fill.srgb)
2583
+ }
2584
+ });
2585
+ }
2586
+
2587
+ // src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.tsx
2588
+ function ColorScaleSlider({
2589
+ colors,
2590
+ value,
2591
+ onValueChange,
2592
+ label,
2593
+ warning,
2594
+ trimEnds = false,
2595
+ snap = false,
2596
+ disabled = false,
2597
+ animateValue = false,
2598
+ style
2398
2599
  }) {
2399
- const tokens = useTokens(elevation);
2400
- const resolvedStyle = useMemo(() => {
2401
- const fontSize = tokens.typography.size[size];
2402
- return {
2403
- // Font family from the theme (e.g. 'default' → 'Inter', 'mono' → 'JetBrains Mono').
2404
- fontFamily: tokens.typography.fonts[font],
2405
- fontSize,
2406
- // Font weight is stored as a number (e.g. 400, 600) but React Native expects a string.
2407
- fontWeight: String(tokens.typography.weight[weight]),
2408
- // Convert the theme color from internal sRGB format to a hex string (e.g. '#1a1a1a').
2409
- color: srgbToHex(tokens[COLOR_MAP[color]].srgb),
2410
- // Line height = font size × multiplier (e.g. 16px × 1.5 = 24px line height).
2411
- lineHeight: fontSize * tokens.typography.lineHeight[lineHeight],
2412
- textAlign: align
2413
- };
2414
- }, [tokens, size, weight, color, font, lineHeight, align]);
2415
- return /* @__PURE__ */ React11.createElement(
2416
- Text,
2600
+ const tokens = useTokens(1);
2601
+ const styles = React13.useMemo(
2602
+ () => getColorScaleSliderStyles(tokens, disabled),
2603
+ [tokens, disabled]
2604
+ );
2605
+ const trackRef = React13.useRef(null);
2606
+ const trackWidth = React13.useRef(0);
2607
+ const trackPageX = React13.useRef(0);
2608
+ const isDragging = React13.useRef(false);
2609
+ const thumbAnim = React13.useRef(new Animated.Value(0)).current;
2610
+ const onValueChangeRef = React13.useRef(onValueChange);
2611
+ const disabledRef = React13.useRef(disabled);
2612
+ const colorsLengthRef = React13.useRef(colors.length);
2613
+ const trimEndsRef = React13.useRef(trimEnds);
2614
+ const snapRef = React13.useRef(snap);
2615
+ React13.useEffect(() => {
2616
+ onValueChangeRef.current = onValueChange;
2617
+ }, [onValueChange]);
2618
+ React13.useEffect(() => {
2619
+ disabledRef.current = disabled;
2620
+ }, [disabled]);
2621
+ React13.useEffect(() => {
2622
+ colorsLengthRef.current = colors.length;
2623
+ }, [colors.length]);
2624
+ React13.useEffect(() => {
2625
+ trimEndsRef.current = trimEnds;
2626
+ }, [trimEnds]);
2627
+ React13.useEffect(() => {
2628
+ snapRef.current = snap;
2629
+ }, [snap]);
2630
+ const computeNv = React13.useCallback((pageX) => {
2631
+ const localX = pageX - trackPageX.current;
2632
+ const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2633
+ const totalSteps2 = colorsLengthRef.current - 1;
2634
+ const minNV2 = trimEndsRef.current ? 1 / totalSteps2 : 0;
2635
+ const maxNV2 = trimEndsRef.current ? 1 - 1 / totalSteps2 : 1;
2636
+ const range2 = maxNV2 - minNV2;
2637
+ let nv = maxNV2 - ratio2 * range2;
2638
+ if (snapRef.current && totalSteps2 > 0) {
2639
+ const stepNv = 1 / totalSteps2;
2640
+ nv = Math.round(nv / stepNv) * stepNv;
2641
+ nv = Math.min(maxNV2, Math.max(minNV2, nv));
2642
+ }
2643
+ return nv;
2644
+ }, []);
2645
+ const panResponder = React13.useRef(
2646
+ PanResponder.create({
2647
+ onStartShouldSetPanResponder: () => !disabledRef.current,
2648
+ onMoveShouldSetPanResponder: () => !disabledRef.current,
2649
+ onPanResponderGrant: (evt) => {
2650
+ isDragging.current = true;
2651
+ onValueChangeRef.current(computeNv(evt.nativeEvent.pageX));
2652
+ },
2653
+ onPanResponderMove: (_evt, gestureState) => {
2654
+ onValueChangeRef.current(computeNv(gestureState.moveX));
2655
+ },
2656
+ onPanResponderRelease: () => {
2657
+ isDragging.current = false;
2658
+ },
2659
+ onPanResponderTerminate: () => {
2660
+ isDragging.current = false;
2661
+ }
2662
+ })
2663
+ ).current;
2664
+ const visibleColors = trimEnds ? colors.slice(1, -1) : colors;
2665
+ const totalSteps = colors.length - 1;
2666
+ const minNV = trimEnds ? 1 / totalSteps : 0;
2667
+ const maxNV = trimEnds ? 1 - 1 / totalSteps : 1;
2668
+ const range = maxNV - minNV;
2669
+ const clampedValue = value !== void 0 ? Math.min(maxNV, Math.max(minNV, value)) : (maxNV + minNV) / 2;
2670
+ const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
2671
+ const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE4);
2672
+ const thumbLeft = ratio * usableWidth;
2673
+ React13.useEffect(() => {
2674
+ if (isDragging.current || !animateValue) {
2675
+ thumbAnim.setValue(thumbLeft);
2676
+ } else {
2677
+ Animated.timing(thumbAnim, {
2678
+ toValue: thumbLeft,
2679
+ duration: 300,
2680
+ useNativeDriver: false
2681
+ }).start();
2682
+ }
2683
+ }, [thumbLeft, animateValue, thumbAnim]);
2684
+ return /* @__PURE__ */ React13.createElement(View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13.createElement(View, { style: styles.labelRow }, /* @__PURE__ */ React13.createElement(Text, { style: styles.label }, label)), /* @__PURE__ */ React13.createElement(
2685
+ View,
2417
2686
  {
2418
- ref,
2419
- testID,
2420
- nativeID,
2421
- accessibilityRole,
2422
- style: style ? [resolvedStyle, ...Array.isArray(style) ? style : [style]] : resolvedStyle,
2423
- numberOfLines
2687
+ ref: trackRef,
2688
+ style: styles.trackContainer,
2689
+ onLayout: (e) => {
2690
+ trackWidth.current = e.nativeEvent.layout.width;
2691
+ const newUsableWidth = Math.max(0, e.nativeEvent.layout.width - THUMB_SIZE4);
2692
+ thumbAnim.setValue(ratio * newUsableWidth);
2693
+ trackRef.current?.measure((_x, _y, _w, _h, pageX) => {
2694
+ if (pageX != null) trackPageX.current = pageX;
2695
+ });
2696
+ },
2697
+ ...panResponder.panHandlers
2424
2698
  },
2425
- children
2426
- );
2699
+ /* @__PURE__ */ React13.createElement(View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React13.createElement(View, { key: i, style: [styles.segment, { backgroundColor: srgbToHex(color.srgb) }] }))),
2700
+ /* @__PURE__ */ React13.createElement(Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2701
+ ), warning && /* @__PURE__ */ React13.createElement(Text, { style: styles.warning }, warning));
2427
2702
  }
2428
2703
  function getAppShellStyles(tokens) {
2429
2704
  return StyleSheet.create({
@@ -2442,11 +2717,11 @@ function getAppShellStyles(tokens) {
2442
2717
  });
2443
2718
  }
2444
2719
 
2445
- // src/AppShell/AppShell.tsx
2720
+ // src/composites/layout/AppShell/AppShell.tsx
2446
2721
  function AppShell({ sidebar, children }) {
2447
2722
  const tokens = useTokens();
2448
- const styles = React11.useMemo(() => getAppShellStyles(tokens), [tokens]);
2449
- return /* @__PURE__ */ React11.createElement(View, { style: styles.container }, sidebar, /* @__PURE__ */ React11.createElement(View, { style: styles.main }, children));
2723
+ const styles = React13.useMemo(() => getAppShellStyles(tokens), [tokens]);
2724
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, sidebar, /* @__PURE__ */ React13.createElement(View, { style: styles.main }, children));
2450
2725
  }
2451
2726
  function getSidebarStyles({ tokens, width, bordered }) {
2452
2727
  const borderColor = srgbToHex(tokens.border.srgb);
@@ -2475,7 +2750,7 @@ function getSidebarStyles({ tokens, width, bordered }) {
2475
2750
  });
2476
2751
  }
2477
2752
 
2478
- // src/Sidebar/Sidebar.tsx
2753
+ // src/composites/layout/Sidebar/Sidebar.tsx
2479
2754
  function Sidebar({
2480
2755
  children,
2481
2756
  header,
@@ -2484,11 +2759,11 @@ function Sidebar({
2484
2759
  bordered = true
2485
2760
  }) {
2486
2761
  const tokens = useTokens();
2487
- const styles = React11.useMemo(
2762
+ const styles = React13.useMemo(
2488
2763
  () => getSidebarStyles({ tokens, width, bordered }),
2489
2764
  [tokens, width, bordered]
2490
2765
  );
2491
- return /* @__PURE__ */ React11.createElement(View, { style: styles.container }, header && /* @__PURE__ */ React11.createElement(View, { style: styles.header }, header), /* @__PURE__ */ React11.createElement(ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React11.createElement(View, { style: styles.footer }, footer));
2766
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, header && /* @__PURE__ */ React13.createElement(View, { style: styles.header }, header), /* @__PURE__ */ React13.createElement(ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React13.createElement(View, { style: styles.footer }, footer));
2492
2767
  }
2493
2768
  function getNavbarStyles({ tokens, height, bordered }) {
2494
2769
  const borderColor = srgbToHex(tokens.border.srgb);
@@ -2517,7 +2792,7 @@ function getNavbarStyles({ tokens, height, bordered }) {
2517
2792
  });
2518
2793
  }
2519
2794
 
2520
- // src/Navbar/Navbar.tsx
2795
+ // src/composites/layout/Navbar/Navbar.tsx
2521
2796
  function Navbar({
2522
2797
  children,
2523
2798
  left,
@@ -2526,19 +2801,21 @@ function Navbar({
2526
2801
  bordered = true
2527
2802
  }) {
2528
2803
  const tokens = useTokens();
2529
- const styles = React11.useMemo(
2804
+ const styles = React13.useMemo(
2530
2805
  () => getNavbarStyles({ tokens, height, bordered }),
2531
2806
  [tokens, height, bordered]
2532
2807
  );
2533
- return /* @__PURE__ */ React11.createElement(View, { style: styles.container }, children ? children : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(View, { style: styles.left }, left), /* @__PURE__ */ React11.createElement(View, { style: styles.right }, right)));
2808
+ return /* @__PURE__ */ React13.createElement(View, { style: styles.container }, children ? children : /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(View, { style: styles.left }, left), /* @__PURE__ */ React13.createElement(View, { style: styles.right }, right)));
2534
2809
  }
2535
2810
 
2536
2811
  // src/registry/registry.ts
2537
2812
  var CATEGORIES = [
2813
+ { id: "primitives", name: "Design Primitives", description: "Core building blocks for theme-aware layouts and typography" },
2538
2814
  { id: "actions", name: "Actions", description: "Interactive elements that trigger actions" },
2539
2815
  { id: "form-controls", name: "Form Controls", description: "Input elements for user data entry" },
2540
- { id: "range-inputs", name: "Range Inputs", description: "Slider controls for numeric values" },
2541
- { id: "layout", name: "Layout", description: "Structural and container components" }
2816
+ { id: "range-inputs", name: "Range Inputs", description: "Slider controls for numeric and continuous values" },
2817
+ { id: "layout", name: "Layout", description: "Structural and container components" },
2818
+ { id: "overlays", name: "Overlays", description: "Floating and portal-based UI elements" }
2542
2819
  ];
2543
2820
  var COMPONENTS = [
2544
2821
  {
@@ -2551,13 +2828,17 @@ var COMPONENTS = [
2551
2828
  variants: [
2552
2829
  { id: "primary-md", label: "Primary", props: { variant: "primary", size: "md" } },
2553
2830
  { id: "secondary-md", label: "Secondary", props: { variant: "secondary", size: "md" } },
2554
- { id: "ghost-md", label: "Ghost", props: { variant: "ghost", size: "md" } },
2555
- { id: "outline-md", label: "Outline", props: { variant: "outline", size: "md" } },
2831
+ { id: "tertiary-md", label: "Tertiary", props: { variant: "tertiary", size: "md" } },
2556
2832
  { id: "primary-sm", label: "Primary Small", props: { variant: "primary", size: "sm" } },
2557
2833
  { id: "primary-lg", label: "Primary Large", props: { variant: "primary", size: "lg" } },
2834
+ { id: "accent-primary", label: "Accent Primary", props: { variant: "primary", size: "md", semantic: "accent" } },
2835
+ { id: "accent-secondary", label: "Accent Secondary", props: { variant: "secondary", size: "md", semantic: "accent" } },
2836
+ { id: "success-primary", label: "Success Primary", props: { variant: "primary", size: "md", semantic: "success" } },
2837
+ { id: "error-primary", label: "Error Primary", props: { variant: "primary", size: "md", semantic: "error" } },
2838
+ { id: "warning-primary", label: "Warning Primary", props: { variant: "primary", size: "md", semantic: "warning" } },
2558
2839
  { id: "icon-left", label: "Icon Left", props: { variant: "primary", size: "md", icon: "add" } },
2559
2840
  { id: "icon-right", label: "Icon Right", props: { variant: "primary", size: "md", icon: "arrow_forward", iconPosition: "right" } },
2560
- { id: "icon-only", label: "Icon Only", props: { variant: "ghost", size: "md", icon: "settings" } }
2841
+ { id: "icon-only", label: "Icon Only", props: { variant: "tertiary", size: "md", icon: "settings" } }
2561
2842
  ],
2562
2843
  editableProps: [
2563
2844
  {
@@ -2567,11 +2848,23 @@ var COMPONENTS = [
2567
2848
  options: [
2568
2849
  { label: "Primary", value: "primary" },
2569
2850
  { label: "Secondary", value: "secondary" },
2570
- { label: "Ghost", value: "ghost" },
2571
- { label: "Outline", value: "outline" }
2851
+ { label: "Tertiary", value: "tertiary" }
2572
2852
  ],
2573
2853
  defaultValue: "primary"
2574
2854
  },
2855
+ {
2856
+ name: "semantic",
2857
+ label: "Semantic",
2858
+ control: "select",
2859
+ options: [
2860
+ { label: "Neutral", value: "neutral" },
2861
+ { label: "Accent", value: "accent" },
2862
+ { label: "Success", value: "success" },
2863
+ { label: "Warning", value: "warning" },
2864
+ { label: "Error", value: "error" }
2865
+ ],
2866
+ defaultValue: "neutral"
2867
+ },
2575
2868
  {
2576
2869
  name: "size",
2577
2870
  label: "Size",
@@ -2919,6 +3212,221 @@ var COMPONENTS = [
2919
3212
  defaultValue: false
2920
3213
  }
2921
3214
  ]
3215
+ },
3216
+ // ── Design Primitives ──
3217
+ {
3218
+ id: "text",
3219
+ name: "Text",
3220
+ importName: "Text",
3221
+ categoryId: "primitives",
3222
+ description: "Typography primitive with semantic size, weight, color, font, and lineHeight",
3223
+ hasChildren: true,
3224
+ variants: [
3225
+ { id: "default", label: "Default", props: {} },
3226
+ { id: "heading", label: "Heading", props: { size: "xl", weight: "bold" } },
3227
+ { id: "subheading", label: "Subheading", props: { size: "lg", weight: "semibold" } },
3228
+ { id: "body", label: "Body", props: { size: "base" } },
3229
+ { id: "caption", label: "Caption", props: { size: "sm", color: "secondary" } },
3230
+ { id: "accent", label: "Accent", props: { color: "accent", weight: "medium" } },
3231
+ { id: "mono", label: "Monospace", props: { font: "mono", size: "sm" } }
3232
+ ],
3233
+ editableProps: [
3234
+ {
3235
+ name: "size",
3236
+ label: "Size",
3237
+ control: "select",
3238
+ options: [
3239
+ { label: "Extra Small", value: "xs" },
3240
+ { label: "Small", value: "sm" },
3241
+ { label: "Base", value: "base" },
3242
+ { label: "Medium", value: "md" },
3243
+ { label: "Large", value: "lg" },
3244
+ { label: "Extra Large", value: "xl" },
3245
+ { label: "XXL", value: "xxl" }
3246
+ ],
3247
+ defaultValue: "base"
3248
+ },
3249
+ {
3250
+ name: "weight",
3251
+ label: "Weight",
3252
+ control: "select",
3253
+ options: [
3254
+ { label: "Regular", value: "regular" },
3255
+ { label: "Medium", value: "medium" },
3256
+ { label: "Semibold", value: "semibold" },
3257
+ { label: "Bold", value: "bold" }
3258
+ ],
3259
+ defaultValue: "regular"
3260
+ },
3261
+ {
3262
+ name: "color",
3263
+ label: "Color",
3264
+ control: "select",
3265
+ options: [
3266
+ { label: "Primary", value: "primary" },
3267
+ { label: "Secondary", value: "secondary" },
3268
+ { label: "Tertiary", value: "tertiary" },
3269
+ { label: "Disabled", value: "disabled" },
3270
+ { label: "Accent", value: "accent" },
3271
+ { label: "Success", value: "success" },
3272
+ { label: "Warning", value: "warning" },
3273
+ { label: "Error", value: "error" }
3274
+ ],
3275
+ defaultValue: "primary"
3276
+ },
3277
+ {
3278
+ name: "font",
3279
+ label: "Font",
3280
+ control: "select",
3281
+ options: [
3282
+ { label: "Default", value: "default" },
3283
+ { label: "Display", value: "display" },
3284
+ { label: "Mono", value: "mono" }
3285
+ ],
3286
+ defaultValue: "default"
3287
+ }
3288
+ ]
3289
+ },
3290
+ {
3291
+ id: "icon",
3292
+ name: "Icon",
3293
+ importName: "Icon",
3294
+ categoryId: "primitives",
3295
+ description: "Material Symbols icon with size, fill, and color",
3296
+ hasChildren: false,
3297
+ variants: [
3298
+ { id: "home", label: "Home", props: { name: "home" } },
3299
+ { id: "settings", label: "Settings", props: { name: "settings" } },
3300
+ { id: "check", label: "Check", props: { name: "check" } },
3301
+ { id: "add", label: "Add", props: { name: "add" } },
3302
+ { id: "delete", label: "Delete", props: { name: "delete" } },
3303
+ { id: "search", label: "Search", props: { name: "search" } },
3304
+ { id: "filled", label: "Filled Icon", props: { name: "favorite", fill: 1 } },
3305
+ { id: "large", label: "Large Icon", props: { name: "star", size: 32 } }
3306
+ ],
3307
+ editableProps: [
3308
+ {
3309
+ name: "name",
3310
+ label: "Icon Name",
3311
+ control: "text",
3312
+ defaultValue: "home"
3313
+ },
3314
+ {
3315
+ name: "size",
3316
+ label: "Size",
3317
+ control: "number",
3318
+ defaultValue: 24
3319
+ },
3320
+ {
3321
+ name: "fill",
3322
+ label: "Fill",
3323
+ control: "select",
3324
+ options: [
3325
+ { label: "Outlined", value: 0 },
3326
+ { label: "Filled", value: 1 }
3327
+ ],
3328
+ defaultValue: 0
3329
+ }
3330
+ ]
3331
+ },
3332
+ {
3333
+ id: "wrapper",
3334
+ name: "Wrapper",
3335
+ importName: "Wrapper",
3336
+ categoryId: "primitives",
3337
+ description: "Lightweight layout container with direction, spacing, and alignment (no theming)",
3338
+ hasChildren: true,
3339
+ variants: [
3340
+ { id: "vertical", label: "Vertical Stack", props: { direction: "vertical", gap: "md" } },
3341
+ { id: "horizontal", label: "Horizontal Row", props: { direction: "horizontal", gap: "md", align: "center" } },
3342
+ { id: "padded", label: "Padded", props: { padding: "lg", gap: "md" } },
3343
+ { id: "centered", label: "Centered", props: { align: "center", justify: "center", padding: "xl" } }
3344
+ ],
3345
+ editableProps: [
3346
+ {
3347
+ name: "direction",
3348
+ label: "Direction",
3349
+ control: "select",
3350
+ options: [
3351
+ { label: "Vertical", value: "vertical" },
3352
+ { label: "Horizontal", value: "horizontal" }
3353
+ ],
3354
+ defaultValue: "vertical"
3355
+ },
3356
+ {
3357
+ name: "gap",
3358
+ label: "Gap",
3359
+ control: "select",
3360
+ options: [
3361
+ { label: "None", value: "" },
3362
+ { label: "Small", value: "sm" },
3363
+ { label: "Medium", value: "md" },
3364
+ { label: "Large", value: "lg" }
3365
+ ],
3366
+ defaultValue: ""
3367
+ },
3368
+ {
3369
+ name: "padding",
3370
+ label: "Padding",
3371
+ control: "select",
3372
+ options: [
3373
+ { label: "None", value: "" },
3374
+ { label: "Small", value: "sm" },
3375
+ { label: "Medium", value: "md" },
3376
+ { label: "Large", value: "lg" }
3377
+ ],
3378
+ defaultValue: ""
3379
+ },
3380
+ {
3381
+ name: "align",
3382
+ label: "Align",
3383
+ control: "select",
3384
+ options: [
3385
+ { label: "Start", value: "start" },
3386
+ { label: "Center", value: "center" },
3387
+ { label: "End", value: "end" }
3388
+ ],
3389
+ defaultValue: "start"
3390
+ },
3391
+ {
3392
+ name: "justify",
3393
+ label: "Justify",
3394
+ control: "select",
3395
+ options: [
3396
+ { label: "Start", value: "start" },
3397
+ { label: "Center", value: "center" },
3398
+ { label: "End", value: "end" },
3399
+ { label: "Space Between", value: "space-between" }
3400
+ ],
3401
+ defaultValue: "start"
3402
+ }
3403
+ ]
3404
+ },
3405
+ // ── Range Inputs (Addition: ColorScaleSlider) ──
3406
+ {
3407
+ id: "color-scale-slider",
3408
+ name: "ColorScaleSlider",
3409
+ importName: "ColorScaleSlider",
3410
+ categoryId: "range-inputs",
3411
+ description: "Interactive palette preview slider with color segments",
3412
+ hasChildren: false,
3413
+ variants: [
3414
+ { id: "default", label: "Default", props: { label: "Key Color" } }
3415
+ ],
3416
+ editableProps: [
3417
+ {
3418
+ name: "label",
3419
+ label: "Label",
3420
+ control: "text",
3421
+ defaultValue: "Key Color"
3422
+ },
3423
+ {
3424
+ name: "disabled",
3425
+ label: "Disabled",
3426
+ control: "toggle",
3427
+ defaultValue: false
3428
+ }
3429
+ ]
2922
3430
  }
2923
3431
  ];
2924
3432
  function getComponent(id) {
@@ -3087,6 +3595,6 @@ var SYSTEM_FONTS = [
3087
3595
  }
3088
3596
  ];
3089
3597
 
3090
- export { AppShell, Button, CATEGORIES, COMPONENTS, Card, ColorScaleSlider, DEFAULT_THEME_CONFIG, Frame, GOOGLE_FONTS, HueSlider, Icon, Navbar, NewtoneProvider, Popover, SYSTEM_FONTS, Select, Sidebar, Slider, Text11 as Text, TextInput, Toggle, Wrapper, buildGoogleFontsUrl, computeTokens, generateComponentCode, getCategory, getComponent, getComponentsByCategory, isOptionGroup, useFocusVisible, useFrameContext, useNewtoneTheme, usePopover, useTokens };
3598
+ export { ACCENT_DEFAULTS, AppShell, Button, CATEGORIES, COMPONENTS, Card, ColorScaleSlider, DEFAULT_THEME_CONFIG, ERROR_DEFAULTS, Frame, GOOGLE_FONTS, HueSlider, Icon, NEUTRAL_DEFAULTS, Navbar, NewtoneProvider, Popover, SUCCESS_DEFAULTS, SYSTEM_FONTS, Select, Sidebar, Slider, Text2 as Text, TextInput, Toggle, WARNING_DEFAULTS, Wrapper, buildGoogleFontsUrl, computeTokens, generateComponentCode, getCategory, getComponent, getComponentsByCategory, isOptionGroup, useFocusVisible, useFrameContext, useNewtoneTheme, usePopover, useTokens };
3091
3599
  //# sourceMappingURL=index.js.map
3092
3600
  //# sourceMappingURL=index.js.map