@newtonedev/components 0.1.7 → 0.1.8

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 +628 -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 +567 -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 +75 -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 +205 -53
  80. package/src/primitives/Text/Text.types.ts +80 -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,188 @@ 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,
862
996
  align,
863
997
  numberOfLines,
864
998
  elevation = 1,
865
999
  style,
866
- // Accessibility
867
- accessibilityRole,
868
- // Testing & platform
1000
+ accessibilityRole: accessibilityRoleOverride,
869
1001
  testID,
870
1002
  nativeID,
871
- ref
1003
+ ref,
1004
+ responsive = false,
1005
+ centerVertically = false,
1006
+ features
872
1007
  }) {
873
1008
  const tokens = useTokens(elevation);
874
- const resolvedStyle = React13.useMemo(() => {
875
- const fontSize = tokens.typography.size[size];
1009
+ const { config, reportingEndpoint } = useNewtoneTheme();
1010
+ const size = sizeOverride ?? "md";
1011
+ const fontSlot = tokens.typography.fonts[scope];
1012
+ const resolvedFontWeight = config.typography.roleWeights?.[role] ?? fonts.ROLE_DEFAULT_WEIGHTS[role];
1013
+ const breakpoint = useBreakpoint();
1014
+ const baseStep = config.typography.roles[role][size];
1015
+ const bpScale = fonts.BREAKPOINT_ROLE_SCALE[breakpoint][role];
1016
+ const step = bpScale === 1 ? baseStep : fonts.scaleRoleStep(baseStep, bpScale);
1017
+ const calibrations = useTypographyCalibrations();
1018
+ const fontSlotFull = config.typography.fonts[scope];
1019
+ const localRatio = useLocalCalibration(
1020
+ fontSlot.family,
1021
+ fonts.SEMANTIC_WEIGHT_MAP.regular,
1022
+ fontSlotFull.config.fallback,
1023
+ calibrations[fontSlot.family]
1024
+ );
1025
+ const isAdaptive = ADAPTIVE_ROLES.has(role);
1026
+ const [containerWidth, setContainerWidth] = React14.useState(null);
1027
+ const characterCount = React14.useMemo(() => extractCharacterCount(children), [children]);
1028
+ const resolvedStep = React14.useMemo(
1029
+ () => fonts.resolveResponsiveSize(
1030
+ {
1031
+ role,
1032
+ size,
1033
+ responsive: responsive && isAdaptive,
1034
+ fontFamily: fontSlot.family,
1035
+ maxFontSize: step.fontSize,
1036
+ minFontSize: Math.max(8, Math.round(step.fontSize * 0.7))
1037
+ },
1038
+ config.typography.roles,
1039
+ containerWidth != null ? { containerWidth, characterCount } : void 0,
1040
+ { [fontSlot.family]: localRatio }
1041
+ ),
1042
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1043
+ [role, size, responsive, isAdaptive, fontSlot.family, step.fontSize, config.typography.roles, containerWidth, characterCount, localRatio]
1044
+ );
1045
+ React14.useEffect(() => {
1046
+ if (!reportingEndpoint || !responsive || !isAdaptive || containerWidth == null) return;
1047
+ const lineWidths = fonts.estimateLineWidths(characterCount, containerWidth, resolvedStep.fontSize, localRatio);
1048
+ const lastLine = lineWidths[lineWidths.length - 1];
1049
+ enqueueObservation(reportingEndpoint, {
1050
+ fontFamily: fontSlot.family,
1051
+ fontWeight: resolvedFontWeight,
1052
+ role,
1053
+ size,
1054
+ fontSize: resolvedStep.fontSize,
1055
+ containerWidth,
1056
+ characterCount,
1057
+ lineCount: lineWidths.length,
1058
+ lastLineRatio: containerWidth > 0 ? lastLine / containerWidth : 1
1059
+ });
1060
+ }, [reportingEndpoint, resolvedStep.fontSize, containerWidth]);
1061
+ const resolvedStyle = React14.useMemo(() => {
1062
+ const activeStep = responsive && isAdaptive ? resolvedStep : step;
1063
+ const currentMetrics = config.typography.fontMetrics?.[fontSlot.family];
1064
+ const correctedLineHeight = currentMetrics ? Math.round(activeStep.lineHeight * currentMetrics.naturalLineHeightRatio / fonts.REFERENCE_LINE_HEIGHT_RATIO / 4) * 4 : activeStep.lineHeight;
1065
+ const vcOffset = centerVertically && currentMetrics ? Math.round(currentMetrics.verticalCenterOffset * activeStep.fontSize * 2) / 2 : 0;
1066
+ const activeFeatures = features ? currentMetrics?.features ? features.filter((tag) => currentMetrics.features.includes(tag)) : [...features] : [];
1067
+ const featureSettings = activeFeatures.length > 0 ? fonts.buildFontFeatureSettings(activeFeatures) : void 0;
876
1068
  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').
1069
+ fontFamily: fontSlot.family,
1070
+ fontSize: activeStep.fontSize,
1071
+ fontWeight: String(resolvedFontWeight),
883
1072
  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
1073
+ lineHeight: correctedLineHeight,
1074
+ textAlign: align,
1075
+ ...vcOffset !== 0 ? { transform: [{ translateY: vcOffset }] } : {},
1076
+ ...featureSettings ? { fontFeatureSettings: featureSettings } : {}
887
1077
  };
888
- }, [tokens, size, weight, color, font, lineHeight, align]);
889
- return /* @__PURE__ */ React13__default.default.createElement(
1078
+ }, [tokens, fontSlot, step, resolvedStep, responsive, isAdaptive, resolvedFontWeight, color, align, config.typography.fontMetrics, centerVertically, features]);
1079
+ const inferredA11yRole = role === "headline" || role === "title" || role === "heading" ? "header" : void 0;
1080
+ const effectiveA11yRole = accessibilityRoleOverride ?? inferredA11yRole;
1081
+ const ariaLevel = effectiveA11yRole === "header" ? ROLE_HEADING_LEVEL[role] : void 0;
1082
+ const scopeCtx = React14.useMemo(() => ({ weights: fonts.SEMANTIC_WEIGHT_MAP }), []);
1083
+ const textNode = /* @__PURE__ */ React14__default.default.createElement(TextScopeContext.Provider, { value: scopeCtx }, /* @__PURE__ */ React14__default.default.createElement(
890
1084
  reactNative.Text,
891
1085
  {
892
1086
  ref,
893
1087
  testID,
894
1088
  nativeID,
895
- accessibilityRole,
1089
+ accessibilityRole: effectiveA11yRole,
1090
+ "aria-level": ariaLevel,
896
1091
  style: style ? [resolvedStyle, ...Array.isArray(style) ? style : [style]] : resolvedStyle,
897
1092
  numberOfLines
898
1093
  },
899
1094
  children
1095
+ ));
1096
+ if (responsive && isAdaptive) {
1097
+ return /* @__PURE__ */ React14__default.default.createElement(
1098
+ reactNative.View,
1099
+ {
1100
+ onLayout: (e) => {
1101
+ const w = e.nativeEvent.layout.width;
1102
+ if (w > 0) setContainerWidth(w);
1103
+ },
1104
+ style: { width: "100%" }
1105
+ },
1106
+ textNode
1107
+ );
1108
+ }
1109
+ return textNode;
1110
+ }
1111
+ function TextSpan({ children, color, weight, italic, underline, highlight, style }) {
1112
+ const tokens = useTokens(1);
1113
+ const scopeCtx = React14.useContext(TextScopeContext);
1114
+ const spanStyle = React14.useMemo(() => {
1115
+ const s = {};
1116
+ if (color) s.color = resolveTextColor(color, tokens);
1117
+ if (weight && scopeCtx) s.fontWeight = String(scopeCtx.weights[weight]);
1118
+ if (italic) s.fontStyle = "italic";
1119
+ if (underline) s.textDecorationLine = "underline";
1120
+ if (highlight) s.backgroundColor = resolveTextColor(highlight, tokens);
1121
+ return s;
1122
+ }, [tokens, scopeCtx, color, weight, italic, underline, highlight]);
1123
+ return React14__default.default.createElement(
1124
+ reactNative.Text,
1125
+ { style: style ? [spanStyle, ...Array.isArray(style) ? style : [style]] : spanStyle },
1126
+ children
900
1127
  );
901
1128
  }
