@newtonedev/components 0.1.7 → 0.1.9

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 (94) hide show
  1. package/dist/composites/actions/Button/Button.d.ts.map +1 -1
  2. package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -1
  3. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -1
  4. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -1
  5. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -1
  6. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -1
  7. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -1
  8. package/dist/fonts/GoogleFontLoader.d.ts +5 -4
  9. package/dist/fonts/GoogleFontLoader.d.ts.map +1 -1
  10. package/dist/fonts/SelfHostedFontLoader.d.ts +14 -0
  11. package/dist/fonts/SelfHostedFontLoader.d.ts.map +1 -0
  12. package/dist/fonts/buildGoogleFontsUrl.d.ts +1 -16
  13. package/dist/fonts/buildGoogleFontsUrl.d.ts.map +1 -1
  14. package/dist/fonts/measureFont.d.ts +18 -0
  15. package/dist/fonts/measureFont.d.ts.map +1 -0
  16. package/dist/fonts/reportQueue.d.ts +7 -0
  17. package/dist/fonts/reportQueue.d.ts.map +1 -0
  18. package/dist/fonts/useLocalCalibration.d.ts +19 -0
  19. package/dist/fonts/useLocalCalibration.d.ts.map +1 -0
  20. package/dist/fonts/useTypographyCalibrations.d.ts +11 -0
  21. package/dist/fonts/useTypographyCalibrations.d.ts.map +1 -0
  22. package/dist/index.cjs +629 -422
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +7 -6
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +568 -376
  27. package/dist/index.js.map +1 -1
  28. package/dist/primitives/Icon/Icon.types.d.ts +1 -1
  29. package/dist/primitives/Icon/Icon.types.d.ts.map +1 -1
  30. package/dist/primitives/Text/Text.d.ts +33 -8
  31. package/dist/primitives/Text/Text.d.ts.map +1 -1
  32. package/dist/primitives/Text/Text.spans.d.ts +22 -0
  33. package/dist/primitives/Text/Text.spans.d.ts.map +1 -0
  34. package/dist/primitives/Text/Text.types.d.ts +77 -27
  35. package/dist/primitives/Text/Text.types.d.ts.map +1 -1
  36. package/dist/primitives/Text/index.d.ts +23 -2
  37. package/dist/primitives/Text/index.d.ts.map +1 -1
  38. package/dist/primitives/index.d.ts +1 -1
  39. package/dist/primitives/index.d.ts.map +1 -1
  40. package/dist/registry/codegen.d.ts.map +1 -1
  41. package/dist/registry/registry.d.ts.map +1 -1
  42. package/dist/registry/types.d.ts +2 -0
  43. package/dist/registry/types.d.ts.map +1 -1
  44. package/dist/theme/NewtoneProvider.d.ts +9 -1
  45. package/dist/theme/NewtoneProvider.d.ts.map +1 -1
  46. package/dist/theme/defaults.d.ts +1 -0
  47. package/dist/theme/defaults.d.ts.map +1 -1
  48. package/dist/theme/types.d.ts +48 -32
  49. package/dist/theme/types.d.ts.map +1 -1
  50. package/dist/theme/useBreakpoint.d.ts +9 -0
  51. package/dist/theme/useBreakpoint.d.ts.map +1 -0
  52. package/dist/tokens/computeTokens.d.ts +9 -22
  53. package/dist/tokens/computeTokens.d.ts.map +1 -1
  54. package/dist/tokens/types.d.ts +40 -22
  55. package/dist/tokens/types.d.ts.map +1 -1
  56. package/package.json +2 -1
  57. package/src/composites/actions/Button/Button.styles.ts +3 -3
  58. package/src/composites/actions/Button/Button.tsx +3 -2
  59. package/src/composites/form-controls/Select/Select.styles.ts +8 -8
  60. package/src/composites/form-controls/Select/Select.tsx +1 -1
  61. package/src/composites/form-controls/Select/SelectOption.tsx +3 -3
  62. package/src/composites/form-controls/TextInput/TextInput.styles.ts +5 -5
  63. package/src/composites/form-controls/Toggle/Toggle.styles.ts +3 -3
  64. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.ts +6 -6
  65. package/src/composites/range-inputs/HueSlider/HueSlider.styles.ts +9 -9
  66. package/src/composites/range-inputs/Slider/Slider.styles.ts +9 -9
  67. package/src/fonts/GoogleFontLoader.tsx +25 -10
  68. package/src/fonts/SelfHostedFontLoader.tsx +44 -0
  69. package/src/fonts/buildGoogleFontsUrl.ts +2 -31
  70. package/src/fonts/measureFont.ts +42 -0
  71. package/src/fonts/reportQueue.ts +54 -0
  72. package/src/fonts/useLocalCalibration.ts +97 -0
  73. package/src/fonts/useTypographyCalibrations.ts +15 -0
  74. package/src/index.ts +16 -7
  75. package/src/primitives/Frame/Frame.tsx +3 -3
  76. package/src/primitives/Icon/Icon.tsx +1 -1
  77. package/src/primitives/Icon/Icon.types.ts +1 -1
  78. package/src/primitives/Text/Text.spans.ts +57 -0
  79. package/src/primitives/Text/Text.tsx +208 -53
  80. package/src/primitives/Text/Text.types.ts +83 -27
  81. package/src/primitives/Text/index.ts +27 -3
  82. package/src/primitives/index.ts +3 -2
  83. package/src/registry/codegen.ts +1 -0
  84. package/src/registry/registry.ts +55 -53
  85. package/src/registry/types.ts +2 -0
  86. package/src/theme/NewtoneProvider.tsx +18 -2
  87. package/src/theme/defaults.ts +8 -28
  88. package/src/theme/types.ts +63 -33
  89. package/src/theme/useBreakpoint.ts +14 -0
  90. package/src/tokens/computeTokens.ts +23 -19
  91. package/src/tokens/types.ts +10 -24
  92. package/dist/fonts/googleFonts.d.ts +0 -20
  93. package/dist/fonts/googleFonts.d.ts.map +0 -1
  94. package/src/fonts/googleFonts.ts +0 -87
package/dist/index.cjs CHANGED
@@ -1,12 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var React13 = require('react');
3
+ var React14 = require('react');
4
4
  var newtone = require('newtone');
5
+ var fonts = require('@newtonedev/fonts');
5
6
  var reactNative = require('react-native');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
9
- var React13__default = /*#__PURE__*/_interopDefault(React13);
10
+ var React14__default = /*#__PURE__*/_interopDefault(React14);
10
11
 
11
12
  // src/theme/NewtoneProvider.tsx
