@newtonedev/components 0.1.2 → 0.1.3

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 (113) hide show
  1. package/dist/Popover/Popover.d.ts.map +1 -1
  2. package/dist/Popover/Popover.styles.d.ts +64 -1
  3. package/dist/Popover/Popover.styles.d.ts.map +1 -1
  4. package/dist/Select/Select.d.ts.map +1 -1
  5. package/dist/_COMPONENT_TEMPLATE/ComponentName.d.ts +70 -0
  6. package/dist/_COMPONENT_TEMPLATE/ComponentName.d.ts.map +1 -0
  7. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts +22 -0
  8. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts.map +1 -0
  9. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts +45 -0
  10. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts.map +1 -0
  11. package/dist/_COMPONENT_TEMPLATE/index.d.ts +3 -0
  12. package/dist/_COMPONENT_TEMPLATE/index.d.ts.map +1 -0
  13. package/dist/fonts/GoogleFontLoader.d.ts.map +1 -1
  14. package/dist/fonts/IconFontLoader.d.ts.map +1 -1
  15. package/dist/index.cjs +371 -74
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +11 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +370 -76
  20. package/dist/index.js.map +1 -1
  21. package/dist/{Frame → primitives/Frame}/Frame.d.ts +1 -1
  22. package/dist/primitives/Frame/Frame.d.ts.map +1 -0
  23. package/dist/{Frame → primitives/Frame}/Frame.styles.d.ts +11 -2
  24. package/dist/primitives/Frame/Frame.styles.d.ts.map +1 -0
  25. package/dist/primitives/Frame/Frame.types.d.ts +240 -0
  26. package/dist/primitives/Frame/Frame.types.d.ts.map +1 -0
  27. package/dist/{Frame → primitives/Frame}/Frame.utils.d.ts +12 -12
  28. package/dist/primitives/Frame/Frame.utils.d.ts.map +1 -0
  29. package/dist/primitives/Frame/index.d.ts.map +1 -0
  30. package/dist/primitives/Icon/Icon.d.ts +17 -0
  31. package/dist/primitives/Icon/Icon.d.ts.map +1 -0
  32. package/dist/primitives/Icon/Icon.types.d.ts +55 -0
  33. package/dist/primitives/Icon/Icon.types.d.ts.map +1 -0
  34. package/dist/primitives/Icon/index.d.ts +3 -0
  35. package/dist/primitives/Icon/index.d.ts.map +1 -0
  36. package/dist/primitives/Text/Text.d.ts +17 -0
  37. package/dist/primitives/Text/Text.d.ts.map +1 -0
  38. package/dist/primitives/Text/Text.types.d.ts +85 -0
  39. package/dist/primitives/Text/Text.types.d.ts.map +1 -0
  40. package/dist/primitives/Text/index.d.ts +3 -0
  41. package/dist/primitives/Text/index.d.ts.map +1 -0
  42. package/dist/primitives/Wrapper/Wrapper.d.ts +29 -0
  43. package/dist/primitives/Wrapper/Wrapper.d.ts.map +1 -0
  44. package/dist/primitives/Wrapper/Wrapper.styles.d.ts +28 -0
  45. package/dist/primitives/Wrapper/Wrapper.styles.d.ts.map +1 -0
  46. package/dist/primitives/Wrapper/Wrapper.types.d.ts +113 -0
  47. package/dist/primitives/Wrapper/Wrapper.types.d.ts.map +1 -0
  48. package/dist/primitives/Wrapper/index.d.ts +3 -0
  49. package/dist/primitives/Wrapper/index.d.ts.map +1 -0
  50. package/dist/primitives/index.d.ts +12 -0
  51. package/dist/primitives/index.d.ts.map +1 -0
  52. package/dist/primitives/useFocusVisible.d.ts +29 -0
  53. package/dist/primitives/useFocusVisible.d.ts.map +1 -0
  54. package/dist/theme/defaults.d.ts.map +1 -1
  55. package/dist/theme/types.d.ts +13 -6
  56. package/dist/theme/types.d.ts.map +1 -1
  57. package/dist/tokens/computeTokens.d.ts +13 -6
  58. package/dist/tokens/computeTokens.d.ts.map +1 -1
  59. package/dist/tokens/types.d.ts +16 -7
  60. package/dist/tokens/types.d.ts.map +1 -1
  61. package/package.json +1 -1
  62. package/src/Button/Button.styles.ts +9 -9
  63. package/src/Button/Button.tsx +1 -1
  64. package/src/Card/Card.styles.ts +1 -1
  65. package/src/ColorScaleSlider/ColorScaleSlider.styles.ts +1 -1
  66. package/src/HueSlider/HueSlider.styles.ts +1 -1
  67. package/src/Popover/Popover.styles.ts +5 -1
  68. package/src/Popover/Popover.tsx +3 -1
  69. package/src/Select/Select.styles.ts +9 -9
  70. package/src/Select/Select.tsx +2 -3
  71. package/src/Select/SelectOption.tsx +6 -6
  72. package/src/Slider/Slider.styles.ts +1 -1
  73. package/src/TextInput/TextInput.styles.ts +3 -3
  74. package/src/Toggle/Toggle.styles.ts +1 -1
  75. package/src/_COMPONENT_TEMPLATE/ComponentName.styles.ts +29 -0
  76. package/src/_COMPONENT_TEMPLATE/ComponentName.tsx +106 -0
  77. package/src/_COMPONENT_TEMPLATE/ComponentName.types.ts +86 -0
  78. package/src/_COMPONENT_TEMPLATE/index.ts +2 -0
  79. package/src/fonts/GoogleFontLoader.tsx +2 -0
  80. package/src/fonts/IconFontLoader.tsx +2 -0
  81. package/src/index.ts +22 -5
  82. package/src/{Frame → primitives/Frame}/Frame.styles.ts +46 -9
  83. package/src/{Frame → primitives/Frame}/Frame.tsx +90 -16
  84. package/src/primitives/Frame/Frame.types.ts +315 -0
  85. package/src/{Frame → primitives/Frame}/Frame.utils.ts +56 -20
  86. package/src/primitives/Icon/Icon.tsx +89 -0
  87. package/src/primitives/Icon/Icon.types.ts +70 -0
  88. package/src/primitives/Icon/index.ts +2 -0
  89. package/src/primitives/Text/Text.tsx +90 -0
  90. package/src/primitives/Text/Text.types.ts +108 -0
  91. package/src/primitives/Text/index.ts +10 -0
  92. package/src/primitives/Wrapper/Wrapper.styles.ts +113 -0
  93. package/src/primitives/Wrapper/Wrapper.tsx +104 -0
  94. package/src/primitives/Wrapper/Wrapper.types.ts +149 -0
  95. package/src/primitives/Wrapper/index.ts +2 -0
  96. package/src/primitives/index.ts +46 -0
  97. package/src/primitives/useFocusVisible.ts +102 -0
  98. package/src/theme/defaults.ts +13 -6
  99. package/src/theme/types.ts +13 -6
  100. package/src/tokens/computeTokens.ts +1 -1
  101. package/src/tokens/types.ts +16 -7
  102. package/dist/Frame/Frame.d.ts.map +0 -1
  103. package/dist/Frame/Frame.styles.d.ts.map +0 -1
  104. package/dist/Frame/Frame.types.d.ts +0 -115
  105. package/dist/Frame/Frame.types.d.ts.map +0 -1
  106. package/dist/Frame/Frame.utils.d.ts.map +0 -1
  107. package/dist/Frame/index.d.ts.map +0 -1
  108. package/dist/Icon/Icon.d.ts +0 -36
  109. package/dist/Icon/Icon.d.ts.map +0 -1
  110. package/src/Frame/Frame.types.ts +0 -181
  111. package/src/Icon/Icon.tsx +0 -76
  112. /package/dist/{Frame → primitives/Frame}/index.d.ts +0 -0
  113. /package/src/{Frame → primitives/Frame}/index.ts +0 -0