1129
+ function TextBold(props) {
1130
+ return React14__default.default.createElement(TextSpan, { ...props, weight: "bold" });
1131
+ }
1132
+ function TextMedium(props) {
1133
+ return React14__default.default.createElement(TextSpan, { ...props, weight: "medium" });
1134
+ }
1135
+ function TextItalic(props) {
1136
+ return React14__default.default.createElement(TextSpan, { ...props, italic: true });
1137
+ }
1138
+ function TextUnderline(props) {
1139
+ return React14__default.default.createElement(TextSpan, { ...props, underline: true });
1140
+ }
1141
+ function TextHighlight(props) {
1142
+ return React14__default.default.createElement(TextSpan, props);
1143
+ }
1144
+
1145
+ // src/primitives/Text/index.ts
1146
+ var Text2 = Object.assign(TextBase, {
1147
+ Span: TextSpan,
1148
+ Bold: TextBold,
1149
+ Medium: TextMedium,
1150
+ Italic: TextItalic,
1151
+ Underline: TextUnderline,
1152
+ Highlight: TextHighlight
1153
+ });
902
1154
 
903
1155
  // src/primitives/Frame/Frame.utils.ts
904
1156
  function resolveSpacing(value, tokens) {
@@ -1067,7 +1319,7 @@ function Wrapper({
1067
1319
  ref
1068
1320
  }) {
1069
1321
  const tokens = useTokens(1);
1070
- const containerStyle = React13.useMemo(
1322
+ const containerStyle = React14.useMemo(
1071
1323
  () => getWrapperStyles({
1072
1324
  tokens,
1073
1325
  direction,
@@ -1102,7 +1354,7 @@ function Wrapper({
1102
1354
  ]
1103
1355
  );
1104
1356
  const userStyles = Array.isArray(style) ? style : style ? [style] : [];
1105
- return /* @__PURE__ */ React13__default.default.createElement(
1357
+ return /* @__PURE__ */ React14__default.default.createElement(
1106
1358
  reactNative.View,
1107
1359
  {
1108
1360
  ref,
@@ -1129,17 +1381,17 @@ function Button({
1129
1381
  ...pressableProps
1130
1382
  }) {
1131
1383
  const tokens = useTokens();
1132
- const { variantColors, sizeTokens } = React13__default.default.useMemo(
1384
+ const { variantColors, sizeTokens } = React14__default.default.useMemo(
1133
1385
  () => getButtonConfig(variant, semantic, size, disabled, tokens),
1134
1386
  [variant, semantic, size, disabled, tokens]
1135
1387
  );
1136
- const padding = React13__default.default.useMemo(
1388
+ const padding = React14__default.default.useMemo(
1137
1389
  () => computeButtonPadding(size, !!icon, !!children, iconPosition),
1138
1390
  [size, icon, children, iconPosition]
1139
1391
  );
1140
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1392
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.Pressable, { disabled, ...pressableProps }, ({ pressed, hovered }) => (
1141
1393
  // Wrapper handles layout: direction, gap, alignment (padding via style)
1142
- /* @__PURE__ */ React13__default.default.createElement(
1394
+ /* @__PURE__ */ React14__default.default.createElement(
1143
1395
  Wrapper,
1144
1396
  {
1145
1397
  direction: "horizontal",
@@ -1160,13 +1412,14 @@ function Button({
1160
1412
  ...Array.isArray(style) ? style : style ? [style] : []
1161
1413
  ]
1162
1414
  },
1163
- icon && iconPosition === "left" && /* @__PURE__ */ React13__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1415
+ icon && iconPosition === "left" && /* @__PURE__ */ React14__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor }),
1164
1416
  children && // Text primitive with semantic props + color style override
1165
- /* @__PURE__ */ React13__default.default.createElement(
1417
+ /* @__PURE__ */ React14__default.default.createElement(
1166
1418
  Text2,
1167
1419
  {
1420
+ role: "label",
1168
1421
  size: sizeTokens.textSize,
1169
- weight: "semibold",
1422
+ centerVertically: true,
1170
1423
  style: [
1171
1424
  { color: variantColors.textColor },
1172
1425
  ...Array.isArray(textStyle) ? textStyle : textStyle ? [textStyle] : []
@@ -1174,7 +1427,7 @@ function Button({
1174
1427
  },
1175
1428
  children
1176
1429
  ),
1177
- icon && iconPosition === "right" && /* @__PURE__ */ React13__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1430
+ icon && iconPosition === "right" && /* @__PURE__ */ React14__default.default.createElement(Icon, { name: icon, size: sizeTokens.iconSize, color: variantColors.iconColor })
1178
1431
  )
1179
1432
  ));
1180
1433
  }
@@ -1199,11 +1452,11 @@ function Card({
1199
1452
  disabled = false
1200
1453
  }) {
1201
1454
  const tokens = useTokens(elevation);
1202
- const styles = React13__default.default.useMemo(
1455
+ const styles = React14__default.default.useMemo(
1203
1456
  () => getCardStyles(tokens, disabled),
1204
1457
  [tokens, disabled]
1205
1458
  );
1206
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1459
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
1207
1460
  }
1208
1461
  var hadKeyboardEvent = false;
1209
1462
  var isListenerSetup = false;
@@ -1233,16 +1486,16 @@ function setupModality() {
1233
1486
  }, true);
1234
1487
  }
1235
1488
  function useFocusVisible() {
1236
- const [isFocusVisible, setIsFocusVisible] = React13.useState(false);
1237
- React13.useEffect(() => {
1489
+ const [isFocusVisible, setIsFocusVisible] = React14.useState(false);
1490
+ React14.useEffect(() => {
1238
1491
  setupModality();
1239
1492
  }, []);
1240
- const onFocus = React13.useCallback(() => {
1493
+ const onFocus = React14.useCallback(() => {
1241
1494
  if (hadKeyboardEvent) {
1242
1495
  setIsFocusVisible(true);
1243
1496
  }
1244
1497
  }, []);
1245
- const onBlur = React13.useCallback(() => {
1498
+ const onBlur = React14.useCallback(() => {
1246
1499
  setIsFocusVisible(false);
1247
1500
  }, []);
1248
1501
  const focusProps = { onFocus, onBlur };
@@ -1354,9 +1607,9 @@ function getFrameStyles(input) {
1354
1607
 
1355
1608
  // src/primitives/Frame/Frame.tsx
1356
1609
  function wrapTextChildren(children, textStyle) {
1357
- return React13__default.default.Children.map(children, (child) => {
1610
+ return React14__default.default.Children.map(children, (child) => {
1358
1611
  if (typeof child === "string" || typeof child === "number") {
1359
- return /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: textStyle }, child);
1612
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: textStyle }, child);
1360
1613
  }
1361
1614
  return child;
1362
1615
  });
@@ -1411,7 +1664,7 @@ function Frame({
1411
1664
  const parentFrameCtx = useFrameContext();
1412
1665
  const resolvedFrameElevation = elevation ?? 0;
1413
1666
  const resolvedElevation = elevation !== void 0 ? toElevationLevel(elevation) : parentFrameCtx?.elevation ?? 1;
1414
- const tokens = React13.useMemo(() => {
1667
+ const tokens = React14.useMemo(() => {
1415
1668
  return computeTokens(
1416
1669
  config.colorSystem,
1417
1670
  mode,
@@ -1423,7 +1676,7 @@ function Frame({
1423
1676
  config.tokenOverrides
1424
1677
  );
1425
1678
  }, [config, mode, resolvedElevation]);
1426
- const styles = React13.useMemo(
1679
+ const styles = React14.useMemo(
1427
1680
  () => getFrameStyles({
1428
1681
  tokens,
1429
1682
  frameElevation: resolvedFrameElevation,
@@ -1471,7 +1724,7 @@ function Frame({
1471
1724
  disabled
1472
1725
  ]
1473
1726
  );
1474
- const contextValue = React13.useMemo(
1727
+ const contextValue = React14.useMemo(
1475
1728
  () => ({ elevation: resolvedElevation, tokens }),
1476
1729
  [resolvedElevation, tokens]
1477
1730
  );
@@ -1492,23 +1745,23 @@ function Frame({
1492
1745
  outlineOffset: 2
1493
1746
  } : void 0;
1494
1747
  const webFocusProps = isInteractive ? focusProps : {};
1495
- const textStyle = React13.useMemo(
1748
+ const textStyle = React14.useMemo(
1496
1749
  () => ({
1497
1750
  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
1751
+ fontSize: tokens.typography.fontSizes["05"],
1752
+ fontFamily: tokens.typography.fonts.main.family,
1753
+ lineHeight: tokens.typography.lineHeights["06"]
1501
1754
  }),
1502
1755
  [tokens]
1503
1756
  );
1504
- const wrappedChildren = React13.useMemo(
1757
+ const wrappedChildren = React14.useMemo(
1505
1758
  () => wrapTextChildren(children, textStyle),
1506
1759
  [children, textStyle]
1507
1760
  );
1508
- return /* @__PURE__ */ React13__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1761
+ return /* @__PURE__ */ React14__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1509
1762
  // Pressable handles taps. When href is set, react-native-web renders
1510
1763
  // it as an <a> tag so it works like a regular link on the web.
1511
- /* @__PURE__ */ React13__default.default.createElement(
1764
+ /* @__PURE__ */ React14__default.default.createElement(
1512
1765
  reactNative.Pressable,
1513
1766
  {
1514
1767
  ref,
@@ -1533,7 +1786,7 @@ function Frame({
1533
1786
  )
1534
1787
  ) : (
1535
1788
  // Non-interactive Frame: just a plain View with no tap handling.
1536
- /* @__PURE__ */ React13__default.default.createElement(
1789
+ /* @__PURE__ */ React14__default.default.createElement(
1537
1790
  reactNative.View,
1538
1791
  {
1539
1792
  ref,
@@ -1553,20 +1806,20 @@ function getTextInputStyles(tokens, disabled) {
1553
1806
  gap: tokens.spacing["04"]
1554
1807
  },
1555
1808
  label: {
1556
- fontFamily: tokens.typography.fonts.default,
1557
- fontSize: tokens.typography.size.sm,
1558
- fontWeight: tokens.typography.weight.semibold,
1809
+ fontFamily: tokens.typography.fonts.main.family,
1810
+ fontSize: tokens.typography.fontSizes["04"],
1811
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1559
1812
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
1560
1813
  },
1561
1814
  input: {
1562
- fontFamily: tokens.typography.fonts.default,
1815
+ fontFamily: tokens.typography.fonts.main.family,
1563
1816
  backgroundColor: newtone.srgbToHex(tokens.backgroundSunken.srgb),
1564
1817
  borderWidth: 1,
1565
1818
  borderColor: newtone.srgbToHex(tokens.border.srgb),
1566
1819
  borderRadius: tokens.radius.md,
1567
1820
  paddingVertical: tokens.spacing["08"],
1568
1821
  paddingHorizontal: tokens.spacing["12"],
1569
- fontSize: tokens.typography.size.base,
1822
+ fontSize: tokens.typography.fontSizes["05"],
1570
1823
  color: disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb),
1571
1824
  opacity: disabled ? 0.5 : 1
1572
1825
  }
@@ -1579,11 +1832,11 @@ function TextInput({
1579
1832
  ...textInputProps
1580
1833
  }) {
1581
1834
  const tokens = useTokens(1);
1582
- const styles = React13__default.default.useMemo(
1835
+ const styles = React14__default.default.useMemo(
1583
1836
  () => getTextInputStyles(tokens, disabled),
1584
1837
  [tokens, disabled]
1585
1838
  );
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(
1839
+ 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
1840
  reactNative.TextInput,
1588
1841
  {
1589
1842
  style: styles.input,
@@ -1635,15 +1888,15 @@ function Popover({
1635
1888
  contentStyle
1636
1889
  }) {
1637
1890
  const tokens = useTokens(1);
1638
- const containerRef = React13.useRef(null);
1639
- const [triggerHeight, setTriggerHeight] = React13.useState(0);
1640
- const onTriggerLayout = React13.useCallback(
1891
+ const containerRef = React14.useRef(null);
1892
+ const [triggerHeight, setTriggerHeight] = React14.useState(0);
1893
+ const onTriggerLayout = React14.useCallback(
1641
1894
  (e) => {
1642
1895
  setTriggerHeight(e.nativeEvent.layout.height);
1643
1896
  },
1644
1897
  []
1645
1898
  );
1646
- React13.useEffect(() => {
1899
+ React14.useEffect(() => {
1647
1900
  if (!isOpen) return;
1648
1901
  openPopovers.forEach((closeFn) => closeFn());
1649
1902
  openPopovers.clear();
@@ -1652,7 +1905,7 @@ function Popover({
1652
1905
  openPopovers.delete(onClose);
1653
1906
  };
1654
1907
  }, [isOpen, onClose]);
1655
- React13.useEffect(() => {
1908
+ React14.useEffect(() => {
1656
1909
  if (!isOpen) return;
1657
1910
  if (typeof document === "undefined") return;
1658
1911
  const handleMouseDown = (e) => {
@@ -1664,7 +1917,7 @@ function Popover({
1664
1917
  document.addEventListener("mousedown", handleMouseDown, true);
1665
1918
  return () => document.removeEventListener("mousedown", handleMouseDown, true);
1666
1919
  }, [isOpen, onClose]);
1667
- const handleKeyDown = React13.useCallback(
1920
+ const handleKeyDown = React14.useCallback(
1668
1921
  (e) => {
1669
1922
  if (closeOnEscape && e.key === "Escape") {
1670
1923
  e.stopPropagation();
@@ -1673,41 +1926,41 @@ function Popover({
1673
1926
  },
1674
1927
  [closeOnEscape, onClose]
1675
1928
  );
1676
- const styles = React13.useMemo(
1929
+ const styles = React14.useMemo(
1677
1930
  () => getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpen),
1678
1931
  [tokens, triggerHeight, offset, maxHeight, width, isOpen]
1679
1932
  );
1680
- const containerStyles = React13.useMemo(
1933
+ const containerStyles = React14.useMemo(
1681
1934
  () => [styles.container, ...Array.isArray(style) ? style : style ? [style] : []],
1682
1935
  [styles.container, style]
1683
1936
  );
1684
- const mergedContentStyles = React13.useMemo(
1937
+ const mergedContentStyles = React14.useMemo(
1685
1938
  () => [styles.content, ...Array.isArray(contentStyle) ? contentStyle : contentStyle ? [contentStyle] : []],
1686
1939
  [styles.content, contentStyle]
1687
1940
  );
1688
1941
  const webProps = { onKeyDown: handleKeyDown };
1689
- return /* @__PURE__ */ React13__default.default.createElement(
1942
+ return /* @__PURE__ */ React14__default.default.createElement(
1690
1943
  reactNative.View,
1691
1944
  {
1692
1945
  ref: containerRef,
1693
1946
  style: containerStyles,
1694
1947
  ...webProps
1695
1948
  },
1696
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { onLayout: onTriggerLayout }, trigger),
1697
- isOpen && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: mergedContentStyles }, children)
1949
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { onLayout: onTriggerLayout }, trigger),
1950
+ isOpen && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: mergedContentStyles }, children)
1698
1951
  );
1699
1952
  }
1700
1953
  function usePopover(options) {
1701
- const [isOpen, setIsOpen] = React13.useState(options?.initialOpen ?? false);
1702
- const open = React13.useCallback(() => {
1954
+ const [isOpen, setIsOpen] = React14.useState(options?.initialOpen ?? false);
1955
+ const open = React14.useCallback(() => {
1703
1956
  setIsOpen(true);
1704
1957
  options?.onOpenChange?.(true);
1705
1958
  }, [options]);
1706
- const close = React13.useCallback(() => {
1959
+ const close = React14.useCallback(() => {
1707
1960
  setIsOpen(false);
1708
1961
  options?.onOpenChange?.(false);
1709
1962
  }, [options]);
1710
- const toggle = React13.useCallback(() => {
1963
+ const toggle = React14.useCallback(() => {
1711
1964
  setIsOpen((prev) => {
1712
1965
  const next = !prev;
1713
1966
  options?.onOpenChange?.(next);
@@ -1723,7 +1976,7 @@ function isOptionGroup(item) {
1723
1976
  }
1724
1977
  function getSelectStyles(tokens, disabled, size, isOpen) {
1725
1978
  const isSm = size === "sm";
1726
- const fontSize = isSm ? tokens.typography.size.sm : tokens.typography.size.base;
1979
+ const fontSize = isSm ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
1727
1980
  const iconSize = fontSize + 2;
1728
1981
  const iconSpace = iconSize + tokens.spacing["08"];
1729
1982
  const paddingVertical = isSm ? tokens.spacing["04"] : tokens.spacing["08"];
@@ -1734,9 +1987,9 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1734
1987
  zIndex: isOpen ? 999 : 0
1735
1988
  },
1736
1989
  label: {
1737
- fontFamily: tokens.typography.fonts.default,
1738
- fontSize: tokens.typography.size.sm,
1739
- fontWeight: tokens.typography.weight.semibold,
1990
+ fontFamily: tokens.typography.fonts.main.family,
1991
+ fontSize: tokens.typography.fontSizes["04"],
1992
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1740
1993
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
1741
1994
  },
1742
1995
  trigger: {
@@ -1753,7 +2006,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1753
2006
  },
1754
2007
  triggerText: {
1755
2008
  flex: 1,
1756
- fontFamily: tokens.typography.fonts.default,
2009
+ fontFamily: tokens.typography.fonts.main.family,
1757
2010
  fontSize,
1758
2011
  color: disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb)
1759
2012
  },
@@ -1765,9 +2018,9 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1765
2018
  justifyContent: "center"
1766
2019
  },
1767
2020
  groupLabel: {
1768
- fontFamily: tokens.typography.fonts.default,
1769
- fontSize: tokens.typography.size.xs,
1770
- fontWeight: tokens.typography.weight.semibold,
2021
+ fontFamily: tokens.typography.fonts.main.family,
2022
+ fontSize: tokens.typography.fontSizes["01"],
2023
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1771
2024
  color: newtone.srgbToHex(tokens.textSecondary.srgb),
1772
2025
  textTransform: "uppercase",
1773
2026
  letterSpacing: 0.5,
@@ -1794,10 +2047,10 @@ function useSelect({
1794
2047
  onClose,
1795
2048
  onOpen
1796
2049
  }) {
1797
- const [focusedIndex, setFocusedIndex] = React13.useState(-1);
1798
- const typeAheadRef = React13.useRef("");
1799
- const typeAheadTimerRef = React13.useRef();
1800
- React13.useEffect(() => {
2050
+ const [focusedIndex, setFocusedIndex] = React14.useState(-1);
2051
+ const typeAheadRef = React14.useRef("");
2052
+ const typeAheadTimerRef = React14.useRef();
2053
+ React14.useEffect(() => {
1801
2054
  if (isOpen) {
1802
2055
  const selectedIdx = flatOptions.findIndex((o) => o.value === value);
1803
2056
  if (selectedIdx >= 0 && !flatOptions[selectedIdx].disabled) {
@@ -1810,7 +2063,7 @@ function useSelect({
1810
2063
  setFocusedIndex(-1);
1811
2064
  }
1812
2065
  }, [isOpen, flatOptions, value]);
1813
- const handleKeyDown = React13.useCallback(
2066
+ const handleKeyDown = React14.useCallback(
1814
2067
  (e) => {
1815
2068
  const key = e.key;
1816
2069
  if (!isOpen) {
@@ -1889,9 +2142,9 @@ function SelectOptionRow({
1889
2142
  const tokens = useTokens(1);
1890
2143
  const paddingVertical = size === "sm" ? tokens.spacing["04"] : tokens.spacing["08"];
1891
2144
  const paddingHorizontal = size === "sm" ? tokens.spacing["08"] : tokens.spacing["12"];
1892
- const fontSize = size === "sm" ? tokens.typography.size.sm : tokens.typography.size.base;
2145
+ const fontSize = size === "sm" ? tokens.typography.fontSizes["04"] : tokens.typography.fontSizes["05"];
1893
2146
  if (renderOption) {
1894
- return /* @__PURE__ */ React13__default.default.createElement(
2147
+ return /* @__PURE__ */ React14__default.default.createElement(
1895
2148
  reactNative.Pressable,
1896
2149
  {
1897
2150
  onPress: option.disabled ? void 0 : onSelect,
@@ -1902,7 +2155,7 @@ function SelectOptionRow({
1902
2155
  renderOption(option, { isSelected, isFocused })
1903
2156
  );
1904
2157
  }
1905
- return /* @__PURE__ */ React13__default.default.createElement(
2158
+ return /* @__PURE__ */ React14__default.default.createElement(
1906
2159
  reactNative.Pressable,
1907
2160
  {
1908
2161
  onPress: option.disabled ? void 0 : onSelect,
@@ -1931,18 +2184,18 @@ function SelectOptionRow({
1931
2184
  }
1932
2185
  ]
1933
2186
  },
1934
- /* @__PURE__ */ React13__default.default.createElement(
2187
+ /* @__PURE__ */ React14__default.default.createElement(
1935
2188
  reactNative.Text,
1936
2189
  {
1937
2190
  style: [
1938
2191
  {
1939
2192
  flex: 1,
1940
- fontFamily: tokens.typography.fonts.default,
2193
+ fontFamily: tokens.typography.fonts.main.family,
1941
2194
  fontSize,
1942
2195
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
1943
2196
  },
1944
2197
  isSelected && {
1945
- fontWeight: tokens.typography.weight.semibold,
2198
+ fontWeight: tokens.typography.fonts.main.weights.medium,
1946
2199
  color: newtone.srgbToHex(tokens.accent.fill.srgb)
1947
2200
  },
1948
2201
  option.disabled && {
@@ -1953,7 +2206,7 @@ function SelectOptionRow({
1953
2206
  },
1954
2207
  option.label
1955
2208
  ),
1956
- isSelected && /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React13__default.default.createElement(
2209
+ isSelected && /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React14__default.default.createElement(
1957
2210
  Icon,
1958
2211
  {
1959
2212
  name: "check",
@@ -1988,7 +2241,7 @@ function Select({
1988
2241
  }) {
1989
2242
  const tokens = useTokens(1);
1990
2243
  const { isOpen, open, close, toggle } = usePopover();
1991
- const flatOptions = React13.useMemo(() => flattenOptions(options), [options]);
2244
+ const flatOptions = React14.useMemo(() => flattenOptions(options), [options]);
1992
2245
  const { focusedIndex, handleKeyDown } = useSelect({
1993
2246
  flatOptions,
1994
2247
  value,
@@ -2000,7 +2253,7 @@ function Select({
2000
2253
  onClose: close,
2001
2254
  onOpen: open
2002
2255
  });
2003
- const styles = React13.useMemo(
2256
+ const styles = React14.useMemo(
2004
2257
  () => getSelectStyles(tokens, disabled, size, isOpen),
2005
2258
  [tokens, disabled, size, isOpen]
2006
2259
  );
@@ -2008,7 +2261,7 @@ function Select({
2008
2261
  const displayLabel = selectedOption?.label ?? placeholder ?? value;
2009
2262
  const iconColor = disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb);
2010
2263
  const triggerWebProps = { onKeyDown: handleKeyDown };
2011
- const trigger = /* @__PURE__ */ React13__default.default.createElement(
2264
+ const trigger = /* @__PURE__ */ React14__default.default.createElement(
2012
2265
  reactNative.Pressable,
2013
2266
  {
2014
2267
  onPress: disabled ? void 0 : toggle,
@@ -2018,24 +2271,24 @@ function Select({
2018
2271
  ...triggerWebProps,
2019
2272
  style: styles.trigger
2020
2273
  },
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(
2274
+ renderValue ? renderValue(selectedOption) : /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.triggerText, numberOfLines: 1 }, displayLabel),
2275
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.iconWrapper, pointerEvents: "none" }, /* @__PURE__ */ React14__default.default.createElement(
2023
2276
  Icon,
2024
2277
  {
2025
2278
  name: isOpen ? "expand_less" : "expand_more",
2026
- size: size === "sm" ? tokens.typography.size.sm + 2 : tokens.typography.size.base + 2,
2279
+ size: size === "sm" ? tokens.typography.fontSizes["04"] + 2 : tokens.typography.fontSizes["05"] + 2,
2027
2280
  color: iconColor
2028
2281
  }
2029
2282
  ))
2030
2283
  );
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(
2284
+ 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
2285
  Popover,
2033
2286
  {
2034
2287
  isOpen: isOpen && !disabled,
2035
2288
  onClose: close,
2036
2289
  trigger
2037
2290
  },
2038
- /* @__PURE__ */ React13__default.default.createElement(
2291
+ /* @__PURE__ */ React14__default.default.createElement(
2039
2292
  reactNative.ScrollView,
2040
2293
  {
2041
2294
  bounces: false,
@@ -2044,7 +2297,7 @@ function Select({
2044
2297
  },
2045
2298
  options.map((item) => {
2046
2299
  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(
2300
+ 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
2301
  SelectOptionRow,
2049
2302
  {
2050
2303
  key: opt.value,
@@ -2060,7 +2313,7 @@ function Select({
2060
2313
  }
2061
2314
  )));
2062
2315
  }
2063
- return /* @__PURE__ */ React13__default.default.createElement(
2316
+ return /* @__PURE__ */ React14__default.default.createElement(
2064
2317
  SelectOptionRow,
2065
2318
  {
2066
2319
  key: item.value,
@@ -2092,9 +2345,9 @@ function getToggleStyles(tokens, value, disabled) {
2092
2345
  opacity: disabled ? 0.5 : 1
2093
2346
  },
2094
2347
  label: {
2095
- fontFamily: tokens.typography.fonts.default,
2096
- fontSize: tokens.typography.size.sm,
2097
- fontWeight: tokens.typography.weight.semibold,
2348
+ fontFamily: tokens.typography.fonts.main.family,
2349
+ fontSize: tokens.typography.fontSizes["04"],
2350
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2098
2351
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2099
2352
  },
2100
2353
  track: {
@@ -2124,16 +2377,16 @@ function Toggle({
2124
2377
  style
2125
2378
  }) {
2126
2379
  const tokens = useTokens(1);
2127
- const styles = React13__default.default.useMemo(
2380
+ const styles = React14__default.default.useMemo(
2128
2381
  () => getToggleStyles(tokens, value, disabled),
2129
2382
  [tokens, value, disabled]
2130
2383
  );
2131
- const handlePress = React13__default.default.useCallback(() => {
2384
+ const handlePress = React14__default.default.useCallback(() => {
2132
2385
  if (!disabled) {
2133
2386
  onValueChange(!value);
2134
2387
  }
2135
2388
  }, [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(
2389
+ 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
2390
  reactNative.Pressable,
2138
2391
  {
2139
2392
  onPress: handlePress,
@@ -2141,7 +2394,7 @@ function Toggle({
2141
2394
  accessibilityRole: "switch",
2142
2395
  accessibilityState: { checked: value, disabled }
2143
2396
  },
2144
- /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.track }, /* @__PURE__ */ React13__default.default.createElement(reactNative.View, { style: styles.thumb }))
2397
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.track }, /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.thumb }))
2145
2398
  ));
2146
2399
  }
2147
2400
  var TRACK_HEIGHT2 = 6;
@@ -2158,15 +2411,15 @@ function getSliderStyles(tokens, disabled) {
2158
2411
  alignItems: "center"
2159
2412
  },
2160
2413
  label: {
2161
- fontFamily: tokens.typography.fonts.default,
2162
- fontSize: tokens.typography.size.sm,
2163
- fontWeight: tokens.typography.weight.semibold,
2414
+ fontFamily: tokens.typography.fonts.main.family,
2415
+ fontSize: tokens.typography.fontSizes["04"],
2416
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2164
2417
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2165
2418
  },
2166
2419
  value: {
2167
- fontFamily: tokens.typography.fonts.default,
2168
- fontSize: tokens.typography.size.sm,
2169
- fontWeight: tokens.typography.weight.medium,
2420
+ fontFamily: tokens.typography.fonts.main.family,
2421
+ fontSize: tokens.typography.fontSizes["04"],
2422
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2170
2423
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
2171
2424
  },
2172
2425
  valueInput: {
@@ -2178,9 +2431,9 @@ function getSliderStyles(tokens, disabled) {
2178
2431
  borderRadius: 4,
2179
2432
  backgroundColor: "transparent",
2180
2433
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
2181
- fontFamily: tokens.typography.fonts.default,
2182
- fontSize: tokens.typography.size.sm,
2183
- fontWeight: tokens.typography.weight.medium,
2434
+ fontFamily: tokens.typography.fonts.main.family,
2435
+ fontSize: tokens.typography.fontSizes["04"],
2436
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2184
2437
  textAlign: "right"
2185
2438
  },
2186
2439
  trackContainer: {
@@ -2227,41 +2480,41 @@ function Slider({
2227
2480
  style
2228
2481
  }) {
2229
2482
  const tokens = useTokens(1);
2230
- const styles = React13__default.default.useMemo(
2483
+ const styles = React14__default.default.useMemo(
2231
2484
  () => getSliderStyles(tokens, disabled),
2232
2485
  [tokens, disabled]
2233
2486
  );
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(() => {
2487
+ const trackRef = React14__default.default.useRef(null);
2488
+ const trackWidth = React14__default.default.useRef(0);
2489
+ const trackPageX = React14__default.default.useRef(0);
2490
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2491
+ const minRef = React14__default.default.useRef(min);
2492
+ const maxRef = React14__default.default.useRef(max);
2493
+ const stepRef = React14__default.default.useRef(step);
2494
+ const disabledRef = React14__default.default.useRef(disabled);
2495
+ React14__default.default.useEffect(() => {
2243
2496
  onValueChangeRef.current = onValueChange;
2244
2497
  }, [onValueChange]);
2245
- React13__default.default.useEffect(() => {
2498
+ React14__default.default.useEffect(() => {
2246
2499
  minRef.current = min;
2247
2500
  }, [min]);
2248
- React13__default.default.useEffect(() => {
2501
+ React14__default.default.useEffect(() => {
2249
2502
  maxRef.current = max;
2250
2503
  }, [max]);
2251
- React13__default.default.useEffect(() => {
2504
+ React14__default.default.useEffect(() => {
2252
2505
  stepRef.current = step;
2253
2506
  }, [step]);
2254
- React13__default.default.useEffect(() => {
2507
+ React14__default.default.useEffect(() => {
2255
2508
  disabledRef.current = disabled;
2256
2509
  }, [disabled]);
2257
- const computeValue = React13__default.default.useCallback((pageX) => {
2510
+ const computeValue = React14__default.default.useCallback((pageX) => {
2258
2511
  const localX = pageX - trackPageX.current;
2259
2512
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2260
2513
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2261
2514
  const stepped = Math.round(raw / stepRef.current) * stepRef.current;
2262
2515
  return Math.min(maxRef.current, Math.max(minRef.current, stepped));
2263
2516
  }, []);
2264
- const panResponder = React13__default.default.useRef(
2517
+ const panResponder = React14__default.default.useRef(
2265
2518
  reactNative.PanResponder.create({
2266
2519
  onStartShouldSetPanResponder: () => !disabledRef.current,
2267
2520
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2277,7 +2530,7 @@ function Slider({
2277
2530
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE2);
2278
2531
  const thumbLeft = ratio * usableWidth;
2279
2532
  const fillWidth = thumbLeft + THUMB_SIZE2 / 2;
2280
- const handleValueTextSubmit = React13__default.default.useCallback(
2533
+ const handleValueTextSubmit = React14__default.default.useCallback(
2281
2534
  (text) => {
2282
2535
  const raw = Number(text);
2283
2536
  if (!Number.isNaN(raw)) {
@@ -2286,12 +2539,12 @@ function Slider({
2286
2539
  },
2287
2540
  [onValueChange, min, max]
2288
2541
  );
2289
- const [editText, setEditText] = React13__default.default.useState(String(value));
2290
- React13__default.default.useEffect(() => {
2542
+ const [editText, setEditText] = React14__default.default.useState(String(value));
2543
+ React14__default.default.useEffect(() => {
2291
2544
  setEditText(String(value));
2292
2545
  }, [value]);
2293
2546
  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(
2547
+ 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
2548
  reactNative.TextInput,
2296
2549
  {
2297
2550
  style: styles.valueInput,
@@ -2303,7 +2556,7 @@ function Slider({
2303
2556
  selectTextOnFocus: true,
2304
2557
  editable: !disabled
2305
2558
  }
2306
- ) : showValue && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.value }, value)), /* @__PURE__ */ React13__default.default.createElement(
2559
+ ) : showValue && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.value }, value)), /* @__PURE__ */ React14__default.default.createElement(
2307
2560
  reactNative.View,
2308
2561
  {
2309
2562
  ref: trackRef,
@@ -2316,9 +2569,9 @@ function Slider({
2316
2569
  },
2317
2570
  ...panResponder.panHandlers
2318
2571
  },
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 }] })
2572
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.trackRail }),
2573
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.trackFill, { width: fillWidth }] }),
2574
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2322
2575
  ));
2323
2576
  }
2324
2577
  var TRACK_HEIGHT3 = 22;
@@ -2374,15 +2627,15 @@ function getHueSliderStyles(tokens, disabled) {
2374
2627
  alignItems: "center"
2375
2628
  },
2376
2629
  label: {
2377
- fontFamily: tokens.typography.fonts.default,
2378
- fontSize: tokens.typography.size.sm,
2379
- fontWeight: tokens.typography.weight.semibold,
2630
+ fontFamily: tokens.typography.fonts.main.family,
2631
+ fontSize: tokens.typography.fontSizes["04"],
2632
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2380
2633
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2381
2634
  },
2382
2635
  value: {
2383
- fontFamily: tokens.typography.fonts.default,
2384
- fontSize: tokens.typography.size.sm,
2385
- fontWeight: tokens.typography.weight.medium,
2636
+ fontFamily: tokens.typography.fonts.main.family,
2637
+ fontSize: tokens.typography.fontSizes["04"],
2638
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2386
2639
  color: newtone.srgbToHex(tokens.textPrimary.srgb)
2387
2640
  },
2388
2641
  valueInput: {
@@ -2394,9 +2647,9 @@ function getHueSliderStyles(tokens, disabled) {
2394
2647
  borderRadius: 4,
2395
2648
  backgroundColor: "transparent",
2396
2649
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
2397
- fontFamily: tokens.typography.fonts.default,
2398
- fontSize: tokens.typography.size.sm,
2399
- fontWeight: tokens.typography.weight.medium,
2650
+ fontFamily: tokens.typography.fonts.main.family,
2651
+ fontSize: tokens.typography.fontSizes["04"],
2652
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2400
2653
  textAlign: "right"
2401
2654
  },
2402
2655
  trackContainer: {
@@ -2441,41 +2694,41 @@ function HueSlider({
2441
2694
  style
2442
2695
  }) {
2443
2696
  const tokens = useTokens(1);
2444
- const styles = React13__default.default.useMemo(
2697
+ const styles = React14__default.default.useMemo(
2445
2698
  () => getHueSliderStyles(tokens, disabled),
2446
2699
  [tokens, disabled]
2447
2700
  );
2448
- const segments = React13__default.default.useMemo(
2701
+ const segments = React14__default.default.useMemo(
2449
2702
  () => buildHueSegments(min, max),
2450
2703
  [min, max]
2451
2704
  );
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(() => {
2705
+ const trackRef = React14__default.default.useRef(null);
2706
+ const trackWidth = React14__default.default.useRef(0);
2707
+ const trackPageX = React14__default.default.useRef(0);
2708
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2709
+ const minRef = React14__default.default.useRef(min);
2710
+ const maxRef = React14__default.default.useRef(max);
2711
+ const disabledRef = React14__default.default.useRef(disabled);
2712
+ React14__default.default.useEffect(() => {
2460
2713
  onValueChangeRef.current = onValueChange;
2461
2714
  }, [onValueChange]);
2462
- React13__default.default.useEffect(() => {
2715
+ React14__default.default.useEffect(() => {
2463
2716
  minRef.current = min;
2464
2717
  }, [min]);
2465
- React13__default.default.useEffect(() => {
2718
+ React14__default.default.useEffect(() => {
2466
2719
  maxRef.current = max;
2467
2720
  }, [max]);
2468
- React13__default.default.useEffect(() => {
2721
+ React14__default.default.useEffect(() => {
2469
2722
  disabledRef.current = disabled;
2470
2723
  }, [disabled]);
2471
- const computeHue = React13__default.default.useCallback((pageX) => {
2724
+ const computeHue = React14__default.default.useCallback((pageX) => {
2472
2725
  const localX = pageX - trackPageX.current;
2473
2726
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2474
2727
  const raw = minRef.current + ratio2 * (maxRef.current - minRef.current);
2475
2728
  const stepped = Math.round(raw);
2476
2729
  return (stepped % 360 + 360) % 360;
2477
2730
  }, []);
2478
- const panResponder = React13__default.default.useRef(
2731
+ const panResponder = React14__default.default.useRef(
2479
2732
  reactNative.PanResponder.create({
2480
2733
  onStartShouldSetPanResponder: () => !disabledRef.current,
2481
2734
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2491,7 +2744,7 @@ function HueSlider({
2491
2744
  const ratio = max > min ? (sliderValue - min) / (max - min) : 0;
2492
2745
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE3);
2493
2746
  const thumbLeft = ratio * usableWidth;
2494
- const handleValueTextSubmit = React13__default.default.useCallback(
2747
+ const handleValueTextSubmit = React14__default.default.useCallback(
2495
2748
  (text) => {
2496
2749
  const raw = Number(text);
2497
2750
  if (!Number.isNaN(raw)) {
@@ -2500,12 +2753,12 @@ function HueSlider({
2500
2753
  },
2501
2754
  [onValueChange]
2502
2755
  );
2503
- const [editText, setEditText] = React13__default.default.useState(String(value));
2504
- React13__default.default.useEffect(() => {
2756
+ const [editText, setEditText] = React14__default.default.useState(String(value));
2757
+ React14__default.default.useEffect(() => {
2505
2758
  setEditText(String(value));
2506
2759
  }, [value]);
2507
2760
  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(
2761
+ 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
2762
  reactNative.TextInput,
2510
2763
  {
2511
2764
  style: styles.valueInput,
@@ -2517,7 +2770,7 @@ function HueSlider({
2517
2770
  selectTextOnFocus: true,
2518
2771
  editable: !disabled
2519
2772
  }
2520
- ) : showValue && /* @__PURE__ */ React13__default.default.createElement(reactNative.Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React13__default.default.createElement(
2773
+ ) : showValue && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.value }, value, "\xB0")), /* @__PURE__ */ React14__default.default.createElement(
2521
2774
  reactNative.View,
2522
2775
  {
2523
2776
  ref: trackRef,
@@ -2530,8 +2783,8 @@ function HueSlider({
2530
2783
  },
2531
2784
  ...panResponder.panHandlers
2532
2785
  },
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 }] })
2786
+ /* @__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 }] }))),
2787
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: [styles.thumb, { left: thumbLeft }] })
2535
2788
  ));
2536
2789
  }
2537
2790
  var TRACK_HEIGHT4 = 22;
@@ -2548,9 +2801,9 @@ function getColorScaleSliderStyles(tokens, disabled) {
2548
2801
  alignItems: "center"
2549
2802
  },
2550
2803
  label: {
2551
- fontFamily: tokens.typography.fonts.default,
2552
- fontSize: tokens.typography.size.sm,
2553
- fontWeight: tokens.typography.weight.semibold,
2804
+ fontFamily: tokens.typography.fonts.main.family,
2805
+ fontSize: tokens.typography.fontSizes["04"],
2806
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2554
2807
  color: newtone.srgbToHex(tokens.textSecondary.srgb)
2555
2808
  },
2556
2809
  trackContainer: {
@@ -2580,9 +2833,9 @@ function getColorScaleSliderStyles(tokens, disabled) {
2580
2833
  borderColor: newtone.srgbToHex(tokens.border.srgb)
2581
2834
  },
2582
2835
  warning: {
2583
- fontFamily: tokens.typography.fonts.default,
2584
- fontSize: tokens.typography.size.xs,
2585
- fontWeight: tokens.typography.weight.medium,
2836
+ fontFamily: tokens.typography.fonts.main.family,
2837
+ fontSize: tokens.typography.fontSizes["01"],
2838
+ fontWeight: tokens.typography.fonts.main.weights.medium,
2586
2839
  color: newtone.srgbToHex(tokens.error.fill.srgb)
2587
2840
  }
2588
2841
  });
@@ -2602,36 +2855,36 @@ function ColorScaleSlider({
2602
2855
  style
2603
2856
  }) {
2604
2857
  const tokens = useTokens(1);
2605
- const styles = React13__default.default.useMemo(
2858
+ const styles = React14__default.default.useMemo(
2606
2859
  () => getColorScaleSliderStyles(tokens, disabled),
2607
2860
  [tokens, disabled]
2608
2861
  );
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(() => {
2862
+ const trackRef = React14__default.default.useRef(null);
2863
+ const trackWidth = React14__default.default.useRef(0);
2864
+ const trackPageX = React14__default.default.useRef(0);
2865
+ const isDragging = React14__default.default.useRef(false);
2866
+ const thumbAnim = React14__default.default.useRef(new reactNative.Animated.Value(0)).current;
2867
+ const onValueChangeRef = React14__default.default.useRef(onValueChange);
2868
+ const disabledRef = React14__default.default.useRef(disabled);
2869
+ const colorsLengthRef = React14__default.default.useRef(colors.length);
2870
+ const trimEndsRef = React14__default.default.useRef(trimEnds);
2871
+ const snapRef = React14__default.default.useRef(snap);
2872
+ React14__default.default.useEffect(() => {
2620
2873
  onValueChangeRef.current = onValueChange;
2621
2874
  }, [onValueChange]);
2622
- React13__default.default.useEffect(() => {
2875
+ React14__default.default.useEffect(() => {
2623
2876
  disabledRef.current = disabled;
2624
2877
  }, [disabled]);
2625
- React13__default.default.useEffect(() => {
2878
+ React14__default.default.useEffect(() => {
2626
2879
  colorsLengthRef.current = colors.length;
2627
2880
  }, [colors.length]);
2628
- React13__default.default.useEffect(() => {
2881
+ React14__default.default.useEffect(() => {
2629
2882
  trimEndsRef.current = trimEnds;
2630
2883
  }, [trimEnds]);
2631
- React13__default.default.useEffect(() => {
2884
+ React14__default.default.useEffect(() => {
2632
2885
  snapRef.current = snap;
2633
2886
  }, [snap]);
2634
- const computeNv = React13__default.default.useCallback((pageX) => {
2887
+ const computeNv = React14__default.default.useCallback((pageX) => {
2635
2888
  const localX = pageX - trackPageX.current;
2636
2889
  const ratio2 = Math.min(1, Math.max(0, localX / trackWidth.current));
2637
2890
  const totalSteps2 = colorsLengthRef.current - 1;
@@ -2646,7 +2899,7 @@ function ColorScaleSlider({
2646
2899
  }
2647
2900
  return nv;
2648
2901
  }, []);
2649
- const panResponder = React13__default.default.useRef(
2902
+ const panResponder = React14__default.default.useRef(
2650
2903
  reactNative.PanResponder.create({
2651
2904
  onStartShouldSetPanResponder: () => !disabledRef.current,
2652
2905
  onMoveShouldSetPanResponder: () => !disabledRef.current,
@@ -2674,7 +2927,7 @@ function ColorScaleSlider({
2674
2927
  const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
2675
2928
  const usableWidth = Math.max(0, trackWidth.current - THUMB_SIZE4);
2676
2929
  const thumbLeft = ratio * usableWidth;
2677
- React13__default.default.useEffect(() => {
2930
+ React14__default.default.useEffect(() => {
2678
2931
  if (isDragging.current || !animateValue) {
2679
2932
  thumbAnim.setValue(thumbLeft);
2680
2933
  } else {
@@ -2685,7 +2938,7 @@ function ColorScaleSlider({
2685
2938
  }).start();
2686
2939
  }
2687
2940
  }, [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(
2941
+ 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
2942
  reactNative.View,
2690
2943
  {
2691
2944
  ref: trackRef,
@@ -2700,9 +2953,9 @@ function ColorScaleSlider({
2700
2953
  },
2701
2954
  ...panResponder.panHandlers
2702
2955
  },
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));
2956
+ /* @__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) }] }))),
2957
+ /* @__PURE__ */ React14__default.default.createElement(reactNative.Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2958
+ ), warning && /* @__PURE__ */ React14__default.default.createElement(reactNative.Text, { style: styles.warning }, warning));
2706
2959
  }
2707
2960
  function getAppShellStyles(tokens) {
2708
2961
  return reactNative.StyleSheet.create({
@@ -2724,8 +2977,8 @@ function getAppShellStyles(tokens) {
2724
2977
  // src/composites/layout/AppShell/AppShell.tsx
2725
2978
  function AppShell({ sidebar, children }) {
2726
2979
  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));
2980
+ const styles = React14__default.default.useMemo(() => getAppShellStyles(tokens), [tokens]);
2981
+ return /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.container }, sidebar, /* @__PURE__ */ React14__default.default.createElement(reactNative.View, { style: styles.main }, children));
2729
2982
  }
2730
2983
  function getSidebarStyles({ tokens, width, bordered }) {
2731
2984
  const borderColor = newtone.srgbToHex(tokens.border.srgb);
@@ -2763,11 +3016,11 @@ function Sidebar({
2763
3016
  bordered = true
2764
3017
  }) {
2765
3018
  const tokens = useTokens();
2766
- const styles = React13__default.default.useMemo(
3019
+ const styles = React14__default.default.useMemo(
2767
3020
  () => getSidebarStyles({ tokens, width, bordered }),
2768
3021
  [tokens, width, bordered]
2769
3022
  );
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));
3023
+ 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
3024
  }
2772
3025
  function getNavbarStyles({ tokens, height, bordered }) {
2773
3026
  const borderColor = newtone.srgbToHex(tokens.border.srgb);
@@ -2805,28 +3058,27 @@ function Navbar({
2805
3058
  bordered = true
2806
3059
  }) {
2807
3060
  const tokens = useTokens();
2808
- const styles = React13__default.default.useMemo(
3061
+ const styles = React14__default.default.useMemo(
2809
3062
  () => getNavbarStyles({ tokens, height, bordered }),
2810
3063
  [tokens, height, bordered]
2811
3064
  );
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)));
3065
+ 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
3066
  }
2814
3067
 
2815
3068
  // src/registry/registry.ts
2816
3069
  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" }
3070
+ { id: "colors", name: "Colors", description: "Color palettes and token visualization", icon: "palette" },
3071
+ { id: "typography", name: "Typography", description: "Text roles, scopes, and weight control", icon: "text_fields" },
3072
+ { id: "symbols", name: "Symbols", description: "Material Symbols icon browser", icon: "grid_view" },
3073
+ { id: "layout", name: "Layout", description: "Structural containers \u2014 Frame and Wrapper", icon: "grid_on" },
3074
+ { id: "components", name: "Components", description: "Interactive UI components", icon: "widgets" }
2823
3075
  ];
2824
3076
  var COMPONENTS = [
2825
3077
  {
2826
3078
  id: "button",
2827
3079
  name: "Button",
2828
3080
  importName: "Button",
2829
- categoryId: "actions",
3081
+ categoryId: "components",
2830
3082
  description: "Interactive button with multiple variants, sizes, and optional icon",
2831
3083
  hasChildren: true,
2832
3084
  variants: [
@@ -2908,7 +3160,7 @@ var COMPONENTS = [
2908
3160
  id: "text-input",
2909
3161
  name: "TextInput",
2910
3162
  importName: "TextInput",
2911
- categoryId: "form-controls",
3163
+ categoryId: "components",
2912
3164
  description: "Text input field with label support",
2913
3165
  hasChildren: false,
2914
3166
  variants: [
@@ -2935,7 +3187,7 @@ var COMPONENTS = [
2935
3187
  id: "select",
2936
3188
  name: "Select",
2937
3189
  importName: "Select",
2938
- categoryId: "form-controls",
3190
+ categoryId: "components",
2939
3191
  description: "Dropdown selector with options",
2940
3192
  hasChildren: false,
2941
3193
  variants: [
@@ -2982,7 +3234,7 @@ var COMPONENTS = [
2982
3234
  id: "toggle",
2983
3235
  name: "Toggle",
2984
3236
  importName: "Toggle",
2985
- categoryId: "form-controls",
3237
+ categoryId: "components",
2986
3238
  description: "Binary switch component",
2987
3239
  hasChildren: false,
2988
3240
  variants: [
@@ -3009,7 +3261,7 @@ var COMPONENTS = [
3009
3261
  id: "slider",
3010
3262
  name: "Slider",
3011
3263
  importName: "Slider",
3012
- categoryId: "range-inputs",
3264
+ categoryId: "components",
3013
3265
  description: "Numeric range slider",
3014
3266
  hasChildren: false,
3015
3267
  variants: [
@@ -3053,7 +3305,7 @@ var COMPONENTS = [
3053
3305
  id: "hue-slider",
3054
3306
  name: "HueSlider",
3055
3307
  importName: "HueSlider",
3056
- categoryId: "range-inputs",
3308
+ categoryId: "components",
3057
3309
  description: "Specialized slider for hue selection (0-360\xB0)",
3058
3310
  hasChildren: false,
3059
3311
  variants: [
@@ -3189,7 +3441,7 @@ var COMPONENTS = [
3189
3441
  id: "card",
3190
3442
  name: "Card",
3191
3443
  importName: "Card",
3192
- categoryId: "layout",
3444
+ categoryId: "components",
3193
3445
  description: "Surface container with elevation levels",
3194
3446
  hasChildren: true,
3195
3447
  variants: [
@@ -3222,45 +3474,59 @@ var COMPONENTS = [
3222
3474
  id: "text",
3223
3475
  name: "Text",
3224
3476
  importName: "Text",
3225
- categoryId: "primitives",
3226
- description: "Typography primitive with semantic size, weight, color, font, and lineHeight",
3477
+ categoryId: "typography",
3478
+ description: "Typography primitive with semantic scope (font family) and role (purpose)",
3227
3479
  hasChildren: true,
3480
+ previewLayout: "list",
3228
3481
  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" } }
3482
+ { id: "body", label: "Body", props: { role: "body" } },
3483
+ { id: "headline", label: "Headline", props: { role: "headline", scope: "display" } },
3484
+ { id: "title", label: "Title", props: { role: "title", scope: "display" } },
3485
+ { id: "heading", label: "Heading", props: { role: "heading" } },
3486
+ { id: "subheading", label: "Subheading", props: { role: "subheading" } },
3487
+ { id: "label", label: "Label", props: { role: "label" } },
3488
+ { id: "caption", label: "Caption", props: { role: "caption", color: "secondary" } },
3489
+ { id: "mono", label: "Monospace", props: { scope: "mono", role: "body" } },
3490
+ { id: "currency", label: "Currency", props: { scope: "currency", role: "body" } }
3236
3491
  ],
3237
3492
  editableProps: [
3238
3493
  {
3239
- name: "size",
3240
- label: "Size",
3494
+ name: "scope",
3495
+ label: "Scope",
3241
3496
  control: "select",
3242
3497
  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" }
3498
+ { label: "Main", value: "main" },
3499
+ { label: "Display", value: "display" },
3500
+ { label: "Mono", value: "mono" },
3501
+ { label: "Currency", value: "currency" }
3250
3502
  ],
3251
- defaultValue: "base"
3503
+ defaultValue: "main"
3252
3504
  },
3253
3505
  {
3254
- name: "weight",
3255
- label: "Weight",
3506
+ name: "role",
3507
+ label: "Role",
3508
+ control: "select",
3509
+ options: [
3510
+ { label: "Headline", value: "headline" },
3511
+ { label: "Title", value: "title" },
3512
+ { label: "Heading", value: "heading" },
3513
+ { label: "Subheading", value: "subheading" },
3514
+ { label: "Body", value: "body" },
3515
+ { label: "Label", value: "label" },
3516
+ { label: "Caption", value: "caption" }
3517
+ ],
3518
+ defaultValue: "body"
3519
+ },
3520
+ {
3521
+ name: "size",
3522
+ label: "Size",
3256
3523
  control: "select",
3257
3524
  options: [
3258
- { label: "Regular", value: "regular" },
3259
- { label: "Medium", value: "medium" },
3260
- { label: "Semibold", value: "semibold" },
3261
- { label: "Bold", value: "bold" }
3525
+ { label: "Small", value: "sm" },
3526
+ { label: "Medium", value: "md" },
3527
+ { label: "Large", value: "lg" }
3262
3528
  ],
3263
- defaultValue: "regular"
3529
+ defaultValue: "md"
3264
3530
  },
3265
3531
  {
3266
3532
  name: "color",
@@ -3277,17 +3543,6 @@ var COMPONENTS = [
3277
3543
  { label: "Error", value: "error" }
3278
3544
  ],
3279
3545
  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
3546
  }
3292
3547
  ]
3293
3548
  },
@@ -3295,7 +3550,7 @@ var COMPONENTS = [
3295
3550
  id: "icon",
3296
3551
  name: "Icon",
3297
3552
  importName: "Icon",
3298
- categoryId: "primitives",
3553
+ categoryId: "symbols",
3299
3554
  description: "Material Symbols icon with size and fill",
3300
3555
  hasChildren: false,
3301
3556
  variants: [
@@ -3332,7 +3587,7 @@ var COMPONENTS = [
3332
3587
  id: "wrapper",
3333
3588
  name: "Wrapper",
3334
3589
  importName: "Wrapper",
3335
- categoryId: "primitives",
3590
+ categoryId: "layout",
3336
3591
  description: "Lightweight layout container with direction, spacing, and alignment (no theming)",
3337
3592
  hasChildren: true,
3338
3593
  variants: [
@@ -3406,7 +3661,7 @@ var COMPONENTS = [
3406
3661
  id: "color-scale-slider",
3407
3662
  name: "ColorScaleSlider",
3408
3663
  importName: "ColorScaleSlider",
3409
- categoryId: "range-inputs",
3664
+ categoryId: "components",
3410
3665
  description: "Interactive palette preview slider with color segments",
3411
3666
  hasChildren: false,
3412
3667
  variants: [
@@ -3449,6 +3704,7 @@ var HANDLER_PROPS = {
3449
3704
  };
3450
3705
  var CHILDREN_CONTENT = {
3451
3706
  button: "Button",
3707
+ text: "The quick brown fox",
3452
3708
  card: "{/* content */}",
3453
3709
  frame: "{/* content */}"
3454
3710
  };
@@ -3754,72 +4010,22 @@ var ICON_CATALOG = [
3754
4010
  }
3755
4011
  ];
3756
4012
 
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
-
4013
+ Object.defineProperty(exports, "DEFAULT_FONT_SIZES", {
4014
+ enumerable: true,
4015
+ get: function () { return fonts.DEFAULT_FONT_SIZES; }
4016
+ });
4017
+ Object.defineProperty(exports, "DEFAULT_LINE_HEIGHTS", {
4018
+ enumerable: true,
4019
+ get: function () { return fonts.DEFAULT_LINE_HEIGHTS; }
4020
+ });
4021
+ Object.defineProperty(exports, "DEFAULT_ROLE_SCALES", {
4022
+ enumerable: true,
4023
+ get: function () { return fonts.DEFAULT_ROLE_SCALES; }
4024
+ });
4025
+ Object.defineProperty(exports, "buildGoogleFontsUrl", {
4026
+ enumerable: true,
4027
+ get: function () { return fonts.buildGoogleFontsUrl; }
4028
+ });
3823
4029
  exports.ACCENT_DEFAULTS = ACCENT_DEFAULTS;
3824
4030
  exports.AppShell = AppShell;
3825
4031
  exports.Button = Button;
@@ -3830,7 +4036,6 @@ exports.ColorScaleSlider = ColorScaleSlider;
3830
4036
  exports.DEFAULT_THEME_CONFIG = DEFAULT_THEME_CONFIG;
3831
4037
  exports.ERROR_DEFAULTS = ERROR_DEFAULTS;
3832
4038
  exports.Frame = Frame;
3833
- exports.GOOGLE_FONTS = GOOGLE_FONTS;
3834
4039
  exports.HueSlider = HueSlider;
3835
4040
  exports.ICON_CATALOG = ICON_CATALOG;
3836
4041
  exports.Icon = Icon;
@@ -3839,7 +4044,6 @@ exports.Navbar = Navbar;
3839
4044
  exports.NewtoneProvider = NewtoneProvider;
3840
4045
  exports.Popover = Popover;
3841
4046
  exports.SUCCESS_DEFAULTS = SUCCESS_DEFAULTS;
3842
- exports.SYSTEM_FONTS = SYSTEM_FONTS;
3843
4047
  exports.Select = Select;
3844
4048
  exports.Sidebar = Sidebar;
3845
4049
  exports.Slider = Slider;
@@ -3848,17 +4052,19 @@ exports.TextInput = TextInput;
3848
4052
  exports.Toggle = Toggle;
3849
4053
  exports.WARNING_DEFAULTS = WARNING_DEFAULTS;
3850
4054
  exports.Wrapper = Wrapper;
3851
- exports.buildGoogleFontsUrl = buildGoogleFontsUrl;
3852
4055
  exports.computeTokens = computeTokens;
3853
4056
  exports.generateComponentCode = generateComponentCode;
3854
4057
  exports.getCategory = getCategory;
3855
4058
  exports.getComponent = getComponent;
3856
4059
  exports.getComponentsByCategory = getComponentsByCategory;
3857
4060
  exports.isOptionGroup = isOptionGroup;
4061
+ exports.measureAvgCharWidth = measureAvgCharWidth;
3858
4062
  exports.useFocusVisible = useFocusVisible;
3859
4063
  exports.useFrameContext = useFrameContext;
4064
+ exports.useLocalCalibration = useLocalCalibration;
3860
4065
  exports.useNewtoneTheme = useNewtoneTheme;
3861
4066
  exports.usePopover = usePopover;
3862
4067
  exports.useTokens = useTokens;
4068
+ exports.useTypographyCalibrations = useTypographyCalibrations;
3863
4069
  //# sourceMappingURL=index.cjs.map
3864
4070
  //# sourceMappingURL=index.cjs.map