12
13
  var DEFAULT_THEME_CONFIG = {
@@ -60,40 +61,10 @@ var DEFAULT_THEME_CONFIG = {
60
61
  pill: 999
61
62
  },
62
63
  typography: {
63
- fonts: {
64
- mono: {
65
- type: "system",
66
- family: "ui-monospace",
67
- fallback: "SFMono-Regular, Menlo, Monaco, Consolas, monospace"
68
- },
69
- display: {
70
- type: "system",
71
- family: "system-ui",
72
- fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
73
- },
74
- default: {
75
- type: "system",
76
- family: "system-ui",
77
- fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
78
- }
79
- },
80
- scale: {
81
- xs: 10,
82
- // 16 / 1.25^2
83
- sm: 13,
84
- // 16 / 1.25
85
- base: 16,
86
- md: 20,
87
- // 16 * 1.25
88
- lg: 25,
89
- // 16 * 1.25^2
90
- xl: 31,
91
- // 16 * 1.25^3
92
- xxl: 39
93
- // 16 * 1.25^4
94
- },
95
- lineHeight: { tight: 1.25, normal: 1.5, relaxed: 1.75 },
96
- fontWeight: { regular: 400, medium: 500, semibold: 600, bold: 700 }
64
+ fonts: fonts.DEFAULT_FONT_SLOTS,
65
+ fontSizes: fonts.DEFAULT_FONT_SIZES,
66
+ lineHeights: fonts.DEFAULT_LINE_HEIGHTS,
67
+ roles: fonts.DEFAULT_ROLE_SCALES
97
68
  },
98
69
  icons: {
99
70
  variant: "rounded",
@@ -105,26 +76,12 @@ var DEFAULT_THEME_CONFIG = {
105
76
  }
106
77
  };
107
78
 
108
- // src/fonts/buildGoogleFontsUrl.ts
109
- function buildGoogleFontsUrl(fonts) {
110
- const googleFonts = [fonts.mono, fonts.display, fonts.default].filter(
111
- (f) => f.type === "google"
112
- );
113
- if (googleFonts.length === 0) return null;
114
- const unique = [...new Map(googleFonts.map((f) => [f.family, f])).values()];
115
- const families = unique.map((f) => {
116
- const encoded = f.family.replace(/ /g, "+");
117
- return `family=${encoded}:wght@400;500;600;700`;
118
- });
119
- return `https://fonts.googleapis.com/css2?${families.join("&")}&display=swap`;
120
- }
121
-
122
79
  // src/fonts/GoogleFontLoader.tsx
123
- function GoogleFontLoader({ fonts }) {
124
- const linkRef = React13.useRef(null);
125
- React13.useEffect(() => {
80
+ function GoogleFontLoader({ fonts: fonts$1 }) {
81
+ const linkRef = React14.useRef(null);
82
+ React14.useEffect(() => {
126
83
  if (typeof document === "undefined") return;
127
- const url = buildGoogleFontsUrl(fonts);
84
+ const url = fonts.buildGoogleFontsUrl(fonts$1);
128
85
  if (linkRef.current) {
129
86
  linkRef.current.remove();
130
87
  linkRef.current = null;
@@ -144,18 +101,55 @@ function GoogleFontLoader({ fonts }) {
144
101
  }
145
102
  };
146
103
  }, [
147
- fonts.mono.family,
148
- fonts.mono.type,
149
- fonts.display.family,
150
- fonts.display.type,
151
- fonts.default.family,
152
- fonts.default.type
104
+ fonts$1.main.config.family,
105
+ fonts$1.main.config.type,
106
+ fonts$1.main.weights.regular,
107
+ fonts$1.main.weights.medium,
108
+ fonts$1.main.weights.bold,
109
+ fonts$1.display.config.family,
110
+ fonts$1.display.config.type,
111
+ fonts$1.display.weights.regular,
112
+ fonts$1.display.weights.medium,
113
+ fonts$1.display.weights.bold,
114
+ fonts$1.mono.config.family,
115
+ fonts$1.mono.config.type,
116
+ fonts$1.mono.weights.regular,
117
+ fonts$1.mono.weights.medium,
118
+ fonts$1.mono.weights.bold,
119
+ fonts$1.currency.config.family,
120
+ fonts$1.currency.config.type,
121
+ fonts$1.currency.weights.regular,
122
+ fonts$1.currency.weights.medium,
123
+ fonts$1.currency.weights.bold
153
124
  ]);
154
125
  return null;
155
126
  }
127
+ function SelfHostedFontLoader({ fontFaceCss }) {
128
+ const styleRef = React14.useRef(null);
129
+ React14.useEffect(() => {
130
+ if (typeof document === "undefined") return;
131
+ if (styleRef.current) {
132
+ styleRef.current.remove();
133
+ styleRef.current = null;
134
+ }
135
+ if (!fontFaceCss) return;
136
+ const style = document.createElement("style");
137
+ style.setAttribute("data-newtone-fonts", "self-hosted");
138
+ style.textContent = fontFaceCss;
139
+ document.head.appendChild(style);
140
+ styleRef.current = style;
141
+ return () => {
142
+ if (styleRef.current) {
143
+ styleRef.current.remove();
144
+ styleRef.current = null;
145
+ }
146
+ };
147
+ }, [fontFaceCss]);
148
+ return null;
149
+ }
156
150
  function IconFontLoader({ icons }) {
157
- const linkRef = React13.useRef(null);
158
- React13.useEffect(() => {
151
+ const linkRef = React14.useRef(null);
152
+ React14.useEffect(() => {
159
153
  if (typeof document === "undefined") return;
160
154
  const variantName = icons.variant.charAt(0).toUpperCase() + icons.variant.slice(1);
161
155
  const family = `Material+Symbols+${variantName}`;
@@ -182,33 +176,36 @@ function IconFontLoader({ icons }) {
182
176
  }
183
177
 
184
178
  // src/theme/NewtoneProvider.tsx
185
- var ThemeContext = React13.createContext(null);
179
+ var ThemeContext = React14.createContext(null);
186
180
  function NewtoneProvider({
187
181
  config = DEFAULT_THEME_CONFIG,
188
182
  initialMode = "light",
189
- children
183
+ children,
184
+ reportingEndpoint,
185
+ fontFaceCss
190
186
  }) {
191
- const [mode, setMode] = React13.useState(initialMode);
192
- const value = React13.useMemo(
187
+ const [mode, setMode] = React14.useState(initialMode);
188
+ const value = React14.useMemo(
193
189
  () => ({
194
190
  config,
195
191
  mode,
196
- setMode
192
+ setMode,
193
+ reportingEndpoint
197
194
  }),
198
- [config, mode]
195
+ [config, mode, reportingEndpoint]
199
196
  );
200
- return /* @__PURE__ */ React13__default.default.createElement(ThemeContext.Provider, { value }, /* @__PURE__ */ React13__default.default.createElement(GoogleFontLoader, { fonts: config.typography.fonts }), /* @__PURE__ */ React13__default.default.createElement(IconFontLoader, { icons: config.icons }), children);
197
+ return /* @__PURE__ */ React14__default.default.createElement(ThemeContext.Provider, { value }, fontFaceCss ? /* @__PURE__ */ React14__default.default.createElement(SelfHostedFontLoader, { fontFaceCss }) : /* @__PURE__ */ React14__default.default.createElement(GoogleFontLoader, { fonts: config.typography.fonts }), /* @__PURE__ */ React14__default.default.createElement(IconFontLoader, { icons: config.icons }), children);
201
198
  }
202
199
  function useNewtoneTheme() {
203
- const context = React13.useContext(ThemeContext);
200
+ const context = React14.useContext(ThemeContext);
204
201
  if (!context) {
205
202
  throw new Error("useNewtoneTheme must be used within NewtoneProvider");
206
203
  }
207
204
  return context;
208
205
  }
209
- var FrameContext = React13.createContext(null);
206
+ var FrameContext = React14.createContext(null);
210
207
  function useFrameContext() {
211
- return React13.useContext(FrameContext);
208
+ return React14.useContext(FrameContext);
212
209
  }
213
210
  var NEUTRAL_DEFAULTS = {
214
211
  light: {
@@ -280,10 +277,6 @@ var ERROR_DEFAULTS = {
280
277
  border: { enabled: 0.08, focused: 0.16, filled: 0.24 }
281
278
  }
282
279
  };
283
- function fontConfigToFamily(font) {
284
- const family = font.family.includes(" ") ? `"${font.family}"` : font.family;
285
- return `${family}, ${font.fallback}`;
286
- }
287
280
  var clamp = (n) => Math.max(0, Math.min(1, n));
288
281
  function computePaletteTokens(palette, defaults, mode, elevation, dynamicRange, elevationDelta, effectiveTextMode, autoAccentNv, neutralTextPrimary, neutralBgElevated) {
289
282
  const modeDefaults = defaults[mode];
@@ -538,13 +531,25 @@ function computeTokens(config, mode, elevation, spacing, radius, typography, ico
538
531
  radius,
539
532
  typography: {
540
533
  fonts: {
541
- mono: fontConfigToFamily(typography.fonts.mono),
542
- display: fontConfigToFamily(typography.fonts.display),
543
- default: fontConfigToFamily(typography.fonts.default)
534
+ main: {
535
+ family: fonts.fontConfigToFamily(typography.fonts.main.config),
536
+ weights: typography.fonts.main.weights
537
+ },
538
+ display: {
539
+ family: fonts.fontConfigToFamily(typography.fonts.display.config),
540
+ weights: typography.fonts.display.weights
541
+ },
542
+ mono: {
543
+ family: fonts.fontConfigToFamily(typography.fonts.mono.config),
544
+ weights: typography.fonts.mono.weights
545
+ },
546
+ currency: {
547
+ family: fonts.fontConfigToFamily(typography.fonts.currency.config),
548
+ weights: typography.fonts.currency.weights
549
+ }
544
550
  },
545
- size: typography.scale,
546
- lineHeight: typography.lineHeight,
547
- weight: typography.fontWeight
551
+ fontSizes: typography.fontSizes,
552
+ lineHeights: typography.lineHeights
548
553
  },
549
554
  icons: {
550
555
  variant: icons.variant,
@@ -560,7 +565,7 @@ function useTokens(elevation) {
560
565
  const frameCtx = useFrameContext();
561
566
  const resolvedElevation = elevation ?? frameCtx?.elevation ?? 1;
562
567
  const canReuse = frameCtx !== null && elevation === void 0 && frameCtx.elevation === resolvedElevation;
563
- return React13.useMemo(() => {
568
+ return React14.useMemo(() => {
564
569
  if (canReuse) {
565
570
  return { ...frameCtx.tokens, elevation: resolvedElevation };
566
571
  }
@@ -659,7 +664,7 @@ function getSizeConfig(size, tokens) {
659
664
  padding: 8,
660
665
  gap: tokens.spacing["08"],
661
666
  borderRadius: 8,
662
- textSize: "base",
667
+ textSize: "md",
663
668
  // 16px
664
669
  iconSize: 24
665
670
  },
@@ -667,7 +672,7 @@ function getSizeConfig(size, tokens) {
667
672
  padding: 12,
668
673
  gap: tokens.spacing["08"],
669
674
  borderRadius: 12,
670
- textSize: "base",
675
+ textSize: "md",
671
676
  // 16px
672
677
  iconSize: 24
673
678
  },
@@ -675,7 +680,7 @@ function getSizeConfig(size, tokens) {
675
680
  padding: 16,
676
681
  gap: tokens.spacing["08"],
677
682
  borderRadius: 16,
678
- textSize: "base",
683
+ textSize: "md",
679
684
  // 16px
680
685
  iconSize: 24
681
686
  }
@@ -789,8 +794,8 @@ function Icon({
789
794
  ref
790
795
  }) {
791
796
  const tokens = useTokens();
792
- const iconStyle = React13.useMemo(() => {
793
- const fontSize = size ?? tokens.typography.size.base;
797
+ const iconStyle = React14.useMemo(() => {
798
+ const fontSize = size ?? tokens.typography.fontSizes["05"];
794
799
  const getOpticalSize = (size2) => {
795
800
  if (size2 <= 22) return 20;
796
801
  if (size2 <= 32) return 24;
@@ -819,7 +824,7 @@ function Icon({
819
824
  ...style
820
825
  };
821
826
  }, [tokens, size, opticalSize, fill, color, style]);
822
- return /* @__PURE__ */ React13__default.default.createElement(
827
+ return /* @__PURE__ */ React14__default.default.createElement(
823
828
  reactNative.Text,
824
829
  {
825
830
  ref,
@@ -832,6 +837,118 @@ function Icon({
832
837
  name
833
838
  );
834
839
  }
840
+
841
+ // src/fonts/measureFont.ts
842
+ var REF_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
843
+ async function measureAvgCharWidth(fontFamily, fontWeight, fallback, fontSize = 16) {
844
+ if (typeof document === "undefined") return 0.55;
845
+ try {
846
+ await document.fonts.load(`${fontWeight} ${fontSize}px "${fontFamily}"`);
847
+ const canvas = document.createElement("canvas");
848
+ const ctx = canvas.getContext("2d");
849
+ if (!ctx) return 0.55;
850
+ ctx.font = `${fontWeight} ${fontSize}px "${fontFamily}", ${fallback}`;
851
+ const ratio = ctx.measureText(REF_STRING).width / REF_STRING.length / fontSize;
852
+ return Math.round(ratio * 1e3) / 1e3;
853
+ } catch {
854
+ return 0.55;
855
+ }
856
+ }
857
+
858
+ // src/fonts/useLocalCalibration.ts
859
+ var STORAGE_KEY = "newtone:font-metrics:v1";
860
+ var TTL_MS = 7 * 24 * 60 * 60 * 1e3;
861
+ function readCache() {
862
+ if (typeof localStorage === "undefined") return {};
863
+ try {
864
+ const raw = localStorage.getItem(STORAGE_KEY);
865
+ return raw ? JSON.parse(raw) : {};
866
+ } catch {
867
+ return {};
868
+ }
869
+ }
870
+ function writeCache(cache) {
871
+ if (typeof localStorage === "undefined") return;
872
+ try {
873
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(cache));
874
+ } catch {
875
+ }
876
+ }
877
+ function cacheKey(fontFamily, fontWeight) {
878
+ return `${fontFamily}:${fontWeight}`;
879
+ }
880
+ function useLocalCalibration(fontFamily, fontWeight, fallback, baseCalibration) {
881
+ const key = cacheKey(fontFamily, fontWeight);
882
+ const [ratio, setRatio] = React14.useState(() => {
883
+ const cache = readCache();
884
+ const entry = cache[key];
885
+ if (entry && Date.now() - entry.measuredAt < TTL_MS) {
886
+ return entry.ratio;
887
+ }
888
+ return baseCalibration ?? 0.55;
889
+ });
890
+ React14.useEffect(() => {
891
+ const cache = readCache();
892
+ const entry = cache[key];
893
+ if (entry && Date.now() - entry.measuredAt < TTL_MS) {
894
+ if (entry.ratio !== ratio) setRatio(entry.ratio);
895
+ return;
896
+ }
897
+ let cancelled = false;
898
+ measureAvgCharWidth(fontFamily, fontWeight, fallback).then((measured) => {
899
+ if (cancelled) return;
900
+ const updated = { ...readCache(), [key]: { ratio: measured, measuredAt: Date.now() } };
901
+ writeCache(updated);
902
+ setRatio(measured);
903
+ });
904
+ return () => {
905
+ cancelled = true;
906
+ };
907
+ }, [key, fontFamily, fontWeight, fallback]);
908
+ return ratio;
909
+ }
910
+
911
+ // src/fonts/useTypographyCalibrations.ts
912
+ function useTypographyCalibrations() {
913
+ const { config } = useNewtoneTheme();
914
+ return config.typography.calibrations ?? {};
915
+ }
916
+
917
+ // src/fonts/reportQueue.ts
918
+ var queue = [];
919
+ var flushTimer;
920
+ function flush() {
921
+ if (queue.length === 0) return;
922
+ const byEndpoint = /* @__PURE__ */ new Map();
923
+ for (const item of queue) {
924
+ const group = byEndpoint.get(item.endpoint) ?? [];
925
+ group.push(item.payload);
926
+ byEndpoint.set(item.endpoint, group);
927
+ }
928
+ queue.length = 0;
929
+ for (const [endpoint, observations] of byEndpoint) {
930
+ fetch(endpoint, {
931
+ method: "POST",
932
+ headers: { "Content-Type": "application/json" },
933
+ body: JSON.stringify({ observations }),
934
+ // keepalive: true allows the request to outlive the page
935
+ keepalive: true
936
+ }).catch(() => {
937
+ });
938
+ }
939
+ }
940
+ function enqueueObservation(endpoint, payload) {
941
+ queue.push({ endpoint, payload });
942
+ if (flushTimer !== void 0) clearTimeout(flushTimer);
943
+ flushTimer = setTimeout(flush, 2e3);
944
+ }
945
+ function useBreakpoint() {
946
+ const { width } = reactNative.useWindowDimensions();
947
+ return fonts.getBreakpointForWidth(width);
948
+ }
949
+
950
+ // src/primitives/Text/Text.tsx
951
+ var TextScopeContext = React14.createContext(null);
835
952
  function resolveTextColor(color, tokens) {
836
953
  switch (color) {
837
954
  case "primary":
@@ -852,53 +969,189 @@ function resolveTextColor(color, tokens) {
852
969
  return newtone.srgbToHex(tokens.error.fill.srgb);
853
970
  }
854
971
  }
855
- function Text2({
972
+ var ADAPTIVE_ROLES = /* @__PURE__ */ new Set(["headline", "title", "heading", "subheading"]);
973
+ var ROLE_HEADING_LEVEL = {
974
+ headline: 1,
975
+ title: 2,
976
+ heading: 3
977
+ };
978
+ function extractCharacterCount(node) {
979
+ if (typeof node === "string") return node.length;
980
+ if (typeof node === "number") return String(node).length;
981
+ if (!node) return 0;
982
+ if (Array.isArray(node)) {
983
+ return node.reduce((sum, child) => sum + extractCharacterCount(child), 0);
984
+ }
985
+ if (typeof node === "object" && "props" in node) {
986
+ return extractCharacterCount(node.props?.children);
987
+ }
988
+ return 0;
989
+ }
990
+ function TextBase({
856
991
  children,
857
- size = "base",
858
- weight = "regular",
992
+ scope = "main",
993
+ role = "body",
859
994
  color = "primary",
860
- font = "default",
861
- lineHeight = "normal",
995
+ size: sizeOverride,
996
+ weight: weightOverride,
862
997
  align,
863
998
  numberOfLines,
864
999
  elevation = 1,
865
1000
  style,
866
- // Accessibility
867
- accessibilityRole,
868
- // Testing & platform
1001
+ accessibilityRole: accessibilityRoleOverride,
869
1002
  testID,
870
1003
  nativeID,
871
- ref
1004
+ ref,
1005
+ responsive = false,
1006
+ centerVertically = false,
1007
+ features
872
1008
  }) {
873
1009
  const tokens = useTokens(elevation);
874
- const resolvedStyle = React13.useMemo(() => {
875
- const fontSize = tokens.typography.size[size];
1010
+ const { config, reportingEndpoint } = useNewtoneTheme();
1011
+ const size = sizeOverride ?? "md";
1012
+ const fontSlot = tokens.typography.fonts[scope];
1013
+ const resolvedFontWeight = weightOverride ? fonts.SEMANTIC_WEIGHT_MAP[weightOverride] : config.typography.roleWeights?.[role] ?? fonts.ROLE_DEFAULT_WEIGHTS[role];
1014
+ const breakpoint = useBreakpoint();
1015
+ const baseStep = config.typography.roles[role][size];
1016
+ const bpScale = fonts.BREAKPOINT_ROLE_SCALE[breakpoint][role];
1017
+ const step = bpScale === 1 ? baseStep : fonts.scaleRoleStep(baseStep, bpScale);
1018
+ const calibrations = useTypographyCalibrations();
1019
+ const fontSlotFull = config.typography.fonts[scope];
1020
+ const localRatio = useLocalCalibration(
1021
+ fontSlot.family,
1022
+ fonts.SEMANTIC_WEIGHT_MAP.regular,
1023
+ fontSlotFull.config.fallback,
1024
+ calibrations[fontSlot.family]
1025
+ );
1026
+ const isAdaptive = ADAPTIVE_ROLES.has(role);
1027
+ const [containerWidth, setContainerWidth] = React14.useState(null);
1028
+ const characterCount = React14.useMemo(() => extractCharacterCount(children), [children]);
1029
+ const resolvedStep = React14.useMemo(
1030
+ () => fonts.resolveResponsiveSize(
1031
+ {
1032
+ role,
1033
+ size,
1034
+ responsive: responsive && isAdaptive,
1035
+ fontFamily: fontSlot.family,
1036
+ maxFontSize: step.fontSize,
1037
+ minFontSize: Math.max(8, Math.round(step.fontSize * 0.7))
1038
+ },
1039
+ config.typography.roles,
1040
+ containerWidth != null ? { containerWidth, characterCount } : void 0,
1041
+ { [fontSlot.family]: localRatio }
1042
+ ),
1043
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1044
+ [role, size, responsive, isAdaptive, fontSlot.family, step.fontSize, config.typography.roles, containerWidth, characterCount, localRatio]
1045
+ );
1046
+ React14.useEffect(() => {
1047
+ if (!reportingEndpoint || !responsive || !isAdaptive || containerWidth == null) return;
1048
+ const lineWidths = fonts.estimateLineWidths(characterCount, containerWidth, resolvedStep.fontSize, localRatio);
1049
+ const lastLine = lineWidths[lineWidths.length - 1];
1050
+ enqueueObservation(reportingEndpoint, {
1051
+ fontFamily: fontSlot.family,
1052
+ fontWeight: resolvedFontWeight,
1053
+ role,
1054
+ size,
1055
+ fontSize: resolvedStep.fontSize,
1056
+ containerWidth,
1057
+ characterCount,
1058
+ lineCount: lineWidths.length,
1059
+ lastLineRatio: containerWidth > 0 ? lastLine / containerWidth : 1
1060
+ });
1061
+ }, [reportingEndpoint, resolvedStep.fontSize, containerWidth]);
1062
+ const resolvedStyle = React14.useMemo(() => {
1063
+ const activeStep = responsive && isAdaptive ? resolvedStep : step;
1064
+ const currentMetrics = config.typography.fontMetrics?.[fontSlot.family];
1065
+ const correctedLineHeight = currentMetrics ? Math.round(activeStep.lineHeight * currentMetrics.naturalLineHeightRatio / fonts.REFERENCE_LINE_HEIGHT_RATIO / 4) * 4 : activeStep.lineHeight;
1066
+ const vcOffset = centerVertically && currentMetrics ? Math.round(currentMetrics.verticalCenterOffset * activeStep.fontSize * 2) / 2 : 0;
1067
+ const activeFeatures = features ? currentMetrics?.features ? features.filter((tag) => currentMetrics.features.includes(tag)) : [...features] : [];
1068
+ const featureSettings = activeFeatures.length > 0 ? fonts.buildFontFeatureSettings(activeFeatures) : void 0;
876
1069
  return {
877
- // Font family from the theme (e.g. 'default' → 'Inter', 'mono' → 'JetBrains Mono').
878
- fontFamily: tokens.typography.fonts[font],
879
- fontSize,
880
- // Font weight is stored as a number (e.g. 400, 600) but React Native expects a string.
881
- fontWeight: String(tokens.typography.weight[weight]),
882
- // Convert the theme color from internal sRGB format to a hex string (e.g. '#1a1a1a').
1070
+ fontFamily: fontSlot.family,
1071
+ fontSize: activeStep.fontSize,
1072
+ fontWeight: String(resolvedFontWeight),
883
1073
  color: resolveTextColor(color, tokens),
884
- // Line height = font size × multiplier (e.g. 16px × 1.5 = 24px line height).
885
- lineHeight: fontSize * tokens.typography.lineHeight[lineHeight],
886
- textAlign: align
1074
+ lineHeight: correctedLineHeight,
1075
+ textAlign: align,
1076
+ ...vcOffset !== 0 ? { transform: [{ translateY: vcOffset }] } : {},
1077
+ ...featureSettings ? { fontFeatureSettings: featureSettings } : {}
887
1078
  };
888
- }, [tokens, size, weight, color, font, lineHeight, align]);
889
- return /* @__PURE__ */ React13__default.default.createElement(
1079
+ }, [tokens, fontSlot, step, resolvedStep, responsive, isAdaptive, resolvedFontWeight, color, align, config.typography.fontMetrics, centerVertically, features]);
1080
+ const inferredA11yRole = role === "headline" || role === "title" || role === "heading" ? "header" : void 0;
1081
+ const effectiveA11yRole = accessibilityRoleOverride ?? inferredA11yRole;
1082
+ const ariaLevel = effectiveA11yRole === "header" ? ROLE_HEADING_LEVEL[role] : void 0;
1083
+ const scopeCtx = React14.useMemo(() => ({ weights: fonts.SEMANTIC_WEIGHT_MAP }), []);
1084
+ const textNode = /* @__PURE__ */ React14__default.default.createElement(TextScopeContext.Provider, { value: scopeCtx }, /* @__PURE__ */ React14__default.default.createElement(
890
1085
  reactNative.Text,
891
1086
  {
892
1087
  ref,
893
1088
  testID,
894
1089
  nativeID,
895
- accessibilityRole,
1090
+ accessibilityRole: effectiveA11yRole,
1091
+ "aria-level": ariaLevel,
896
1092
  style: style ? [resolvedStyle, ...Array.isArray(style) ? style : [style]] : resolvedStyle,
897
1093
  numberOfLines
898
1094
  },
899
1095
  children
1096
+ ));
1097
+ if (responsive && isAdaptive) {
1098
+ return /* @__PURE__ */ React14__default.default.createElement(
1099
+ reactNative.View,
1100
+ {
1101
+ onLayout: (e) => {
1102
+ const w = e.nativeEvent.layout.width;
1103
+ if (w > 0) setContainerWidth(w);
1104
+ },
1105
+ style: { width: "100%" }
1106
+ },
1107
+ textNode
1108
+ );
1109
+ }
1110
+ return textNode;
1111
+ }
1112
+ function TextSpan({ children, color, weight, italic, underline, highlight, style }) {
1113
+ const tokens = useTokens(1);
1114
+ const scopeCtx = React14.useContext(TextScopeContext);
1115
+ const spanStyle = React14.useMemo(() => {
1116
+ const s = {};
1117
+ if (color) s.color = resolveTextColor(color, tokens);
1118
+ if (weight && scopeCtx) s.fontWeight = String(scopeCtx.weights[weight]);
1119
+ if (italic) s.fontStyle = "italic";
1120
+ if (underline) s.textDecorationLine = "underline";
1121
+ if (highlight) s.backgroundColor = resolveTextColor(highlight, tokens);
1122
+ return s;
1123
+ }, [tokens, scopeCtx, color, weight, italic, underline, highlight]);
1124
+ return React14__default.default.createElement(
1125
+ reactNative.Text,
1126
+ { style: style ? [spanStyle, ...Array.isArray(style) ? style : [style]] : spanStyle },
1127
+ children
900
1128
  );
901
1129
  }
1130
+ function TextBold(props) {
1131
+ return React14__default.default.createElement(TextSpan, { ...props, weight: "bold" });
1132
+ }
1133
+ function TextMedium(props) {
1134
+ return React14__default.default.createElement(TextSpan, { ...props, weight: "medium" });
1135
+ }
1136
+ function TextItalic(props) {
1137
+ return React14__default.default.createElement(TextSpan, { ...props, italic: true });
1138
+ }
1139
+ function TextUnderline(props) {
1140
+ return React14__default.default.createElement(TextSpan, { ...props, underline: true });
1141
+ }
1142
+ function TextHighlight(props) {
1143
+ return React14__default.default.createElement(TextSpan, props);
1144
+ }
1145
+
1146
+ // src/primitives/Text/index.ts
1147
+ var Text2 = Object.assign(TextBase, {
1148
+ Span: TextSpan,
1149
+ Bold: TextBold,
1150
+ Medium: TextMedium,
1151
+ Italic: TextItalic,
1152
+ Underline: TextUnderline,
1153
+ Highlight: TextHighlight
1154
+ });
902
1155
 
903
1156
  // src/primitives/Frame/Frame.utils.ts
904
1157
  function resolveSpacing(value, tokens) {
@@ -1067,7 +1320,7 @@ function Wrapper({
1067
1320
  ref
1068
1321
  }) {
1069
1322
  const tokens = useTokens(1);
1070
- const containerStyle = React13.useMemo(
1323
+ const containerStyle = React14.useMemo(
1071
1324
  () => getWrapperStyles({
1072
1325
  tokens,
1073
1326
  direction,
@@ -1102,7 +1355,7 @@ function Wrapper({
1102
1355
  ]
1103
1356
  );
1104
1357
  const userStyles = Array.isArray(style) ? style : style ? [style] : [];
1105
- return /* @__PURE__ */ React13__default.default.createElement(
1358
+ return /* @__PURE__ */ React14__default.default.createElement(
1106
1359
  reactNative.View,
1107
1360
  {
1108
1361
  ref,
@@ -1129,17 +1382,17 @@ function Button({
1129
1382
  ...pressableProps
1130
1383
  }) {
1131
1384
  const tokens = useTokens();
1132
- const { variantColors, sizeTokens } = React13__default.default.useMemo(
1385
+ const { variantColors, sizeTokens } = React14__default.default.useMemo(
1133
1386
  () => getButtonConfig(variant, semantic, size, disabled, tokens),
1134
1387
  [variant, semantic, size, disabled, tokens]
1135
1388
  );
1136
- const padding = React13__default.default.useMemo(
1389
+ const padding = React14__default.default.useMemo(
1137
1390
  () => computeButtonPadding(size, !!icon, !!children, iconPosition),
1138
1391
  [size, icon, children, iconPosition]
1139
1392
  );
1140
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1393
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1141
1394
  // Wrapper handles layout: direction, gap, alignment (padding via style)
1142
- /* @__PURE__ */ React13__default.default.createElement(
1395
+ /* @__PURE__ */ React14__default.default.createElement(
1143
1396
  Wrapper,
1144
1397
  {
1145
1398
  direction: "horizontal",
@@ -1160,13 +1413,14 @@ function Button({
1160
1413
  ...Array.isArray(style) ? style : style ? [style] : []
1161
1414
  ]
1162
1415
  },
1163
- icon && iconPosition === "left" && /* @__PURE__ */ React13__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1416
+ icon && iconPosition === "left" && /* @__PURE__ */ React14__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1164
1417
  children && // Text primitive with semantic props + color style override
1165
- /* @__PURE__ */ React13__default.default.createElement(
1418
+ /* @__PURE__ */ React14__default.default.createElement(
1166
1419
  Text2,
1167
1420
  {
1421
+ role: "label",
1168
1422
  size: sizeTokens.textSize,
1169
- weight: "semibold",
1423
+ centerVertically: true,
1170
1424
  style: [
1171
1425
  { color: variantColors.textColor },
1172
1426
  ...Array.isArray(textStyle) ? textStyle : textStyle ? [textStyle] : []
@@ -1174,7 +1428,7 @@ function Button({
1174
1428
  },
1175
1429
  children
1176
1430
  ),
1177
- icon && iconPosition === "right" && /* @__PURE__ */ React13__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1431
+ icon && iconPosition === "right" && /* @__PURE__ */ React14__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1178
1432
  )
1179
1433
  ));
1180
1434
  }
@@ -1199,11 +1453,11 @@ function Card({
1199
1453
  disabled = false
1200
1454
  }) {
1201
1455
  const tokens = useTokens(elevation);
1202
- const styles = React13__default.default.useMemo(
1456
+ const styles = React14__default.default.useMemo(
1203
1457
  () => getCardStyles(tokens, disabled),
1204
1458
  [tokens, disabled]
1205
1459
  );
1206
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1460
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1207
1461
  }
1208
1462
  var hadKeyboardEvent = false;
1209
1463
  var isListenerSetup = false;
@@ -1233,16 +1487,16 @@ function setupModality() {
1233
1487
  }, true);
1234
1488
  }
1235
1489
  function useFocusVisible() {
1236
- const [isFocusVisible, setIsFocusVisible] = React13.useState(false);
1237
- React13.useEffect(() => {
1490
+ const [isFocusVisible, setIsFocusVisible] = React14.useState(false);
1491
+ React14.useEffect(() => {
1238
1492
  setupModality();
1239
1493
  }, []);
1240
- const onFocus = React13.useCallback(() => {
1494
+ const onFocus = React14.useCallback(() => {
1241
1495
  if (hadKeyboardEvent) {
1242
1496
  setIsFocusVisible(true);
1243
1497
  }
1244
1498
  }, []);
1245
- const onBlur = React13.useCallback(() => {
1499
+ const onBlur = React14.useCallback(() => {
1246
1500
  setIsFocusVisible(false);
1247
1501
  }, []);
1248
1502
  const focusProps = { onFocus, onBlur };
@@ -1354,9 +1608,9 @@ function getFrameStyles(input) {
1354
1608
 
1355
1609
  // src/primitives/Frame/Frame.tsx
1356
1610
  function wrapTextChildren(children, textStyle) {
1357
- return React13__default.default.Children.map(children, (child) => {
1611
+ return React14__default.default.Children.map(children, (child) => {
1358
1612
  if (typeof child === "string" || typeof child === "number") {
1359
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: textStyle }, child);
1613
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: textStyle }, child);
1360
1614
  }
1361
1615
  return child;
1362
1616
  });
@@ -1411,7 +1665,7 @@ function Frame({
1411
1665
  const parentFrameCtx = useFrameContext();
1412
1666
  const resolvedFrameElevation = elevation ?? 0;
1413
1667
  const resolvedElevation = elevation !== void 0 ? toElevationLevel(elevation) : parentFrameCtx?.elevation ?? 1;
1414
- const tokens = React13.useMemo(() => {
1668
+ const tokens = React14.useMemo(() => {
1415
1669
  return computeTokens(
1416
1670
  config.colorSystem,
1417
1671
  mode,
@@ -1423,7 +1677,7 @@ function Frame({
1423
1677
  config.tokenOverrides
1424
1678
  );
1425
1679
  }, [config, mode, resolvedElevation]);
1426
- const styles = React13.useMemo(
1680
+ const styles = React14.useMemo(
1427
1681
  () => getFrameStyles({
1428
1682
  tokens,
1429
1683
  frameElevation: resolvedFrameElevation,
@@ -1471,7 +1725,7 @@ function Frame({
1471
1725
  disabled
1472
1726
  ]
1473
1727
  );
1474
- const contextValue = React13.useMemo(
1728
+ const contextValue = React14.useMemo(
1475
1729
  () => ({ elevation: resolvedElevation, tokens }),
1476
1730
  [resolvedElevation, tokens]
1477
1731
  );
@@ -1492,23 +1746,23 @@ function Frame({
1492
1746
  outlineOffset: 2
1493
1747
  } : void 0;
1494
1748
  const webFocusProps = isInteractive ? focusProps : {};
1495
- const textStyle = React13.useMemo(
1749
+ const textStyle = React14.useMemo(
1496
1750
  () => ({
1497
1751
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
1498
- fontSize: tokens.typography.size.base,
1499
- fontFamily: tokens.typography.fonts.default,
1500
- lineHeight: tokens.typography.size.base * tokens.typography.lineHeight.normal
1752
+ fontSize: tokens.typography.fontSizes["05"],
1753
+ fontFamily: tokens.typography.fonts.main.family,
1754
+ lineHeight: tokens.typography.lineHeights["06"]
1501
1755
  }),
1502
1756
  [tokens]
1503
1757
  );
1504
- const wrappedChildren = React13.useMemo(
1758
+ const wrappedChildren = React14.useMemo(
1505
1759
  () => wrapTextChildren(children, textStyle),
1506
1760
  [children, textStyle]
1507
1761
  );
1508
- return /* @__PURE__ */ React13__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1762
+ return /* @__PURE__ */ React14__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1509
1763
  // Pressable handles taps. When href is set, react-native-web renders
1510
1764
  // it as an <a> tag so it works like a regular link on the web.
1511
- /* @__PURE__ */ React13__default.default.createElement(
1765
+ /* @__PURE__ */ React14__default.default.createElement(
1512
1766
  reactNative.Pressable,
1513
1767
  {
1514
1768
  ref,
@@ -1533,7 +1787,7 @@ function Frame({
1533
1787
  )
1534
1788
  ) : (
1535
1789
  // Non-interactive Frame: just a plain View with no tap handling.
1536
- /* @__PURE__ */ React13__default.default.createElement(
1790
+ /* @__PURE__ */ React14__default.default.createElement(
1537
1791
  reactNative.View,
1538
1792
  {
1539
1793
  ref,
@@ -1553,20 +1807,20 @@ function getTextInputStyles(tokens, disabled) {
1553
1807
  gap: tokens.spacing["04"]
1554
1808
  },
1555
1809
  label: {
1556
- fontFamily: tokens.typography.fonts.default,
1557
- fontSize: tokens.typography.size.sm,
1558
- fontWeight: tokens.typography.weight.semibold,
1810
+ fontFamily: tokens.typography.fonts.main.family,
1811
+ fontSize: tokens.typography.fontSizes["04"],
1812
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1559
1813
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
1560
1814
  },
1561
1815
  input: {
1562
- fontFamily: tokens.typography.fonts.default,
1816
+ fontFamily: tokens.typography.fonts.main.family,
1563
1817
  backgroundColor: newtone.srgbToHex(tokens.backgroundSunken.srgb),
1564
1818
  borderWidth: 1,
1565
1819
  borderColor: newtone.srgbToHex(tokens.border.srgb),
1566
1820
  borderRadius: tokens.radius.md,
1567
1821
  paddingVertical: tokens.spacing["08"],
1568
1822
  paddingHorizontal: tokens.spacing["12"],
1569
- fontSize: tokens.typography.size.base,
1823
+ fontSize: tokens.typography.fontSizes["05"],
1570
1824
  color: disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb),
1571
1825
  opacity: disabled ? 0.5 : 1
1572
1826
  }
@@ -1579,11 +1833,11 @@ function TextInput({
1579
1833
  ...textInputProps
1580
1834
  }) {
1581
1835
  const tokens = useTokens(1);
1582
- const styles = React13__default.default.useMemo(
1836
+ const styles = React14__default.default.useMemo(
1583
1837
  () => getTextInputStyles(tokens, disabled),
1584
1838
  [tokens, disabled]
1585
1839
  );
1586
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React13__default.default.createElement(
1840
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React14__default.default.createElement(
1587
1841
  reactNative.TextInput,
1588
1842
  {
1589
1843
  style: styles.input,
@@ -1635,15 +1889,15 @@ function Popover({
1635
1889
  contentStyle
1636
1890
  }) {
1637
1891
  const tokens = useTokens(1);
1638
- const containerRef = React13.useRef(null);
1639
- const [triggerHeight, setTriggerHeight] = React13.useState(0);
1640
- const onTriggerLayout = React13.useCallback(
1892
+ const containerRef = React14.useRef(null);
1893
+ const [triggerHeight, setTriggerHeight] = React14.useState(0);
1894
+ const onTriggerLayout = React14.useCallback(
1641
1895
  (e) => {
1642
1896
  setTriggerHeight(e.nativeEvent.layout.height);
1643
1897
  },
1644
1898
  []
1645
1899
  );
1646
- React13.useEffect(() => {
1900
+ React14.useEffect(() => {
1647
1901
  if (!isOpen) return;
1648
1902
  openPopovers.forEach((closeFn) => closeFn());
1649
1903
  openPopovers.clear();
@@ -1652,7 +1906,7 @@ function Popover({
1652
1906
  openPopovers.delete(onClose);
1653
1907
  };
1654
1908
  }, [isOpen, onClose]);
1655
- React13.useEffect(() => {
1909
+ React14.useEffect(() => {
1656
1910
  if (!isOpen) return;
1657
1911
  if (typeof document === "undefined") return;
1658
1912
  const handleMouseDown = (e) => {
@@ -1664,7 +1918,7 @@ function Popover({
1664
1918
  document.addEventListener("mousedown", handleMouseDown, true);
1665
1919
  return () => document.removeEventListener("mousedown", handleMouseDown, true);
1666
1920
  }, [isOpen, onClose]);
1667
- const handleKeyDown = React13.useCallback(
1921
+ const handleKeyDown = React14.useCallback(
1668
1922
  (e) => {
1669
1923
  if (closeOnEscape && e.key === "Escape") {
1670
1924
  e.stopPropagation();
@@ -1673,41 +1927,41 @@ function Popover({
1673
1927
  },
1674
1928
  [closeOnEscape, onClose]
1675
1929
  );
1676
- const styles = React13.useMemo(
1930
+ const styles = React14.useMemo(
1677
1931
  () => getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpen),
1678
1932
  [tokens, triggerHeight, offset, maxHeight, width, isOpen]
1679
1933
  );
1680
- const containerStyles = React13.useMemo(
1934
+ const containerStyles = React14.useMemo(
1681
1935
  () => [styles.container, ...Array.isArray(style) ? style : style ? [style] : []],
1682
1936
  [styles.container, style]
1683
1937
  );
1684
- const mergedContentStyles = React13.useMemo(
1938
+ const mergedContentStyles = React14.useMemo(
1685
1939
  () => [styles.content, ...Array.isArray(contentStyle) ? contentStyle : contentStyle ? [contentStyle] : []],
1686
1940
  [styles.content, contentStyle]
1687
1941
  );
1688
1942
  const webProps = { onKeyDown: handleKeyDown };
1689
- return /* @__PURE__ */ React13__default.default.createElement(
1943
+ return /* @__PURE__ */ React14__default.default.createElement(
1690
1944
  reactNative.View,
1691
1945
  {
1692
1946
  ref: containerRef,
1693
1947
  style: containerStyles,
1694
1948
  ...webProps
1695
1949
  },
1696
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { onLayout: onTriggerLayout }, trigger),
1697
- isOpen && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: mergedContentStyles }, children)
1950
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { onLayout: onTriggerLayout }, trigger),
1951
+ isOpen && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: mergedContentStyles }, children)
1698
1952
  );
1699
1953
  }
1700
1954
  function usePopover(options) {
1701
- const [isOpen, setIsOpen] = React13.useState(options?.initialOpen ?? false);
1702
- const open = React13.useCallback(() => {
1955
+ const [isOpen, setIsOpen] = React14.useState(options?.initialOpen ?? false);
1956
+ const open = React14.useCallback(() => {
1703
1957
  setIsOpen(true);
1704
1958
  options?.onOpenChange?.(true);
1705
1959
  }, [options]);
1706
- const close = React13.useCallback(() => {
1960
+ const close = React14.useCallback(() => {
1707
1961
  setIsOpen(false);
1708
1962
  options?.onOpenChange?.(false);
1709
1963
  }, [options]);
1710
- const toggle = React13.useCallback(() => {
1964
+ const toggle = React14.useCallback(() => {
1711
1965
  setIsOpen((prev) => {
1712
1966
  const next = !prev;
1713
1967
  options?.onOpenChange?.(next);
@@ -1723,7 +1977,7 @@ function isOptionGroup(item) {
1723
1977
  }
1724
1978
  function getSelectStyles(tokens, disabled, size, isOpen) {
1725
1979
  const isSm = size === "sm";
1726
- const fontSize = isSm ? tokens.typography.size.sm : tokens.typography.size.base;
1980
+ const fontSize = isSm ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
1727
1981
  const iconSize = fontSize + 2;
1728
1982
  const iconSpace = iconSize + tokens.spacing["08"];
1729
1983
  const paddingVertical = isSm ? tokens.spacing["04"] : tokens.spacing["08"];
@@ -1734,9 +1988,9 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1734
1988
  zIndex: isOpen ? 999 : 0
1735
1989
  },
1736
1990
  label: {
1737
- fontFamily: tokens.typography.fonts.default,
1738
- fontSize: tokens.typography.size.sm,
1739
- fontWeight: tokens.typography.weight.semibold,
1991
+ fontFamily: tokens.typography.fonts.main.family,
1992
+ fontSize: tokens.typography.fontSizes["04"],
1993
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1740
1994
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
1741
1995
  },
1742
1996
  trigger: {
@@ -1753,7 +2007,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1753
2007
  },
1754
2008
  triggerText: {
1755
2009
  flex: 1,
1756
- fontFamily: tokens.typography.fonts.default,
2010
+ fontFamily: tokens.typography.fonts.main.family,
1757
2011
  fontSize,
1758
2012
  color: disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb)
1759
2013
  },
@@ -1765,9 +2019,9 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1765
2019
  justifyContent: "center"
1766
2020
  },
1767
2021
  groupLabel: {
1768
- fontFamily: tokens.typography.fonts.default,
1769
- fontSize: tokens.typography.size.xs,
1770
- fontWeight: tokens.typography.weight.semibold,
2022
+ fontFamily: tokens.typography.fonts.main.family,
2023
+ fontSize: tokens.typography.fontSizes["01"],
2024
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1771
2025
  color: newtone.srgbToHex(tokens.textSecondary.srgb),
1772
2026
  textTransform: "uppercase",
1773
2027
  letterSpacing: 0.5,
@@ -1794,10 +2048,10 @@ function useSelect({
1794
2048
  onClose,
1795
2049
  onOpen
1796
2050
  }) {
1797
- const [focusedIndex, setFocusedIndex] = React13.useState(-1);
1798
- const typeAheadRef = React13.useRef("");
1799
- const typeAheadTimerRef = React13.useRef();
1800
- React13.useEffect(() => {
2051
+ const [focusedIndex, setFocusedIndex] = React14.useState(-1);
2052
+ const typeAheadRef = React14.useRef("");
2053
+ const typeAheadTimerRef = React14.useRef();
2054
+ React14.useEffect(() => {
1801
2055
  if (isOpen) {
1802
2056
  const selectedIdx = flatOptions.findIndex((o) => o.value === value);
1803
2057
  if (selectedIdx >= 0 && !flatOptions[selectedIdx].disabled) {
@@ -1810,7 +2064,7 @@ function useSelect({
1810
2064
  setFocusedIndex(-1);
1811
2065
  }
1812
2066
  }, [isOpen, flatOptions, value]);
1813
- const handleKeyDown = React13.useCallback(
2067
+ const handleKeyDown = React14.useCallback(
1814
2068
  (e) => {
1815
2069
  const key = e.key;
1816
2070
  if (!isOpen) {
@@ -1889,9 +2143,9 @@ function SelectOptionRow({
1889
2143
  const tokens = useTokens(1);
1890
2144
  const paddingVertical = size === "sm" ? tokens.spacing["04"] : tokens.spacing["08"];
1891
2145
  const paddingHorizontal = size === "sm" ? tokens.spacing["08"] : tokens.spacing["12"];
1892
- const fontSize = size === "sm" ? tokens.typography.size.sm : tokens.typography.size.base;
2146
+ const fontSize = size === "sm" ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
1893
2147
  if (renderOption) {
1894
- return /* @__PURE__ */ React13__default.default.createElement(
2148
+ return /* @__PURE__ */ React14__default.default.createElement(
1895
2149
  reactNative.Pressable,
1896
2150
  {
1897
2151
  onPress: option.disabled ? void 0 : onSelect,
@@ -1902,7 +2156,7 @@ function SelectOptionRow({
1902
2156
  renderOption(option, { isSelected, isFocused })
1903
2157
  );
1904
2158
  }
1905
- return /* @__PURE__ */ React13__default.default.createElement(
2159
+ return /* @__PURE__ */ React14__default.default.createElement(
1906
2160
  reactNative.Pressable,
1907
2161
  {
1908
2162
  onPress: option.disabled ? void 0 : onSelect,
@@ -1931,18 +2185,18 @@ function SelectOptionRow({
1931
2185
  }
1932
2186
  ]
1933
2187
  },
1934
- /* @__PURE__ */ React13__default.default.createElement(
2188
+ /* @__PURE__ */ React14__default.default.createElement(
1935
2189
  reactNative.Text,
1936
2190
  {
1937
2191
  style: [
1938
2192
  {
1939
2193
  flex: 1,
1940
- fontFamily: tokens.typography.fonts.default,
2194
+ fontFamily: tokens.typography.fonts.main.family,
1941
2195
  fontSize,
1942
2196
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
1943
2197
  },
1944
2198
  isSelected && {
1945
- fontWeight: tokens.typography.weight.semibold,
2199
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1946
2200
  color: newtone.srgbToHex(tokens.accent.fill.srgb)
1947
2201
  },
1948
2202
  option.disabled && {
@@ -1953,7 +2207,7 @@ function SelectOptionRow({
1953
2207
  },
1954
2208
  option.label
1955
2209
  ),
1956
- isSelected && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React13__default.default.createElement(
2210
+ isSelected && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React14__default.default.createElement(
1957
2211
  Icon,
1958
2212
  {
1959
2213
  name: "check",
@@ -1988,7 +2242,7 @@ function Select({
1988
2242
  }) {
1989
2243
  const tokens = useTokens(1);
1990
2244
  const { isOpen, open, close, toggle } = usePopover();
1991
- const flatOptions = React13.useMemo(() => flattenOptions(options), [options]);
2245
+ const flatOptions = React14.useMemo(() => flattenOptions(options), [options]);
1992
2246
  const { focusedIndex, handleKeyDown } = useSelect({
1993
2247
  flatOptions,
1994
2248
  value,
@@ -2000,7 +2254,7 @@ function Select({
2000
2254
  onClose: close,
2001
2255
  onOpen: open
2002
2256
  });
2003
- const styles = React13.useMemo(
2257
+ const styles = React14.useMemo(
2004
2258
  () => getSelectStyles(tokens, disabled, size, isOpen),
2005
2259
  [tokens, disabled, size, isOpen]
2006
2260
  );
@@ -2008,7 +2262,7 @@ function Select({
2008
2262
  const displayLabel = selectedOption?.label ?? placeholder ?? value;
2009
2263
  const iconColor = disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb);
2010
2264
  const triggerWebProps = { onKeyDown: handleKeyDown };
2011
- const trigger = /* @__PURE__ */ React13__default.default.createElement(
2265
+ const trigger = /* @__PURE__ */ React14__default.default.createElement(
2012
2266
  reactNative.Pressable,
2013
2267
  {
2014
2268
  onPress: disabled ? void 0 : toggle,
@@ -2018,24 +2272,24 @@ function Select({
2018
2272
  ...triggerWebProps,
2019
2273
  style: styles.trigger
2020
2274
  },
2021
- renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
2022
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React13__default.default.createElement(
2275
+ renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
2276
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React14__default.default.createElement(
2023
2277
  Icon,
2024
2278
  {
2025
2279
  name: isOpen ? "expand_less" : "expand_more",
2026
- size: size === "sm" ? tokens.typography.size.sm + 2 : tokens.typography.size.base + 2,
2280
+ size: size === "sm" ? tokens.typography.fontSizes["04"] + 2 : tokens.typography.fontSizes["05"] + 2,
2027
2281
  color: iconColor
2028
2282
  }
2029
2283
  ))
2030
2284
  );
2031
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React13__default.default.createElement(
2285
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : style ? [style] : []] }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React14__default.default.createElement(
2032
2286
  Popover,
2033
2287
  {
2034
2288
  isOpen: isOpen && !disabled,
2035
2289
  onClose: close,
2036
2290
  trigger
2037
2291
  },
2038
- /* @__PURE__ */ React13__default.default.createElement(
2292
+ /* @__PURE__ */ React14__default.default.createElement(
2039
2293
  reactNative.ScrollView,
2040
2294
  {
2041
2295
  bounces: false,
@@ -2044,7 +2298,7 @@ function Select({
2044
2298
  },
2045
2299
  options.map((item) => {
2046
2300
  if (isOptionGroup(item)) {
2047
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { key: item.label }, /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React13__default.default.createElement(
2301
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { key: item.label }, /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.groupLabel }, item.label), item.options.map((opt) => /* @__PURE__ */ React14__default.default.createElement(
2048
2302
  SelectOptionRow,
2049
2303
  {
2050
2304
  key: opt.value,
@@ -2060,7 +2314,7 @@ function Select({
2060
2314
  }
2061
2315
  )));
2062
2316
  }
2063
- return /* @__PURE__ */ React13__default.default.createElement(
2317
+ return /* @__PURE__ */ React14__default.default.createElement(
2064
2318
  SelectOptionRow,
2065
2319
  {
2066
2320
  key: item.value,
@@ -2092,9 +2346,9 @@ function getToggleStyles(tokens, value, disabled) {
2092
2346
  opacity: disabled ? 0.5 : 1
2093
2347
  },
2094
2348
  label: {
2095
- fontFamily: tokens.typography.fonts.default,
2096
- fontSize: tokens.typography.size.sm,
2097
- fontWeight: tokens.typography.weight.semibold,
2349
+ fontFamily: tokens.typography.fonts.main.family,
2350
+ fontSize: tokens.typography.fontSizes["04"],
2351
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2098
2352
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2099
2353
  },
2100
2354
  track: {
@@ -2124,16 +2378,16 @@ function Toggle({
2124
2378
  style
2125
2379
  }) {
2126
2380
  const tokens = useTokens(1);
2127
- const styles = React13__default.default.useMemo(
2381
+ const styles = React14__default.default.useMemo(
2128
2382
  () => getToggleStyles(tokens, value, disabled),
2129
2383
  [tokens, value, disabled]
2130
2384
  );
2131
- const handlePress = React13__default.default.useCallback(() => {
2385
+ const handlePress = React14__default.default.useCallback(() => {
2132
2386
  if (!disabled) {
2133
2387
  onValueChange(!value);
2134
2388
  }
2135
2389
  }, [disabled, value, onValueChange]);
2136
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React13__default.default.createElement(
2390
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label), /* @__PURE__ */ React14__default.default.createElement(
2137
2391
  reactNative.Pressable,
2138
2392
  {
2139
2393
  onPress: handlePress,
@@ -2141,7 +2395,7 @@ function Toggle({
2141
2395
  accessibilityRole: "switch",
2142
2396
  accessibilityState: { checked: value, disabled }
2143
2397
  },
2144
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.track }, /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.thumb }))
2398
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.track }, /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.thumb }))
2145
2399
  ));
2146
2400
  }
2147
2401
  var TRACK_HEIGHT2 = 6;
@@ -2158,15 +2412,15 @@ function getSliderStyles(tokens, disabled) {
2158
2412
  alignItems: "center"
2159
2413
  },
2160
2414
  label: {
2161
- fontFamily: tokens.typography.fonts.default,
2162
- fontSize: tokens.typography.size.sm,
2163
- fontWeight: tokens.typography.weight.semibold,
2415
+ fontFamily: tokens.typography.fonts.main.family,
2416
+ fontSize: tokens.typography.fontSizes["04"],
2417
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2164
2418
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2165
2419
  },
2166
2420
  value: {
2167
- fontFamily: tokens.typography.fonts.default,
2168
- fontSize: tokens.typography.size.sm,
2169
- fontWeight: tokens.typography.weight.medium,
2421
+ fontFamily: tokens.typography.fonts.main.family,
2422
+ fontSize: tokens.typography.fontSizes["04"],
2423
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2170
2424
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
2171
2425
  },
2172
2426
  valueInput: {
@@ -2178,9 +2432,9 @@ function getSliderStyles(tokens, disabled) {
2178
2432
  borderRadius: 4,
2179
2433
  backgroundColor: "transparent",
2180
2434
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
2181
- fontFamily: tokens.typography.fonts.default,
2182
- fontSize: tokens.typography.size.sm,
2183
- fontWeight: tokens.typography.weight.medium,
2435
+ fontFamily: tokens.typography.fonts.main.family,
2436
+ fontSize: tokens.typography.fontSizes["04"],
2437
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2184
2438
  textAlign: "right"
2185
2439
  },
2186
2440
  trackContainer: {
@@ -2227,41 +2481,41 @@ function Slider({
2227
2481
  style
2228
2482
  }) {
2229
2483
  const tokens = useTokens(1);
2230
- const styles = React13__default.default.useMemo(
2484
+ const styles = React14__default.default.useMemo(
2231
2485
  () => getSliderStyles(tokens, disabled),
2232
2486
  [tokens, disabled]
2233
2487
  );
2234
- const trackRef = React13__default.default.useRef(null);
2235
- const trackWidth = React13__default.default.useRef(0);
2236
- const trackPageX = React13__default.default.useRef(0);
2237
- const onValueChangeRef = React13__default.default.useRef(onValueChange);
2238
- const minRef = React13__default.default.useRef(min);
2239
- const maxRef = React13__default.default.useRef(max);
2240
- const stepRef = React13__default.default.useRef(step);
2241
- const disabledRef = React13__default.default.useRef(disabled);
2242
- React13__default.default.useEffect(() => {
2488
+ const trackRef = React14__default.default.useRef(null);
2489
+ const trackWidth = React14__default.default.useRef(0);
2490
+ const trackPageX = React14__default.default.useRef(0);
2491
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2492
+ const minRef = React14__default.default.useRef(min);
2493
+ const maxRef = React14__default.default.useRef(max);
2494
+ const stepRef = React14__default.default.useRef(step);
2495
+ const disabledRef = React14__default.default.useRef(disabled);
2496
+ React14__default.default.useEffect(() => {
2243
2497
  onValueChangeRef.current = onValueChange;
2244
2498
  }, [onValueChange]);
2245
- React13__default.default.useEffect(() => {
2499
+ React14__default.default.useEffect(() => {
2246
2500
  minRef.current = min;
2247
2501
  }, [min]);
2248
- React13__default.default.useEffect(() => {
2502
+ React14__default.default.useEffect(() => {
2249
2503
  maxRef.current = max;
2250
2504
  }, [max]);
2251
- React13__default.default.useEffect(() => {
2505
+ React14__default.default.useEffect(() => {
2252
2506
  stepRef.current = step;
2253
2507
  }, [step]);
2254
- React13__default.default.useEffect(() => {
2508
+ React14__default.default.useEffect(() => {
2255
2509
  disabledRef.current = disabled;
2256
2510
  }, [disabled]);
2257
- const computeValue = React13__default.default.useCallback((pageX) => {
2511
+ const computeValue = React14__default.default.useCallback((pageX) => {
2258
2512
  const localX = pageX - trackPageX.current;
2259
2513
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2260
2514
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2261
2515
  const stepped = Math.round(raw / stepRef.current) * stepRef.current;
2262
2516
  return Math.min(maxRef.current, Math.max(minRef.current, stepped));
2263
2517
  }, []);
2264
- const panResponder = React13__default.default.useRef(
2518
+ const panResponder = React14__default.default.useRef(
2265
2519
  reactNative.PanResponder.create({
2266
2520
  onStartShouldSetPanResponder: () => !disabledRef.current,
2267
2521
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2277,7 +2531,7 @@ function Slider({
2277
2531
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE2);
2278
2532
  const thumbLeft = ratio * usableWidth;
2279
2533
  const fillWidth = thumbLeft + THUMB_SIZE2 / 2;
2280
- const handleValueTextSubmit = React13__default.default.useCallback(
2534
+ const handleValueTextSubmit = React14__default.default.useCallback(
2281
2535
  (text) => {
2282
2536
  const raw = Number(text);
2283
2537
  if (!Number.isNaN(raw)) {
@@ -2286,12 +2540,12 @@ function Slider({
2286
2540
  },
2287
2541
  [onValueChange, min, max]
2288
2542
  );
2289
- const [editText, setEditText] = React13__default.default.useState(String(value));
2290
- React13__default.default.useEffect(() => {
2543
+ const [editText, setEditText] = React14__default.default.useState(String(value));
2544
+ React14__default.default.useEffect(() => {
2291
2545
  setEditText(String(value));
2292
2546
  }, [value]);
2293
2547
  const showLabel = label || showValue || editableValue;
2294
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.labelRow }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13__default.default.createElement(
2548
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.labelRow }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React14__default.default.createElement(
2295
2549
  reactNative.TextInput,
2296
2550
  {
2297
2551
  style: styles.valueInput,
@@ -2303,7 +2557,7 @@ function Slider({
2303
2557
  selectTextOnFocus: true,
2304
2558
  editable: !disabled
2305
2559
  }
2306
- ) : showValue && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.value }, value)), /* @__PURE__ */ React13__default.default.createElement(
2560
+ ) : showValue && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.value }, value)), /* @__PURE__ */ React14__default.default.createElement(
2307
2561
  reactNative.View,
2308
2562
  {
2309
2563
  ref: trackRef,
@@ -2316,9 +2570,9 @@ function Slider({
2316
2570
  },
2317
2571
  ...panResponder.panHandlers
2318
2572
  },
2319
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.trackRail }),
2320
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.trackFill, { width: fillWidth }] }),
2321
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2573
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.trackRail }),
2574
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.trackFill, { width: fillWidth }] }),
2575
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2322
2576
  ));
2323
2577
  }
2324
2578
  var TRACK_HEIGHT3 = 22;
@@ -2374,15 +2628,15 @@ function getHueSliderStyles(tokens, disabled) {
2374
2628
  alignItems: "center"
2375
2629
  },
2376
2630
  label: {
2377
- fontFamily: tokens.typography.fonts.default,
2378
- fontSize: tokens.typography.size.sm,
2379
- fontWeight: tokens.typography.weight.semibold,
2631
+ fontFamily: tokens.typography.fonts.main.family,
2632
+ fontSize: tokens.typography.fontSizes["04"],
2633
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2380
2634
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2381
2635
  },
2382
2636
  value: {
2383
- fontFamily: tokens.typography.fonts.default,
2384
- fontSize: tokens.typography.size.sm,
2385
- fontWeight: tokens.typography.weight.medium,
2637
+ fontFamily: tokens.typography.fonts.main.family,
2638
+ fontSize: tokens.typography.fontSizes["04"],
2639
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2386
2640
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
2387
2641
  },
2388
2642
  valueInput: {
@@ -2394,9 +2648,9 @@ function getHueSliderStyles(tokens, disabled) {
2394
2648
  borderRadius: 4,
2395
2649
  backgroundColor: "transparent",
2396
2650
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
2397
- fontFamily: tokens.typography.fonts.default,
2398
- fontSize: tokens.typography.size.sm,
2399
- fontWeight: tokens.typography.weight.medium,
2651
+ fontFamily: tokens.typography.fonts.main.family,
2652
+ fontSize: tokens.typography.fontSizes["04"],
2653
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2400
2654
  textAlign: "right"
2401
2655
  },
2402
2656
  trackContainer: {
@@ -2441,41 +2695,41 @@ function HueSlider({
2441
2695
  style
2442
2696
  }) {
2443
2697
  const tokens = useTokens(1);
2444
- const styles = React13__default.default.useMemo(
2698
+ const styles = React14__default.default.useMemo(
2445
2699
  () => getHueSliderStyles(tokens, disabled),
2446
2700
  [tokens, disabled]
2447
2701
  );
2448
- const segments = React13__default.default.useMemo(
2702
+ const segments = React14__default.default.useMemo(
2449
2703
  () => buildHueSegments(min, max),
2450
2704
  [min, max]
2451
2705
  );
2452
- const trackRef = React13__default.default.useRef(null);
2453
- const trackWidth = React13__default.default.useRef(0);
2454
- const trackPageX = React13__default.default.useRef(0);
2455
- const onValueChangeRef = React13__default.default.useRef(onValueChange);
2456
- const minRef = React13__default.default.useRef(min);
2457
- const maxRef = React13__default.default.useRef(max);
2458
- const disabledRef = React13__default.default.useRef(disabled);
2459
- React13__default.default.useEffect(() => {
2706
+ const trackRef = React14__default.default.useRef(null);
2707
+ const trackWidth = React14__default.default.useRef(0);
2708
+ const trackPageX = React14__default.default.useRef(0);
2709
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2710
+ const minRef = React14__default.default.useRef(min);
2711
+ const maxRef = React14__default.default.useRef(max);
2712
+ const disabledRef = React14__default.default.useRef(disabled);
2713
+ React14__default.default.useEffect(() => {
2460
2714
  onValueChangeRef.current = onValueChange;
2461
2715
  }, [onValueChange]);
2462
- React13__default.default.useEffect(() => {
2716
+ React14__default.default.useEffect(() => {
2463
2717
  minRef.current = min;
2464
2718
  }, [min]);
2465
- React13__default.default.useEffect(() => {
2719
+ React14__default.default.useEffect(() => {
2466
2720
  maxRef.current = max;
2467
2721
  }, [max]);
2468
- React13__default.default.useEffect(() => {
2722
+ React14__default.default.useEffect(() => {
2469
2723
  disabledRef.current = disabled;
2470
2724
  }, [disabled]);
2471
- const computeHue = React13__default.default.useCallback((pageX) => {
2725
+ const computeHue = React14__default.default.useCallback((pageX) => {
2472
2726
  const localX = pageX - trackPageX.current;
2473
2727
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2474
2728
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2475
2729
  const stepped = Math.round(raw);
2476
2730
  return (stepped % 360 + 360) % 360;
2477
2731
  }, []);
2478
- const panResponder = React13__default.default.useRef(
2732
+ const panResponder = React14__default.default.useRef(
2479
2733
  reactNative.PanResponder.create({
2480
2734
  onStartShouldSetPanResponder: () => !disabledRef.current,
2481
2735
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2491,7 +2745,7 @@ function HueSlider({
2491
2745
  const ratio = max > min ? (sliderValue - min) / (max - min) : 0;
2492
2746
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE3);
2493
2747
  const thumbLeft = ratio * usableWidth;
2494
- const handleValueTextSubmit = React13__default.default.useCallback(
2748
+ const handleValueTextSubmit = React14__default.default.useCallback(
2495
2749
  (text) => {
2496
2750
  const raw = Number(text);
2497
2751
  if (!Number.isNaN(raw)) {
@@ -2500,12 +2754,12 @@ function HueSlider({
2500
2754
  },
2501
2755
  [onValueChange]
2502
2756
  );
2503
- const [editText, setEditText] = React13__default.default.useState(String(value));
2504
- React13__default.default.useEffect(() => {
2757
+ const [editText, setEditText] = React14__default.default.useState(String(value));
2758
+ React14__default.default.useEffect(() => {
2505
2759
  setEditText(String(value));
2506
2760
  }, [value]);
2507
2761
  const showLabel = label || showValue || editableValue;
2508
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.labelRow }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React13__default.default.createElement(
2762
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, showLabel && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.labelRow }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label), editableValue ? /* @__PURE__ */ React14__default.default.createElement(
2509
2763
  reactNative.TextInput,
2510
2764
  {
2511
2765
  style: styles.valueInput,
@@ -2517,7 +2771,7 @@ function HueSlider({
2517
2771
  selectTextOnFocus: true,
2518
2772
  editable: !disabled
2519
2773
  }
2520
- ) : showValue && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React13__default.default.createElement(
2774
+ ) : showValue && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React14__default.default.createElement(
2521
2775
  reactNative.View,
2522
2776
  {
2523
2777
  ref: trackRef,
@@ -2530,8 +2784,8 @@ function HueSlider({
2530
2784
  },
2531
2785
  ...panResponder.panHandlers
2532
2786
  },
2533
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2534
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2787
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.gradientTrack }, segments.map((color, i) => /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { key: i, style: [styles.segment, { backgroundColor: color }] }))),
2788
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2535
2789
  ));
2536
2790
  }
2537
2791
  var TRACK_HEIGHT4 = 22;
@@ -2548,9 +2802,9 @@ function getColorScaleSliderStyles(tokens, disabled) {
2548
2802
  alignItems: "center"
2549
2803
  },
2550
2804
  label: {
2551
- fontFamily: tokens.typography.fonts.default,
2552
- fontSize: tokens.typography.size.sm,
2553
- fontWeight: tokens.typography.weight.semibold,
2805
+ fontFamily: tokens.typography.fonts.main.family,
2806
+ fontSize: tokens.typography.fontSizes["04"],
2807
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2554
2808
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2555
2809
  },
2556
2810
  trackContainer: {
@@ -2580,9 +2834,9 @@ function getColorScaleSliderStyles(tokens, disabled) {
2580
2834
  borderColor: newtone.srgbToHex(tokens.border.srgb)
2581
2835
  },
2582
2836
  warning: {
2583
- fontFamily: tokens.typography.fonts.default,
2584
- fontSize: tokens.typography.size.xs,
2585
- fontWeight: tokens.typography.weight.medium,
2837
+ fontFamily: tokens.typography.fonts.main.family,
2838
+ fontSize: tokens.typography.fontSizes["01"],
2839
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2586
2840
  color: newtone.srgbToHex(tokens.error.fill.srgb)
2587
2841
  }
2588
2842
  });
@@ -2602,36 +2856,36 @@ function ColorScaleSlider({
2602
2856
  style
2603
2857
  }) {
2604
2858
  const tokens = useTokens(1);
2605
- const styles = React13__default.default.useMemo(
2859
+ const styles = React14__default.default.useMemo(
2606
2860
  () => getColorScaleSliderStyles(tokens, disabled),
2607
2861
  [tokens, disabled]
2608
2862
  );
2609
- const trackRef = React13__default.default.useRef(null);
2610
- const trackWidth = React13__default.default.useRef(0);
2611
- const trackPageX = React13__default.default.useRef(0);
2612
- const isDragging = React13__default.default.useRef(false);
2613
- const thumbAnim = React13__default.default.useRef(new reactNative.Animated.Value(0)).current;
2614
- const onValueChangeRef = React13__default.default.useRef(onValueChange);
2615
- const disabledRef = React13__default.default.useRef(disabled);
2616
- const colorsLengthRef = React13__default.default.useRef(colors.length);
2617
- const trimEndsRef = React13__default.default.useRef(trimEnds);
2618
- const snapRef = React13__default.default.useRef(snap);
2619
- React13__default.default.useEffect(() => {
2863
+ const trackRef = React14__default.default.useRef(null);
2864
+ const trackWidth = React14__default.default.useRef(0);
2865
+ const trackPageX = React14__default.default.useRef(0);
2866
+ const isDragging = React14__default.default.useRef(false);
2867
+ const thumbAnim = React14__default.default.useRef(new reactNative.Animated.Value(0)).current;
2868
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2869
+ const disabledRef = React14__default.default.useRef(disabled);
2870
+ const colorsLengthRef = React14__default.default.useRef(colors.length);
2871
+ const trimEndsRef = React14__default.default.useRef(trimEnds);
2872
+ const snapRef = React14__default.default.useRef(snap);
2873
+ React14__default.default.useEffect(() => {
2620
2874
  onValueChangeRef.current = onValueChange;
2621
2875
  }, [onValueChange]);
2622
- React13__default.default.useEffect(() => {
2876
+ React14__default.default.useEffect(() => {
2623
2877
  disabledRef.current = disabled;
2624
2878
  }, [disabled]);
2625
- React13__default.default.useEffect(() => {
2879
+ React14__default.default.useEffect(() => {
2626
2880
  colorsLengthRef.current = colors.length;
2627
2881
  }, [colors.length]);
2628
- React13__default.default.useEffect(() => {
2882
+ React14__default.default.useEffect(() => {
2629
2883
  trimEndsRef.current = trimEnds;
2630
2884
  }, [trimEnds]);
2631
- React13__default.default.useEffect(() => {
2885
+ React14__default.default.useEffect(() => {
2632
2886
  snapRef.current = snap;
2633
2887
  }, [snap]);
2634
- const computeNv = React13__default.default.useCallback((pageX) => {
2888
+ const computeNv = React14__default.default.useCallback((pageX) => {
2635
2889
  const localX = pageX - trackPageX.current;
2636
2890
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2637
2891
  const totalSteps2 = colorsLengthRef.current - 1;
@@ -2646,7 +2900,7 @@ function ColorScaleSlider({
2646
2900
  }
2647
2901
  return nv;
2648
2902
  }, []);
2649
- const panResponder = React13__default.default.useRef(
2903
+ const panResponder = React14__default.default.useRef(
2650
2904
  reactNative.PanResponder.create({
2651
2905
  onStartShouldSetPanResponder: () => !disabledRef.current,
2652
2906
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2674,7 +2928,7 @@ function ColorScaleSlider({
2674
2928
  const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
2675
2929
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE4);
2676
2930
  const thumbLeft = ratio * usableWidth;
2677
- React13__default.default.useEffect(() => {
2931
+ React14__default.default.useEffect(() => {
2678
2932
  if (isDragging.current || !animateValue) {
2679
2933
  thumbAnim.setValue(thumbLeft);
2680
2934
  } else {
@@ -2685,7 +2939,7 @@ function ColorScaleSlider({
2685
2939
  }).start();
2686
2940
  }
2687
2941
  }, [thumbLeft, animateValue, thumbAnim]);
2688
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.labelRow }, /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.label }, label)), /* @__PURE__ */ React13__default.default.createElement(
2942
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, label && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.labelRow }, /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.label }, label)), /* @__PURE__ */ React14__default.default.createElement(
2689
2943
  reactNative.View,
2690
2944
  {
2691
2945
  ref: trackRef,
@@ -2700,9 +2954,9 @@ function ColorScaleSlider({
2700
2954
  },
2701
2955
  ...panResponder.panHandlers
2702
2956
  },
2703
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { key: i, style: [styles.segment, { backgroundColor: newtone.srgbToHex(color.srgb) }] }))),
2704
- /* @__PURE__ */ React13__default.default.createElement(reactNative.Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2705
- ), warning && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.warning }, warning));
2957
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.gradientTrack }, visibleColors.map((color, i) => /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { key: i, style: [styles.segment, { backgroundColor: newtone.srgbToHex(color.srgb) }] }))),
2958
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2959
+ ), warning && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.warning }, warning));
2706
2960
  }
2707
2961
  function getAppShellStyles(tokens) {
2708
2962
  return reactNative.StyleSheet.create({
@@ -2724,8 +2978,8 @@ function getAppShellStyles(tokens) {
2724
2978
  // src/composites/layout/AppShell/AppShell.tsx
2725
2979
  function AppShell({ sidebar, children }) {
2726
2980
  const tokens = useTokens();
2727
- const styles = React13__default.default.useMemo(() => getAppShellStyles(tokens), [tokens]);
2728
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.container }, sidebar, /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.main }, children));
2981
+ const styles = React14__default.default.useMemo(() => getAppShellStyles(tokens), [tokens]);
2982
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.container }, sidebar, /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.main }, children));
2729
2983
  }
2730
2984
  function getSidebarStyles({ tokens, width, bordered }) {
2731
2985
  const borderColor = newtone.srgbToHex(tokens.border.srgb);
@@ -2763,11 +3017,11 @@ function Sidebar({
2763
3017
  bordered = true
2764
3018
  }) {
2765
3019
  const tokens = useTokens();
2766
- const styles = React13__default.default.useMemo(
3020
+ const styles = React14__default.default.useMemo(
2767
3021
  () => getSidebarStyles({ tokens, width, bordered }),
2768
3022
  [tokens, width, bordered]
2769
3023
  );
2770
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.container }, header && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.header }, header), /* @__PURE__ */ React13__default.default.createElement(reactNative.ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.footer }, footer));
3024
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.container }, header && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.header }, header), /* @__PURE__ */ React14__default.default.createElement(reactNative.ScrollView, { style: styles.body }, children), footer && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.footer }, footer));
2771
3025
  }
2772
3026
  function getNavbarStyles({ tokens, height, bordered }) {
2773
3027
  const borderColor = newtone.srgbToHex(tokens.border.srgb);
@@ -2805,28 +3059,27 @@ function Navbar({
2805
3059
  bordered = true
2806
3060
  }) {
2807
3061
  const tokens = useTokens();
2808
- const styles = React13__default.default.useMemo(
3062
+ const styles = React14__default.default.useMemo(
2809
3063
  () => getNavbarStyles({ tokens, height, bordered }),
2810
3064
  [tokens, height, bordered]
2811
3065
  );
2812
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.container }, children ? children : /* @__PURE__ */ React13__default.default.createElement(React13__default.default.Fragment, null, /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.left }, left), /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.right }, right)));
3066
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.container }, children ? children : /* @__PURE__ */ React14__default.default.createElement(React14__default.default.Fragment, null, /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.left }, left), /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.right }, right)));
2813
3067
  }
2814
3068
 
2815
3069
  // src/registry/registry.ts
2816
3070
  var CATEGORIES = [
2817
- { id: "primitives", name: "Design Primitives", description: "Core building blocks for theme-aware layouts and typography" },
2818
- { id: "actions", name: "Actions", description: "Interactive elements that trigger actions" },
2819
- { id: "form-controls", name: "Form Controls", description: "Input elements for user data entry" },
2820
- { id: "range-inputs", name: "Range Inputs", description: "Slider controls for numeric and continuous values" },
2821
- { id: "layout", name: "Layout", description: "Structural and container components" },
2822
- { id: "overlays", name: "Overlays", description: "Floating and portal-based UI elements" }
3071
+ { id: "colors", name: "Colors", description: "Color palettes and token visualization", icon: "palette" },
3072
+ { id: "typography", name: "Typography", description: "Text roles, scopes, and weight control", icon: "text_fields" },
3073
+ { id: "symbols", name: "Symbols", description: "Material Symbols icon browser", icon: "grid_view" },
3074
+ { id: "layout", name: "Layout", description: "Structural containers \u2014 Frame and Wrapper", icon: "grid_on" },
3075
+ { id: "components", name: "Components", description: "Interactive UI components", icon: "widgets" }
2823
3076
  ];
2824
3077
  var COMPONENTS = [
2825
3078
  {
2826
3079
  id: "button",
2827
3080
  name: "Button",
2828
3081
  importName: "Button",
2829
- categoryId: "actions",
3082
+ categoryId: "components",
2830
3083
  description: "Interactive button with multiple variants, sizes, and optional icon",
2831
3084
  hasChildren: true,
2832
3085
  variants: [
@@ -2908,7 +3161,7 @@ var COMPONENTS = [
2908
3161
  id: "text-input",
2909
3162
  name: "TextInput",
2910
3163
  importName: "TextInput",
2911
- categoryId: "form-controls",
3164
+ categoryId: "components",
2912
3165
  description: "Text input field with label support",
2913
3166
  hasChildren: false,
2914
3167
  variants: [
@@ -2935,7 +3188,7 @@ var COMPONENTS = [
2935
3188
  id: "select",
2936
3189
  name: "Select",
2937
3190
  importName: "Select",
2938
- categoryId: "form-controls",
3191
+ categoryId: "components",
2939
3192
  description: "Dropdown selector with options",
2940
3193
  hasChildren: false,
2941
3194
  variants: [
@@ -2982,7 +3235,7 @@ var COMPONENTS = [
2982
3235
  id: "toggle",
2983
3236
  name: "Toggle",
2984
3237
  importName: "Toggle",
2985
- categoryId: "form-controls",
3238
+ categoryId: "components",
2986
3239
  description: "Binary switch component",
2987
3240
  hasChildren: false,
2988
3241
  variants: [
@@ -3009,7 +3262,7 @@ var COMPONENTS = [
3009
3262
  id: "slider",
3010
3263
  name: "Slider",
3011
3264
  importName: "Slider",
3012
- categoryId: "range-inputs",
3265
+ categoryId: "components",
3013
3266
  description: "Numeric range slider",
3014
3267
  hasChildren: false,
3015
3268
  variants: [
@@ -3053,7 +3306,7 @@ var COMPONENTS = [
3053
3306
  id: "hue-slider",
3054
3307
  name: "HueSlider",
3055
3308
  importName: "HueSlider",
3056
- categoryId: "range-inputs",
3309
+ categoryId: "components",
3057
3310
  description: "Specialized slider for hue selection (0-360\xB0)",
3058
3311
  hasChildren: false,
3059
3312
  variants: [
@@ -3189,7 +3442,7 @@ var COMPONENTS = [
3189
3442
  id: "card",
3190
3443
  name: "Card",
3191
3444
  importName: "Card",
3192
- categoryId: "layout",
3445
+ categoryId: "components",
3193
3446
  description: "Surface container with elevation levels",
3194
3447
  hasChildren: true,
3195
3448
  variants: [
@@ -3222,45 +3475,59 @@ var COMPONENTS = [
3222
3475
  id: "text",
3223
3476
  name: "Text",
3224
3477
  importName: "Text",
3225
- categoryId: "primitives",
3226
- description: "Typography primitive with semantic size, weight, color, font, and lineHeight",
3478
+ categoryId: "typography",
3479
+ description: "Typography primitive with semantic scope (font family) and role (purpose)",
3227
3480
  hasChildren: true,
3481
+ previewLayout: "list",
3228
3482
  variants: [
3229
- { id: "default", label: "Default", props: {} },
3230
- { id: "heading", label: "Heading", props: { size: "xl", weight: "bold" } },
3231
- { id: "subheading", label: "Subheading", props: { size: "lg", weight: "semibold" } },
3232
- { id: "body", label: "Body", props: { size: "base" } },
3233
- { id: "caption", label: "Caption", props: { size: "sm", color: "secondary" } },
3234
- { id: "accent", label: "Accent", props: { color: "accent", weight: "medium" } },
3235
- { id: "mono", label: "Monospace", props: { font: "mono", size: "sm" } }
3483
+ { id: "body", label: "Body", props: { role: "body" } },
3484
+ { id: "headline", label: "Headline", props: { role: "headline", scope: "display" } },
3485
+ { id: "title", label: "Title", props: { role: "title", scope: "display" } },
3486
+ { id: "heading", label: "Heading", props: { role: "heading" } },
3487
+ { id: "subheading", label: "Subheading", props: { role: "subheading" } },
3488
+ { id: "label", label: "Label", props: { role: "label" } },
3489
+ { id: "caption", label: "Caption", props: { role: "caption", color: "secondary" } },
3490
+ { id: "mono", label: "Monospace", props: { scope: "mono", role: "body" } },
3491
+ { id: "currency", label: "Currency", props: { scope: "currency", role: "body" } }
3236
3492
  ],
3237
3493
  editableProps: [
3238
3494
  {
3239
- name: "size",
3240
- label: "Size",
3495
+ name: "scope",
3496
+ label: "Scope",
3241
3497
  control: "select",
3242
3498
  options: [
3243
- { label: "Extra Small", value: "xs" },
3244
- { label: "Small", value: "sm" },
3245
- { label: "Base", value: "base" },
3246
- { label: "Medium", value: "md" },
3247
- { label: "Large", value: "lg" },
3248
- { label: "Extra Large", value: "xl" },
3249
- { label: "XXL", value: "xxl" }
3499
+ { label: "Main", value: "main" },
3500
+ { label: "Display", value: "display" },
3501
+ { label: "Mono", value: "mono" },
3502
+ { label: "Currency", value: "currency" }
3250
3503
  ],
3251
- defaultValue: "base"
3504
+ defaultValue: "main"
3252
3505
  },
3253
3506
  {
3254
- name: "weight",
3255
- label: "Weight",
3507
+ name: "role",
3508
+ label: "Role",
3509
+ control: "select",
3510
+ options: [
3511
+ { label: "Headline", value: "headline" },
3512
+ { label: "Title", value: "title" },
3513
+ { label: "Heading", value: "heading" },
3514
+ { label: "Subheading", value: "subheading" },
3515
+ { label: "Body", value: "body" },
3516
+ { label: "Label", value: "label" },
3517
+ { label: "Caption", value: "caption" }
3518
+ ],
3519
+ defaultValue: "body"
3520
+ },
3521
+ {
3522
+ name: "size",
3523
+ label: "Size",
3256
3524
  control: "select",
3257
3525
  options: [
3258
- { label: "Regular", value: "regular" },
3259
- { label: "Medium", value: "medium" },
3260
- { label: "Semibold", value: "semibold" },
3261
- { label: "Bold", value: "bold" }
3526
+ { label: "Small", value: "sm" },
3527
+ { label: "Medium", value: "md" },
3528
+ { label: "Large", value: "lg" }
3262
3529
  ],
3263
- defaultValue: "regular"
3530
+ defaultValue: "md"
3264
3531
  },
3265
3532
  {
3266
3533
  name: "color",
@@ -3277,17 +3544,6 @@ var COMPONENTS = [
3277
3544
  { label: "Error", value: "error" }
3278
3545
  ],
3279
3546
  defaultValue: "primary"
3280
- },
3281
- {
3282
- name: "font",
3283
- label: "Font",
3284
- control: "select",
3285
- options: [
3286
- { label: "Default", value: "default" },
3287
- { label: "Display", value: "display" },
3288
- { label: "Mono", value: "mono" }
3289
- ],
3290
- defaultValue: "default"
3291
3547
  }
3292
3548
  ]
3293
3549
  },
@@ -3295,7 +3551,7 @@ var COMPONENTS = [
3295
3551
  id: "icon",
3296
3552
  name: "Icon",
3297
3553
  importName: "Icon",
3298
- categoryId: "primitives",
3554
+ categoryId: "symbols",
3299
3555
  description: "Material Symbols icon with size and fill",
3300
3556
  hasChildren: false,
3301
3557
  variants: [
@@ -3332,7 +3588,7 @@ var COMPONENTS = [
3332
3588
  id: "wrapper",
3333
3589
  name: "Wrapper",
3334
3590
  importName: "Wrapper",
3335
- categoryId: "primitives",
3591
+ categoryId: "layout",
3336
3592
  description: "Lightweight layout container with direction, spacing, and alignment (no theming)",
3337
3593
  hasChildren: true,
3338
3594
  variants: [
@@ -3406,7 +3662,7 @@ var COMPONENTS = [
3406
3662
  id: "color-scale-slider",
3407
3663
  name: "ColorScaleSlider",
3408
3664
  importName: "ColorScaleSlider",
3409
- categoryId: "range-inputs",
3665
+ categoryId: "components",
3410
3666
  description: "Interactive palette preview slider with color segments",
3411
3667
  hasChildren: false,
3412
3668
  variants: [
@@ -3449,6 +3705,7 @@ var HANDLER_PROPS = {
3449
3705
  };
3450
3706
  var CHILDREN_CONTENT = {
3451
3707
  button: "Button",
3708
+ text: "The quick brown fox",
3452
3709
  card: "{/* content */}",
3453
3710
  frame: "{/* content */}"
3454
3711
  };
@@ -3754,72 +4011,22 @@ var ICON_CATALOG = [
3754
4011
  }
3755
4012
  ];
3756
4013
 
3757
- // src/fonts/googleFonts.ts
3758
- var GOOGLE_FONTS = [
3759
- // Sans-serif
3760
- { family: "Inter", category: "sans-serif", fallback: "sans-serif" },
3761
- { family: "Roboto", category: "sans-serif", fallback: "sans-serif" },
3762
- { family: "Open Sans", category: "sans-serif", fallback: "sans-serif" },
3763
- { family: "Lato", category: "sans-serif", fallback: "sans-serif" },
3764
- { family: "Montserrat", category: "sans-serif", fallback: "sans-serif" },
3765
- { family: "Poppins", category: "sans-serif", fallback: "sans-serif" },
3766
- { family: "Nunito", category: "sans-serif", fallback: "sans-serif" },
3767
- { family: "Source Sans 3", category: "sans-serif", fallback: "sans-serif" },
3768
- { family: "Work Sans", category: "sans-serif", fallback: "sans-serif" },
3769
- { family: "Raleway", category: "sans-serif", fallback: "sans-serif" },
3770
- { family: "DM Sans", category: "sans-serif", fallback: "sans-serif" },
3771
- { family: "Plus Jakarta Sans", category: "sans-serif", fallback: "sans-serif" },
3772
- { family: "Outfit", category: "sans-serif", fallback: "sans-serif" },
3773
- { family: "Space Grotesk", category: "sans-serif", fallback: "sans-serif" },
3774
- { family: "Manrope", category: "sans-serif", fallback: "sans-serif" },
3775
- // Serif
3776
- { family: "Playfair Display", category: "serif", fallback: "serif" },
3777
- { family: "Merriweather", category: "serif", fallback: "serif" },
3778
- { family: "Lora", category: "serif", fallback: "serif" },
3779
- { family: "Libre Baskerville", category: "serif", fallback: "serif" },
3780
- { family: "Source Serif 4", category: "serif", fallback: "serif" },
3781
- { family: "Bitter", category: "serif", fallback: "serif" },
3782
- { family: "Cormorant Garamond", category: "serif", fallback: "serif" },
3783
- { family: "EB Garamond", category: "serif", fallback: "serif" },
3784
- { family: "Crimson Text", category: "serif", fallback: "serif" },
3785
- { family: "Noto Serif", category: "serif", fallback: "serif" },
3786
- // Monospace
3787
- { family: "Fira Code", category: "monospace", fallback: "monospace" },
3788
- { family: "JetBrains Mono", category: "monospace", fallback: "monospace" },
3789
- { family: "Source Code Pro", category: "monospace", fallback: "monospace" },
3790
- { family: "IBM Plex Mono", category: "monospace", fallback: "monospace" },
3791
- { family: "Roboto Mono", category: "monospace", fallback: "monospace" },
3792
- { family: "Space Mono", category: "monospace", fallback: "monospace" },
3793
- { family: "Ubuntu Mono", category: "monospace", fallback: "monospace" },
3794
- { family: "Inconsolata", category: "monospace", fallback: "monospace" },
3795
- // Display
3796
- { family: "Abril Fatface", category: "display", fallback: "serif" },
3797
- { family: "Bebas Neue", category: "display", fallback: "sans-serif" },
3798
- { family: "Oswald", category: "display", fallback: "sans-serif" },
3799
- { family: "Righteous", category: "display", fallback: "sans-serif" },
3800
- { family: "Lobster", category: "display", fallback: "cursive" },
3801
- { family: "Pacifico", category: "display", fallback: "cursive" },
3802
- { family: "Comfortaa", category: "display", fallback: "sans-serif" },
3803
- { family: "Fredoka", category: "display", fallback: "sans-serif" }
3804
- ];
3805
- var SYSTEM_FONTS = [
3806
- {
3807
- family: "system-ui",
3808
- category: "sans-serif",
3809
- fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
3810
- },
3811
- {
3812
- family: "ui-monospace",
3813
- category: "monospace",
3814
- fallback: "SFMono-Regular, Menlo, Monaco, Consolas, monospace"
3815
- },
3816
- {
3817
- family: "ui-serif",
3818
- category: "serif",
3819
- fallback: 'Georgia, "Times New Roman", serif'
3820
- }
3821
- ];
3822
-
4014
+ Object.defineProperty(exports, "DEFAULT_FONT_SIZES", {
4015
+ enumerable: true,
4016
+ get: function () { return fonts.DEFAULT_FONT_SIZES; }
4017
+ });
4018
+ Object.defineProperty(exports, "DEFAULT_LINE_HEIGHTS", {
4019
+ enumerable: true,
4020
+ get: function () { return fonts.DEFAULT_LINE_HEIGHTS; }
4021
+ });
4022
+ Object.defineProperty(exports, "DEFAULT_ROLE_SCALES", {
4023
+ enumerable: true,
4024
+ get: function () { return fonts.DEFAULT_ROLE_SCALES; }
4025
+ });
4026
+ Object.defineProperty(exports, "buildGoogleFontsUrl", {
4027
+ enumerable: true,
4028
+ get: function () { return fonts.buildGoogleFontsUrl; }
4029
+ });
3823
4030
  exports.ACCENT_DEFAULTS = ACCENT_DEFAULTS;
3824
4031
  exports.AppShell = AppShell;
3825
4032
  exports.Button = Button;
@@ -3830,7 +4037,6 @@ exports.ColorScaleSlider = ColorScaleSlider;
3830
4037
  exports.DEFAULT_THEME_CONFIG = DEFAULT_THEME_CONFIG;
3831
4038
  exports.ERROR_DEFAULTS = ERROR_DEFAULTS;
3832
4039
  exports.Frame = Frame;
3833
- exports.GOOGLE_FONTS = GOOGLE_FONTS;
3834
4040
  exports.HueSlider = HueSlider;
3835
4041
  exports.ICON_CATALOG = ICON_CATALOG;
3836
4042
  exports.Icon = Icon;
@@ -3839,7 +4045,6 @@ exports.Navbar = Navbar;
3839
4045
  exports.NewtoneProvider = NewtoneProvider;
3840
4046
  exports.Popover = Popover;
3841
4047
  exports.SUCCESS_DEFAULTS = SUCCESS_DEFAULTS;
3842
- exports.SYSTEM_FONTS = SYSTEM_FONTS;
3843
4048
  exports.Select = Select;
3844
4049
  exports.Sidebar = Sidebar;
3845
4050
  exports.Slider = Slider;
@@ -3848,17 +4053,19 @@ exports.TextInput = TextInput;
3848
4053
  exports.Toggle = Toggle;
3849
4054
  exports.WARNING_DEFAULTS = WARNING_DEFAULTS;
3850
4055
  exports.Wrapper = Wrapper;
3851
- exports.buildGoogleFontsUrl = buildGoogleFontsUrl;
3852
4056
  exports.computeTokens = computeTokens;
3853
4057
  exports.generateComponentCode = generateComponentCode;
3854
4058
  exports.getCategory = getCategory;
3855
4059
  exports.getComponent = getComponent;
3856
4060
  exports.getComponentsByCategory = getComponentsByCategory;
3857
4061
  exports.isOptionGroup = isOptionGroup;
4062
+ exports.measureAvgCharWidth = measureAvgCharWidth;
3858
4063
  exports.useFocusVisible = useFocusVisible;
3859
4064
  exports.useFrameContext = useFrameContext;
4065
+ exports.useLocalCalibration = useLocalCalibration;
3860
4066
  exports.useNewtoneTheme = useNewtoneTheme;
3861
4067
  exports.usePopover = usePopover;
3862
4068
  exports.useTokens = useTokens;
4069
+ exports.useTypographyCalibrations = useTypographyCalibrations;
3863
4070
  //# sourceMappingURL=index.cjs.map
3864
4071
  //# sourceMappingURL=index.cjs.map