package/dist/index.cjs CHANGED
@@ -34,12 +34,32 @@ var DEFAULT_THEME_CONFIG = {
34
34
  // [sunken, default, elevated]
35
35
  },
36
36
  spacing: {
37
- xs: 4,
38
- sm: 8,
39
- md: 12,
40
- lg: 16,
41
- xl: 24,
42
- xxl: 32
37
+ "00": 0,
38
+ // base * 0
39
+ "02": 2,
40
+ // base * 0.25
41
+ "04": 4,
42
+ // base * 0.5
43
+ "06": 6,
44
+ // base * 0.75
45
+ "08": 8,
46
+ // base * 1 (Medium preset, 8px base)
47
+ "10": 10,
48
+ // base * 1.25
49
+ "12": 12,
50
+ // base * 1.5
51
+ "16": 16,
52
+ // base * 2
53
+ "20": 20,
54
+ // base * 2.5
55
+ "24": 24,
56
+ // base * 3
57
+ "32": 32,
58
+ // base * 4
59
+ "40": 40,
60
+ // base * 5
61
+ "48": 48
62
+ // base * 6
43
63
  },
44
64
  radius: {
45
65
  none: 0,
@@ -427,27 +447,27 @@ function useTokens(elevation) {
427
447
  function getSizeConfig(tokens) {
428
448
  return {
429
449
  sm: {
430
- paddingVertical: tokens.spacing.xs,
431
- paddingHorizontal: tokens.spacing.md,
450
+ paddingVertical: tokens.spacing["04"],
451
+ paddingHorizontal: tokens.spacing["12"],
432
452
  fontSize: tokens.typography.size.sm,
433
453
  borderRadius: tokens.radius.sm,
434
- gap: tokens.spacing.xs,
454
+ gap: tokens.spacing["04"],
435
455
  iconSize: tokens.typography.size.sm
436
456
  },
437
457
  md: {
438
- paddingVertical: tokens.spacing.sm,
439
- paddingHorizontal: tokens.spacing.lg,
458
+ paddingVertical: tokens.spacing["08"],
459
+ paddingHorizontal: tokens.spacing["16"],
440
460
  fontSize: tokens.typography.size.base,
441
461
  borderRadius: tokens.radius.md,
442
- gap: tokens.spacing.sm,
462
+ gap: tokens.spacing["08"],
443
463
  iconSize: tokens.typography.size.base
444
464
  },
445
465
  lg: {
446
- paddingVertical: tokens.spacing.md,
447
- paddingHorizontal: tokens.spacing.xl,
466
+ paddingVertical: tokens.spacing["12"],
467
+ paddingHorizontal: tokens.spacing["24"],
448
468
  fontSize: tokens.typography.size.base,
449
469
  borderRadius: tokens.radius.lg,
450
- gap: tokens.spacing.sm,
470
+ gap: tokens.spacing["08"],
451
471
  iconSize: tokens.typography.size.base
452
472
  }
453
473
  };
@@ -528,25 +548,41 @@ function Icon({
528
548
  color,
529
549
  elevation = 1,
530
550
  style,
531
- onPress
551
+ onPress,
552
+ // Accessibility
553
+ accessibilityLabel,
554
+ // Testing & platform
555
+ testID,
556
+ nativeID,
557
+ ref
532
558
  }) {
533
559
  const tokens = useTokens(elevation);
534
- const fontSize = size ?? tokens.typography.size.base;
535
- const opsz = opticalSize ?? fontSize;
536
- const iconColor = color ?? newtone.srgbToHex(tokens.textPrimary.srgb);
537
- const fontFamily = `Material Symbols ${tokens.icons.variant.charAt(0).toUpperCase() + tokens.icons.variant.slice(1)}`;
538
- const fontVariationSettings = `'FILL' ${fill}, 'wght' ${tokens.icons.weight}, 'GRAD' ${tokens.icons.grade}, 'opsz' ${opsz}`;
560
+ const iconStyle = React11.useMemo(() => {
561
+ const fontSize = size ?? tokens.typography.size.base;
562
+ const opsz = opticalSize ?? fontSize;
563
+ const iconColor = color ?? newtone.srgbToHex(tokens.textPrimary.srgb);
564
+ const fontFamily = `Material Symbols ${tokens.icons.variant.charAt(0).toUpperCase() + tokens.icons.variant.slice(1)}`;
565
+ const fontVariationSettings = `'FILL' ${fill}, 'wght' ${tokens.icons.weight}, 'GRAD' ${tokens.icons.grade}, 'opsz' ${opsz}`;
566
+ return {
567
+ fontFamily,
568
+ fontSize,
569
+ color: iconColor,
570
+ userSelect: "none",
571
+ // web-only: prevents users from selecting the icon as text
572
+ fontVariationSettings,
573
+ // web-only: controls the variable font axes listed above
574
+ ...style
575
+ };
576
+ }, [tokens, size, opticalSize, fill, color, style]);
539
577
  return /* @__PURE__ */ React11__default.default.createElement(
540
578
  reactNative.Text,
541
579
  {
542
- style: {
543
- fontFamily,
544
- fontSize,
545
- color: iconColor,
546
- userSelect: "none",
547
- fontVariationSettings,
548
- ...style
549
- },
580
+ ref,
581
+ testID,
582
+ nativeID,
583
+ accessibilityLabel,
584
+ importantForAccessibility: accessibilityLabel ? "yes" : "no-hide-descendants",
585
+ style: iconStyle,
550
586
  onPress
551
587
  },
552
588
  name
@@ -605,7 +641,7 @@ function getCardStyles(tokens, disabled) {
605
641
  borderWidth: 1,
606
642
  borderColor: newtone.srgbToHex(tokens.border.srgb),
607
643
  borderRadius: tokens.radius.lg,
608
- padding: tokens.spacing.lg,
644
+ padding: tokens.spacing["16"],
609
645
  opacity: disabled ? 0.5 : 1
610
646
  }
611
647
  });
@@ -625,8 +661,51 @@ function Card({
625
661
  );
626
662
  return /* @__PURE__ */ React11__default.default.createElement(reactNative.View, { style: [styles.container, ...Array.isArray(style) ? style : [style]] }, children);
627
663
  }
664
+ var hadKeyboardEvent = false;
665
+ var isListenerSetup = false;
666
+ function setupModality() {
667
+ if (isListenerSetup || typeof document === "undefined") return;
668
+ isListenerSetup = true;
669
+ const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
670
+ "Tab",
671
+ "ArrowUp",
672
+ "ArrowDown",
673
+ "ArrowLeft",
674
+ "ArrowRight",
675
+ "Enter",
676
+ " ",
677
+ "Escape"
678
+ ]);
679
+ document.addEventListener("keydown", (e) => {
680
+ if (NAVIGATION_KEYS.has(e.key)) {
681
+ hadKeyboardEvent = true;
682
+ }
683
+ }, true);
684
+ document.addEventListener("pointerdown", () => {
685
+ hadKeyboardEvent = false;
686
+ }, true);
687
+ document.addEventListener("mousedown", () => {
688
+ hadKeyboardEvent = false;
689
+ }, true);
690
+ }
691
+ function useFocusVisible() {
692
+ const [isFocusVisible, setIsFocusVisible] = React11.useState(false);
693
+ React11.useEffect(() => {
694
+ setupModality();
695
+ }, []);
696
+ const onFocus = React11.useCallback(() => {
697
+ if (hadKeyboardEvent) {
698
+ setIsFocusVisible(true);
699
+ }
700
+ }, []);
701
+ const onBlur = React11.useCallback(() => {
702
+ setIsFocusVisible(false);
703
+ }, []);
704
+ const focusProps = { onFocus, onBlur };
705
+ return { isFocusVisible, focusProps };
706
+ }
628
707
 
629
- // src/Frame/Frame.utils.ts
708
+ // src/primitives/Frame/Frame.utils.ts
630
709
  function resolveSpacing(value, tokens) {
631
710
  if (typeof value === "number") return value;
632
711
  return tokens.spacing[value];
@@ -691,7 +770,7 @@ function resolveSizing(width, height) {
691
770
  }
692
771
  if (height !== void 0) {
693
772
  if (height === "fill") {
694
- style.flexGrow = style.flexGrow === 1 ? 1 : 1;
773
+ style.flexGrow = 1;
695
774
  style.height = "100%";
696
775
  } else if (typeof height === "number") {
697
776
  style.height = height;
@@ -727,7 +806,7 @@ function resolveFlexDirection(direction, reverse) {
727
806
  return reverse ? "column-reverse" : "column";
728
807
  }
729
808
 
730
- // src/Frame/Frame.styles.ts
809
+ // src/primitives/Frame/Frame.styles.ts
731
810
  function getFrameStyles(input) {
732
811
  const {
733
812
  tokens,
@@ -816,12 +895,15 @@ function getFrameStyles(input) {
816
895
  if (layout === "grid") {
817
896
  gridWebStyle = {
818
897
  display: "grid",
898
+ // Divide into equal-width columns (e.g. 3 columns → "repeat(3, 1fr)").
819
899
  gridTemplateColumns: columns ? `repeat(${columns}, 1fr)` : void 0,
820
900
  gridTemplateRows: rows ? `repeat(${rows}, 1fr)` : void 0
821
901
  };
822
902
  }
823
903
  const insetBoxShadow = frameElevation === -2 ? "inset 0 2px 4px rgba(0,0,0,0.12)" : null;
824
904
  return {
905
+ // Validate and optimize the container styles through StyleSheet.create(),
906
+ // then extract the single style object with `.c`.
825
907
  container: reactNative.StyleSheet.create({ c: container }).c,
826
908
  pressed,
827
909
  gridWebStyle,
@@ -829,7 +911,7 @@ function getFrameStyles(input) {
829
911
  };
830
912
  }
831
913
 
832
- // src/Frame/Frame.tsx
914
+ // src/primitives/Frame/Frame.tsx
833
915
  function wrapTextChildren(children, textStyle) {
834
916
  return React11__default.default.Children.map(children, (child) => {
835
917
  if (typeof child === "string" || typeof child === "number") {
@@ -875,6 +957,13 @@ function Frame({
875
957
  onPress,
876
958
  href,
877
959
  disabled = false,
960
+ // Accessibility
961
+ accessibilityLabel,
962
+ accessibilityHint,
963
+ // Testing & platform
964
+ testID,
965
+ nativeID,
966
+ ref,
878
967
  // Style override
879
968
  style
880
969
  }) {
@@ -958,6 +1047,14 @@ function Frame({
958
1047
  }
959
1048
  const userStyles = Array.isArray(style) ? style : style ? [style] : [];
960
1049
  const isInteractive = onPress !== void 0 || href !== void 0;
1050
+ const { isFocusVisible, focusProps } = useFocusVisible();
1051
+ const focusRingStyle = isFocusVisible && !disabled ? {
1052
+ outlineWidth: 2,
1053
+ outlineStyle: "solid",
1054
+ outlineColor: newtone.srgbToHex(tokens.interactive.srgb),
1055
+ outlineOffset: 2
1056
+ } : void 0;
1057
+ const webFocusProps = isInteractive ? focusProps : {};
961
1058
  const textStyle = React11.useMemo(
962
1059
  () => ({
963
1060
  color: newtone.srgbToHex(tokens.textPrimary.srgb),
@@ -967,27 +1064,56 @@ function Frame({
967
1064
  }),
968
1065
  [tokens]
969
1066
  );
970
- const wrappedChildren = wrapTextChildren(children, textStyle);
971
- return /* @__PURE__ */ React11__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? /* @__PURE__ */ React11__default.default.createElement(
972
- reactNative.Pressable,
973
- {
974
- onPress,
975
- disabled,
976
- ...href ? { href, accessibilityRole: "link" } : { accessibilityRole: "button" },
977
- style: ({ pressed }) => [
978
- styles.container,
979
- pressed && !disabled && styles.pressed,
980
- ...webOverrides,
981
- ...userStyles
982
- ]
983
- },
984
- wrappedChildren
985
- ) : /* @__PURE__ */ React11__default.default.createElement(reactNative.View, { style: [styles.container, ...webOverrides, ...userStyles] }, wrappedChildren));
1067
+ const wrappedChildren = React11.useMemo(
1068
+ () => wrapTextChildren(children, textStyle),
1069
+ [children, textStyle]
1070
+ );
1071
+ return /* @__PURE__ */ React11__default.default.createElement(FrameContext.Provider, { value: contextValue }, isInteractive ? (
1072
+ // Pressable handles taps. When href is set, react-native-web renders
1073
+ // it as an <a> tag so it works like a regular link on the web.
1074
+ /* @__PURE__ */ React11__default.default.createElement(
1075
+ reactNative.Pressable,
1076
+ {
1077
+ ref,
1078
+ testID,
1079
+ nativeID,
1080
+ accessibilityLabel,
1081
+ accessibilityHint,
1082
+ accessibilityState: disabled ? { disabled: true } : void 0,
1083
+ onPress,
1084
+ disabled,
1085
+ ...href ? { href, accessibilityRole: "link" } : { accessibilityRole: "button" },
1086
+ ...webFocusProps,
1087
+ style: ({ pressed }) => [
1088
+ styles.container,
1089
+ pressed && !disabled && styles.pressed,
1090
+ focusRingStyle,
1091
+ ...webOverrides,
1092
+ ...userStyles
1093
+ ]
1094
+ },
1095
+ wrappedChildren
1096
+ )
1097
+ ) : (
1098
+ // Non-interactive Frame: just a plain View with no tap handling.
1099
+ /* @__PURE__ */ React11__default.default.createElement(
1100
+ reactNative.View,
1101
+ {
1102
+ ref,
1103
+ testID,
1104
+ nativeID,
1105
+ accessibilityLabel,
1106
+ accessibilityHint,
1107
+ style: [styles.container, ...webOverrides, ...userStyles]
1108
+ },
1109
+ wrappedChildren
1110
+ )
1111
+ ));
986
1112
  }
987
1113
  function getTextInputStyles(tokens, disabled) {
988
1114
  return reactNative.StyleSheet.create({
989
1115
  container: {
990
- gap: tokens.spacing.xs
1116
+ gap: tokens.spacing["04"]
991
1117
  },
992
1118
  label: {
993
1119
  fontFamily: tokens.typography.fonts.default,
@@ -1001,8 +1127,8 @@ function getTextInputStyles(tokens, disabled) {
1001
1127
  borderWidth: 1,
1002
1128
  borderColor: newtone.srgbToHex(tokens.border.srgb),
1003
1129
  borderRadius: tokens.radius.md,
1004
- paddingVertical: tokens.spacing.sm,
1005
- paddingHorizontal: tokens.spacing.md,
1130
+ paddingVertical: tokens.spacing["08"],
1131
+ paddingHorizontal: tokens.spacing["12"],
1006
1132
  fontSize: tokens.typography.size.base,
1007
1133
  color: disabled ? newtone.srgbToHex(tokens.textSecondary.srgb) : newtone.srgbToHex(tokens.textPrimary.srgb),
1008
1134
  opacity: disabled ? 0.5 : 1
@@ -1048,7 +1174,11 @@ function getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpe
1048
1174
  maxHeight,
1049
1175
  zIndex: 1e3,
1050
1176
  overflow: "hidden",
1051
- ...{ boxShadow: "0 4px 12px rgba(0,0,0,0.15)" }
1177
+ shadowColor: "#000",
1178
+ shadowOffset: { width: 0, height: 4 },
1179
+ shadowOpacity: 0.15,
1180
+ shadowRadius: 12,
1181
+ elevation: 8
1052
1182
  }
1053
1183
  });
1054
1184
  }
@@ -1087,6 +1217,7 @@ function Popover({
1087
1217
  }, [isOpen, onClose]);
1088
1218
  React11.useEffect(() => {
1089
1219
  if (!isOpen) return;
1220
+ if (typeof document === "undefined") return;
1090
1221
  const handleMouseDown = (e) => {
1091
1222
  const node = containerRef.current;
1092
1223
  if (node && !node.contains(e.target)) {
@@ -1157,12 +1288,12 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1157
1288
  const isSm = size === "sm";
1158
1289
  const fontSize = isSm ? tokens.typography.size.sm : tokens.typography.size.base;
1159
1290
  const iconSize = fontSize + 2;
1160
- const iconSpace = iconSize + tokens.spacing.sm;
1161
- const paddingVertical = isSm ? tokens.spacing.xs : tokens.spacing.sm;
1162
- const paddingHorizontal = isSm ? tokens.spacing.sm : tokens.spacing.md;
1291
+ const iconSpace = iconSize + tokens.spacing["08"];
1292
+ const paddingVertical = isSm ? tokens.spacing["04"] : tokens.spacing["08"];
1293
+ const paddingHorizontal = isSm ? tokens.spacing["08"] : tokens.spacing["12"];
1163
1294
  return reactNative.StyleSheet.create({
1164
1295
  container: {
1165
- gap: tokens.spacing.xs,
1296
+ gap: tokens.spacing["04"],
1166
1297
  zIndex: isOpen ? 999 : 0
1167
1298
  },
1168
1299
  label: {
@@ -1180,7 +1311,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1180
1311
  borderRadius: tokens.radius.md,
1181
1312
  paddingVertical,
1182
1313
  paddingLeft: paddingHorizontal,
1183
- paddingRight: iconSpace + (isSm ? tokens.spacing.xs : tokens.spacing.sm),
1314
+ paddingRight: iconSpace + (isSm ? tokens.spacing["04"] : tokens.spacing["08"]),
1184
1315
  opacity: disabled ? 0.5 : 1
1185
1316
  },
1186
1317
  triggerText: {
@@ -1191,7 +1322,7 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1191
1322
  },
1192
1323
  iconWrapper: {
1193
1324
  position: "absolute",
1194
- right: isSm ? tokens.spacing.xs : tokens.spacing.sm,
1325
+ right: isSm ? tokens.spacing["04"] : tokens.spacing["08"],
1195
1326
  top: 0,
1196
1327
  bottom: 0,
1197
1328
  justifyContent: "center"
@@ -1203,9 +1334,9 @@ function getSelectStyles(tokens, disabled, size, isOpen) {
1203
1334
  color: newtone.srgbToHex(tokens.textSecondary.srgb),
1204
1335
  textTransform: "uppercase",
1205
1336
  letterSpacing: 0.5,
1206
- paddingVertical: tokens.spacing.xs,
1207
- paddingHorizontal: isSm ? tokens.spacing.sm : tokens.spacing.md,
1208
- paddingTop: tokens.spacing.sm
1337
+ paddingVertical: tokens.spacing["04"],
1338
+ paddingHorizontal: isSm ? tokens.spacing["08"] : tokens.spacing["12"],
1339
+ paddingTop: tokens.spacing["08"]
1209
1340
  }
1210
1341
  });
1211
1342
  }
@@ -1319,8 +1450,8 @@ function SelectOptionRow({
1319
1450
  size
1320
1451
  }) {
1321
1452
  const tokens = useTokens(1);
1322
- const paddingVertical = size === "sm" ? tokens.spacing.xs : tokens.spacing.sm;
1323
- const paddingHorizontal = size === "sm" ? tokens.spacing.sm : tokens.spacing.md;
1453
+ const paddingVertical = size === "sm" ? tokens.spacing["04"] : tokens.spacing["08"];
1454
+ const paddingHorizontal = size === "sm" ? tokens.spacing["08"] : tokens.spacing["12"];
1324
1455
  const fontSize = size === "sm" ? tokens.typography.size.sm : tokens.typography.size.base;
1325
1456
  if (renderOption) {
1326
1457
  return /* @__PURE__ */ React11__default.default.createElement(
@@ -1329,7 +1460,7 @@ function SelectOptionRow({
1329
1460
  onPress: option.disabled ? void 0 : onSelect,
1330
1461
  disabled: option.disabled,
1331
1462
  role: "option",
1332
- "aria-selected": isSelected
1463
+ accessibilityState: { selected: isSelected }
1333
1464
  },
1334
1465
  renderOption(option, { isSelected, isFocused })
1335
1466
  );
@@ -1340,7 +1471,7 @@ function SelectOptionRow({
1340
1471
  onPress: option.disabled ? void 0 : onSelect,
1341
1472
  disabled: option.disabled,
1342
1473
  role: "option",
1343
- "aria-selected": isSelected,
1474
+ accessibilityState: { selected: isSelected },
1344
1475
  style: ({ pressed }) => [
1345
1476
  {
1346
1477
  flexDirection: "row",
@@ -1385,7 +1516,7 @@ function SelectOptionRow({
1385
1516
  },
1386
1517
  option.label
1387
1518
  ),
1388
- isSelected && /* @__PURE__ */ React11__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing.sm } }, /* @__PURE__ */ React11__default.default.createElement(
1519
+ isSelected && /* @__PURE__ */ React11__default.default.createElement(reactNative.View, { style: { marginLeft: tokens.spacing["08"] } }, /* @__PURE__ */ React11__default.default.createElement(
1389
1520
  Icon,
1390
1521
  {
1391
1522
  name: "check",
@@ -1446,8 +1577,7 @@ function Select({
1446
1577
  onPress: disabled ? void 0 : toggle,
1447
1578
  disabled,
1448
1579
  role: "combobox",
1449
- "aria-expanded": isOpen,
1450
- "aria-haspopup": "listbox",
1580
+ accessibilityState: { expanded: isOpen },
1451
1581
  ...triggerWebProps,
1452
1582
  style: styles.trigger
1453
1583
  },
@@ -1521,7 +1651,7 @@ function getToggleStyles(tokens, value, disabled) {
1521
1651
  container: {
1522
1652
  flexDirection: "row",
1523
1653
  alignItems: "center",
1524
- gap: tokens.spacing.sm,
1654
+ gap: tokens.spacing["08"],
1525
1655
  opacity: disabled ? 0.5 : 1
1526
1656
  },
1527
1657
  label: {
@@ -1582,7 +1712,7 @@ var THUMB_SIZE2 = 16;
1582
1712
  function getSliderStyles(tokens, disabled) {
1583
1713
  return reactNative.StyleSheet.create({
1584
1714
  container: {
1585
- gap: tokens.spacing.xs,
1715
+ gap: tokens.spacing["04"],
1586
1716
  opacity: disabled ? 0.5 : 1
1587
1717
  },
1588
1718
  labelRow: {
@@ -1798,7 +1928,7 @@ function buildHueSegments(min, max) {
1798
1928
  function getHueSliderStyles(tokens, disabled) {
1799
1929
  return reactNative.StyleSheet.create({
1800
1930
  container: {
1801
- gap: tokens.spacing.xs,
1931
+ gap: tokens.spacing["04"],
1802
1932
  opacity: disabled ? 0.5 : 1
1803
1933
  },
1804
1934
  labelRow: {
@@ -1972,7 +2102,7 @@ var THUMB_SIZE4 = 18;
1972
2102
  function getColorScaleSliderStyles(tokens, disabled) {
1973
2103
  return reactNative.StyleSheet.create({
1974
2104
  container: {
1975
- gap: tokens.spacing.xs,
2105
+ gap: tokens.spacing["04"],
1976
2106
  opacity: disabled ? 0.5 : 1
1977
2107
  },
1978
2108
  labelRow: {
@@ -2137,6 +2267,170 @@ function ColorScaleSlider({
2137
2267
  /* @__PURE__ */ React11__default.default.createElement(reactNative.Animated.View, { style: [styles.thumb, { left: thumbAnim }] })
2138
2268
  ), warning && /* @__PURE__ */ React11__default.default.createElement(reactNative.Text, { style: styles.warning }, warning));
2139
2269
  }
2270
+ function getWrapperStyles(input) {
2271
+ const {
2272
+ tokens,
2273
+ direction = "vertical",
2274
+ wrap = false,
2275
+ reverse = false,
2276
+ align,
2277
+ justify,
2278
+ padding,
2279
+ gap,
2280
+ width,
2281
+ height,
2282
+ minWidth,
2283
+ maxWidth,
2284
+ minHeight,
2285
+ maxHeight
2286
+ } = input;
2287
+ const container = {};
2288
+ container.flexDirection = resolveFlexDirection(direction, reverse);
2289
+ if (wrap) container.flexWrap = "wrap";
2290
+ if (align) container.alignItems = resolveAlignment(align);
2291
+ if (justify) container.justifyContent = resolveJustification(justify);
2292
+ if (padding !== void 0) {
2293
+ const p = resolvePadding(padding, tokens);
2294
+ container.paddingTop = p.top;
2295
+ container.paddingRight = p.right;
2296
+ container.paddingBottom = p.bottom;
2297
+ container.paddingLeft = p.left;
2298
+ }
2299
+ if (gap !== void 0) {
2300
+ const g = resolveGap(gap, tokens);
2301
+ container.rowGap = g.rowGap;
2302
+ container.columnGap = g.columnGap;
2303
+ }
2304
+ Object.assign(container, resolveSizing(width, height));
2305
+ if (minWidth !== void 0) container.minWidth = minWidth;
2306
+ if (maxWidth !== void 0) container.maxWidth = maxWidth;
2307
+ if (minHeight !== void 0) container.minHeight = minHeight;
2308
+ if (maxHeight !== void 0) container.maxHeight = maxHeight;
2309
+ return reactNative.StyleSheet.create({ c: container }).c;
2310
+ }
2311
+
2312
+ // src/primitives/Wrapper/Wrapper.tsx
2313
+ function Wrapper({
2314
+ children,
2315
+ direction,
2316
+ wrap,
2317
+ reverse,
2318
+ align,
2319
+ justify,
2320
+ padding,
2321
+ gap,
2322
+ width,
2323
+ height,
2324
+ minWidth,
2325
+ maxWidth,
2326
+ minHeight,
2327
+ maxHeight,
2328
+ style,
2329
+ // Testing & platform
2330
+ testID,
2331
+ nativeID,
2332
+ ref
2333
+ }) {
2334
+ const tokens = useTokens(1);
2335
+ const containerStyle = React11.useMemo(
2336
+ () => getWrapperStyles({
2337
+ tokens,
2338
+ direction,
2339
+ wrap,
2340
+ reverse,
2341
+ align,
2342
+ justify,
2343
+ padding,
2344
+ gap,
2345
+ width,
2346
+ height,
2347
+ minWidth,
2348
+ maxWidth,
2349
+ minHeight,
2350
+ maxHeight
2351
+ }),
2352
+ [
2353
+ tokens,
2354
+ direction,
2355
+ wrap,
2356
+ reverse,
2357
+ align,
2358
+ justify,
2359
+ padding,
2360
+ gap,
2361
+ width,
2362
+ height,
2363
+ minWidth,
2364
+ maxWidth,
2365
+ minHeight,
2366
+ maxHeight
2367
+ ]
2368
+ );
2369
+ const userStyles = Array.isArray(style) ? style : style ? [style] : [];
2370
+ return /* @__PURE__ */ React11__default.default.createElement(
2371
+ reactNative.View,
2372
+ {
2373
+ ref,
2374
+ testID,
2375
+ nativeID,
2376
+ accessibilityRole: "none",
2377
+ style: [containerStyle, ...userStyles]
2378
+ },
2379
+ children
2380
+ );
2381
+ }
2382
+ var COLOR_MAP = {
2383
+ primary: "textPrimary",
2384
+ secondary: "textSecondary",
2385
+ interactive: "interactive"
2386
+ };
2387
+ function Text11({
2388
+ children,
2389
+ size = "base",
2390
+ weight = "regular",
2391
+ color = "primary",
2392
+ font = "default",
2393
+ lineHeight = "normal",
2394
+ align,
2395
+ numberOfLines,
2396
+ elevation = 1,
2397
+ style,
2398
+ // Accessibility
2399
+ accessibilityRole,
2400
+ // Testing & platform
2401
+ testID,
2402
+ nativeID,
2403
+ ref
2404
+ }) {
2405
+ const tokens = useTokens(elevation);
2406
+ const resolvedStyle = React11.useMemo(() => {
2407
+ const fontSize = tokens.typography.size[size];
2408
+ return {
2409
+ // Font family from the theme (e.g. 'default' → 'Inter', 'mono' → 'JetBrains Mono').
2410
+ fontFamily: tokens.typography.fonts[font],
2411
+ fontSize,
2412
+ // Font weight is stored as a number (e.g. 400, 600) but React Native expects a string.
2413
+ fontWeight: String(tokens.typography.weight[weight]),
2414
+ // Convert the theme color from internal sRGB format to a hex string (e.g. '#1a1a1a').
2415
+ color: newtone.srgbToHex(tokens[COLOR_MAP[color]].srgb),
2416
+ // Line height = font size × multiplier (e.g. 16px × 1.5 = 24px line height).
2417
+ lineHeight: fontSize * tokens.typography.lineHeight[lineHeight],
2418
+ textAlign: align
2419
+ };
2420
+ }, [tokens, size, weight, color, font, lineHeight, align]);
2421
+ return /* @__PURE__ */ React11__default.default.createElement(
2422
+ reactNative.Text,
2423
+ {
2424
+ ref,
2425
+ testID,
2426
+ nativeID,
2427
+ accessibilityRole,
2428
+ style: style ? [resolvedStyle, ...Array.isArray(style) ? style : [style]] : resolvedStyle,
2429
+ numberOfLines
2430
+ },
2431
+ children
2432
+ );
2433
+ }
2140
2434
  function getAppShellStyles(tokens) {
2141
2435
  return reactNative.StyleSheet.create({
2142
2436
  container: {
@@ -2817,8 +3111,10 @@ exports.SYSTEM_FONTS = SYSTEM_FONTS;
2817
3111
  exports.Select = Select;
2818
3112
  exports.Sidebar = Sidebar;
2819
3113
  exports.Slider = Slider;
3114
+ exports.Text = Text11;
2820
3115
  exports.TextInput = TextInput;
2821
3116
  exports.Toggle = Toggle;
3117
+ exports.Wrapper = Wrapper;
2822
3118
  exports.buildGoogleFontsUrl = buildGoogleFontsUrl;
2823
3119
  exports.computeTokens = computeTokens;
2824
3120
  exports.generateComponentCode = generateComponentCode;
@@ -2826,6 +3122,7 @@ exports.getCategory = getCategory;
2826
3122
  exports.getComponent = getComponent;
2827
3123
  exports.getComponentsByCategory = getComponentsByCategory;
2828
3124
  exports.isOptionGroup = isOptionGroup;
3125
+ exports.useFocusVisible = useFocusVisible;
2829
3126
  exports.useFrameContext = useFrameContext;
2830
3127
  exports.useNewtoneTheme = useNewtoneTheme;
2831
3128
  exports.usePopover = usePopover;