@newtonedev/components 0.1.13 → 0.1.14

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 (160) hide show
  1. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts +1 -1
  2. package/dist/composites/actions/Button/Button.d.ts +11 -1
  3. package/dist/composites/actions/Button/Button.d.ts.map +1 -1
  4. package/dist/composites/actions/Button/Button.styles.d.ts.map +1 -1
  5. package/dist/composites/actions/Button/Button.types.d.ts +11 -1
  6. package/dist/composites/actions/Button/Button.types.d.ts.map +1 -1
  7. package/dist/composites/branding/LogoMonogram/LogoMonogram.d.ts +10 -0
  8. package/dist/composites/branding/LogoMonogram/LogoMonogram.d.ts.map +1 -0
  9. package/dist/composites/branding/LogoMonogram/LogoMonogram.types.d.ts +35 -0
  10. package/dist/composites/branding/LogoMonogram/LogoMonogram.types.d.ts.map +1 -0
  11. package/dist/composites/branding/LogoMonogram/index.d.ts +3 -0
  12. package/dist/composites/branding/LogoMonogram/index.d.ts.map +1 -0
  13. package/dist/composites/branding/LogoWordmark/LogoWordmark.d.ts +9 -0
  14. package/dist/composites/branding/LogoWordmark/LogoWordmark.d.ts.map +1 -0
  15. package/dist/composites/branding/LogoWordmark/LogoWordmark.types.d.ts +26 -0
  16. package/dist/composites/branding/LogoWordmark/LogoWordmark.types.d.ts.map +1 -0
  17. package/dist/composites/branding/LogoWordmark/index.d.ts +3 -0
  18. package/dist/composites/branding/LogoWordmark/index.d.ts.map +1 -0
  19. package/dist/composites/display/Chip/Chip.d.ts +25 -0
  20. package/dist/composites/display/Chip/Chip.d.ts.map +1 -0
  21. package/dist/composites/display/Chip/Chip.styles.d.ts +29 -0
  22. package/dist/composites/display/Chip/Chip.styles.d.ts.map +1 -0
  23. package/dist/composites/display/Chip/Chip.types.d.ts +63 -0
  24. package/dist/composites/display/Chip/Chip.types.d.ts.map +1 -0
  25. package/dist/composites/display/Chip/index.d.ts +3 -0
  26. package/dist/composites/display/Chip/index.d.ts.map +1 -0
  27. package/dist/composites/form-controls/Select/Select.d.ts.map +1 -1
  28. package/dist/composites/form-controls/Select/Select.styles.d.ts +2 -2
  29. package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -1
  30. package/dist/composites/form-controls/Select/SelectOption.d.ts.map +1 -1
  31. package/dist/composites/form-controls/TextInput/TextInput.d.ts.map +1 -1
  32. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts +2 -2
  33. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -1
  34. package/dist/composites/form-controls/Toggle/Toggle.d.ts.map +1 -1
  35. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts +2 -2
  36. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -1
  37. package/dist/composites/layout/AppShell/AppShell.d.ts.map +1 -1
  38. package/dist/composites/layout/AppShell/AppShell.styles.d.ts +2 -2
  39. package/dist/composites/layout/AppShell/AppShell.styles.d.ts.map +1 -1
  40. package/dist/composites/layout/Card/Card.d.ts.map +1 -1
  41. package/dist/composites/layout/Card/Card.styles.d.ts +2 -2
  42. package/dist/composites/layout/Card/Card.styles.d.ts.map +1 -1
  43. package/dist/composites/layout/ContentCard/ContentCard.d.ts +33 -0
  44. package/dist/composites/layout/ContentCard/ContentCard.d.ts.map +1 -0
  45. package/dist/composites/layout/ContentCard/ContentCard.styles.d.ts +10 -0
  46. package/dist/composites/layout/ContentCard/ContentCard.styles.d.ts.map +1 -0
  47. package/dist/composites/layout/ContentCard/ContentCard.types.d.ts +52 -0
  48. package/dist/composites/layout/ContentCard/ContentCard.types.d.ts.map +1 -0
  49. package/dist/composites/layout/ContentCard/index.d.ts +3 -0
  50. package/dist/composites/layout/ContentCard/index.d.ts.map +1 -0
  51. package/dist/composites/layout/Divider/Divider.d.ts +25 -0
  52. package/dist/composites/layout/Divider/Divider.d.ts.map +1 -0
  53. package/dist/composites/layout/Divider/Divider.styles.d.ts +8 -0
  54. package/dist/composites/layout/Divider/Divider.styles.d.ts.map +1 -0
  55. package/dist/composites/layout/Divider/Divider.types.d.ts +25 -0
  56. package/dist/composites/layout/Divider/Divider.types.d.ts.map +1 -0
  57. package/dist/composites/layout/Divider/index.d.ts +3 -0
  58. package/dist/composites/layout/Divider/index.d.ts.map +1 -0
  59. package/dist/composites/layout/Navbar/Navbar.d.ts.map +1 -1
  60. package/dist/composites/layout/Navbar/Navbar.styles.d.ts +4 -3
  61. package/dist/composites/layout/Navbar/Navbar.styles.d.ts.map +1 -1
  62. package/dist/composites/layout/Sidebar/Sidebar.d.ts.map +1 -1
  63. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts +4 -3
  64. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts.map +1 -1
  65. package/dist/composites/overlays/Popover/Popover.d.ts.map +1 -1
  66. package/dist/composites/overlays/Popover/Popover.styles.d.ts +2 -2
  67. package/dist/composites/overlays/Popover/Popover.styles.d.ts.map +1 -1
  68. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts.map +1 -1
  69. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts +2 -2
  70. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -1
  71. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts +2 -2
  72. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -1
  73. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts +2 -2
  74. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -1
  75. package/dist/index.cjs +903 -396
  76. package/dist/index.cjs.map +1 -1
  77. package/dist/index.d.ts +12 -2
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +830 -344
  80. package/dist/index.js.map +1 -1
  81. package/dist/primitives/Frame/Frame.d.ts +1 -35
  82. package/dist/primitives/Frame/Frame.d.ts.map +1 -1
  83. package/dist/primitives/Frame/Frame.styles.d.ts +13 -4
  84. package/dist/primitives/Frame/Frame.styles.d.ts.map +1 -1
  85. package/dist/primitives/Frame/Frame.types.d.ts +99 -1
  86. package/dist/primitives/Frame/Frame.types.d.ts.map +1 -1
  87. package/dist/primitives/Frame/index.d.ts +1 -1
  88. package/dist/primitives/Frame/index.d.ts.map +1 -1
  89. package/dist/primitives/Icon/Icon.d.ts.map +1 -1
  90. package/dist/primitives/Icon/Icon.types.d.ts +2 -2
  91. package/dist/primitives/Icon/Icon.types.d.ts.map +1 -1
  92. package/dist/primitives/Text/Text.d.ts +5 -3
  93. package/dist/primitives/Text/Text.d.ts.map +1 -1
  94. package/dist/primitives/Text/Text.spans.d.ts.map +1 -1
  95. package/dist/primitives/Text/Text.types.d.ts +3 -6
  96. package/dist/primitives/Text/Text.types.d.ts.map +1 -1
  97. package/dist/primitives/Wrapper/Wrapper.d.ts +1 -1
  98. package/dist/primitives/Wrapper/Wrapper.d.ts.map +1 -1
  99. package/dist/primitives/Wrapper/Wrapper.styles.d.ts +9 -1
  100. package/dist/primitives/Wrapper/Wrapper.styles.d.ts.map +1 -1
  101. package/dist/primitives/Wrapper/Wrapper.types.d.ts +31 -1
  102. package/dist/primitives/Wrapper/Wrapper.types.d.ts.map +1 -1
  103. package/package.json +1 -1
  104. package/src/composites/actions/Button/Button.styles.ts +71 -55
  105. package/src/composites/actions/Button/Button.tsx +34 -13
  106. package/src/composites/actions/Button/Button.types.ts +13 -1
  107. package/src/composites/branding/LogoMonogram/LogoMonogram.tsx +29 -0
  108. package/src/composites/branding/LogoMonogram/LogoMonogram.types.ts +35 -0
  109. package/src/composites/branding/LogoMonogram/index.ts +2 -0
  110. package/src/composites/branding/LogoWordmark/LogoWordmark.tsx +29 -0
  111. package/src/composites/branding/LogoWordmark/LogoWordmark.types.ts +25 -0
  112. package/src/composites/branding/LogoWordmark/index.ts +2 -0
  113. package/src/composites/display/Chip/Chip.styles.ts +189 -0
  114. package/src/composites/display/Chip/Chip.tsx +97 -0
  115. package/src/composites/display/Chip/Chip.types.ts +74 -0
  116. package/src/composites/display/Chip/index.ts +2 -0
  117. package/src/composites/form-controls/Select/Select.styles.ts +10 -10
  118. package/src/composites/form-controls/Select/Select.tsx +9 -6
  119. package/src/composites/form-controls/Select/SelectOption.tsx +10 -7
  120. package/src/composites/form-controls/TextInput/TextInput.styles.ts +12 -8
  121. package/src/composites/form-controls/TextInput/TextInput.tsx +7 -4
  122. package/src/composites/form-controls/Toggle/Toggle.styles.ts +10 -7
  123. package/src/composites/form-controls/Toggle/Toggle.tsx +4 -3
  124. package/src/composites/layout/AppShell/AppShell.styles.ts +8 -3
  125. package/src/composites/layout/AppShell/AppShell.tsx +6 -2
  126. package/src/composites/layout/Card/Card.styles.ts +10 -4
  127. package/src/composites/layout/Card/Card.tsx +4 -3
  128. package/src/composites/layout/ContentCard/ContentCard.styles.ts +44 -0
  129. package/src/composites/layout/ContentCard/ContentCard.tsx +71 -0
  130. package/src/composites/layout/ContentCard/ContentCard.types.ts +60 -0
  131. package/src/composites/layout/ContentCard/index.ts +2 -0
  132. package/src/composites/layout/Divider/Divider.styles.ts +30 -0
  133. package/src/composites/layout/Divider/Divider.tsx +46 -0
  134. package/src/composites/layout/Divider/Divider.types.ts +28 -0
  135. package/src/composites/layout/Divider/index.ts +2 -0
  136. package/src/composites/layout/Navbar/Navbar.styles.ts +7 -5
  137. package/src/composites/layout/Navbar/Navbar.tsx +4 -3
  138. package/src/composites/layout/Sidebar/Sidebar.styles.ts +7 -5
  139. package/src/composites/layout/Sidebar/Sidebar.tsx +4 -3
  140. package/src/composites/overlays/Popover/Popover.styles.ts +7 -5
  141. package/src/composites/overlays/Popover/Popover.tsx +4 -3
  142. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.ts +5 -5
  143. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.tsx +4 -3
  144. package/src/composites/range-inputs/HueSlider/HueSlider.styles.ts +7 -7
  145. package/src/composites/range-inputs/HueSlider/HueSlider.tsx +1 -1
  146. package/src/composites/range-inputs/Slider/Slider.styles.ts +9 -9
  147. package/src/composites/range-inputs/Slider/Slider.tsx +1 -1
  148. package/src/index.ts +43 -9
  149. package/src/primitives/Frame/Frame.styles.ts +55 -12
  150. package/src/primitives/Frame/Frame.tsx +138 -140
  151. package/src/primitives/Frame/Frame.types.ts +119 -1
  152. package/src/primitives/Frame/index.ts +4 -0
  153. package/src/primitives/Icon/Icon.tsx +9 -6
  154. package/src/primitives/Icon/Icon.types.ts +2 -2
  155. package/src/primitives/Text/Text.spans.ts +9 -5
  156. package/src/primitives/Text/Text.tsx +26 -15
  157. package/src/primitives/Text/Text.types.ts +3 -6
  158. package/src/primitives/Wrapper/Wrapper.styles.ts +32 -0
  159. package/src/primitives/Wrapper/Wrapper.tsx +22 -3
  160. package/src/primitives/Wrapper/Wrapper.types.ts +45 -0
@@ -1,5 +1,5 @@
1
1
  import type { View, ViewStyle, GestureResponderEvent } from 'react-native';
2
- import type { FrameElevation } from 'newtone-api';
2
+ import type { FrameElevation, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
4
  // ── Spacing Types ──────────────────────────────────────────────
5
5
 
@@ -76,6 +76,20 @@ export interface RadiusCorners {
76
76
  */
77
77
  export type RadiusProp = RadiusValue | RadiusCorners;
78
78
 
79
+ // ── Positioning Types ──────────────────────────────────────────
80
+
81
+ /** CSS position mode. `'fixed'` and `'sticky'` are web-only (via react-native-web). */
82
+ export type PositionType = 'absolute' | 'relative' | 'fixed' | 'sticky';
83
+
84
+ /** Position offset value: pixels (number) or percentage string (e.g. `'50%'`). */
85
+ export type OffsetValue = number | string;
86
+
87
+ /** Overflow clipping mode. */
88
+ export type OverflowMode = 'visible' | 'hidden' | 'scroll';
89
+
90
+ /** Pointer-events mode (View prop, not a style). */
91
+ export type PointerEventsMode = 'auto' | 'none' | 'box-none' | 'box-only';
92
+
79
93
  // ── Sizing Types ───────────────────────────────────────────────
80
94
 
81
95
  /**
@@ -159,6 +173,23 @@ export interface FrameProps {
159
173
  */
160
174
  readonly elevation?: FrameElevation;
161
175
 
176
+ /**
177
+ * Named scheme to use for this Frame's subtree.
178
+ * Looks up the scheme's config from the ancestor NewtoneProvider's `schemes` map
179
+ * and uses it instead of the default for token computation and context.
180
+ * Ignored when the provider is in single-config mode.
181
+ *
182
+ * @example
183
+ * ```tsx
184
+ * <NewtoneProvider schemes={{ Default: config1, Dark: config2 }} defaultScheme="Default">
185
+ * <Frame scheme="Dark">
186
+ * {/* Children here get the "Dark" scheme's tokens *​/}
187
+ * </Frame>
188
+ * </NewtoneProvider>
189
+ * ```
190
+ */
191
+ readonly scheme?: string;
192
+
162
193
  // ── Layout ──
163
194
 
164
195
  /** Layout mode. @default 'flex' */
@@ -248,8 +279,95 @@ export interface FrameProps {
248
279
  /** Maximum height in pixels. */
249
280
  readonly maxHeight?: number;
250
281
 
282
+ // ── Positioning ──
283
+
284
+ /**
285
+ * CSS position mode.
286
+ *
287
+ * `'fixed'` and `'sticky'` are web-only (supported via react-native-web).
288
+ * React Native natively supports `'absolute'` and `'relative'`.
289
+ */
290
+ readonly position?: PositionType;
291
+
292
+ /** Offset from the top edge. Accepts pixels (number) or percentage string. */
293
+ readonly top?: OffsetValue;
294
+
295
+ /** Offset from the right edge. Accepts pixels (number) or percentage string. */
296
+ readonly right?: OffsetValue;
297
+
298
+ /** Offset from the bottom edge. Accepts pixels (number) or percentage string. */
299
+ readonly bottom?: OffsetValue;
300
+
301
+ /** Offset from the left edge. Accepts pixels (number) or percentage string. */
302
+ readonly left?: OffsetValue;
303
+
304
+ /** Stacking order. Higher values render above lower values. */
305
+ readonly zIndex?: number;
306
+
307
+ /**
308
+ * Content overflow behavior.
309
+ *
310
+ * When `radius` is set with positive values, Frame auto-applies `overflow: 'hidden'`
311
+ * to clip content at rounded corners. Setting `overflow` explicitly overrides this.
312
+ */
313
+ readonly overflow?: OverflowMode;
314
+
315
+ /**
316
+ * Controls whether the element can be the target of touch/pointer events.
317
+ *
318
+ * - `'auto'` — default, element and children receive events
319
+ * - `'none'` — element and children are invisible to events (pass through)
320
+ * - `'box-none'` — element ignores events but children can receive them
321
+ * - `'box-only'` — element receives events but children cannot
322
+ */
323
+ readonly pointerEvents?: PointerEventsMode;
324
+
325
+ /**
326
+ * Opacity of the element (0 = fully transparent, 1 = fully opaque).
327
+ *
328
+ * When set explicitly, overrides the automatic `0.5` opacity applied by `disabled`.
329
+ */
330
+ readonly opacity?: number;
331
+
251
332
  // ── Appearance ──
252
333
 
334
+ /**
335
+ * Color theme for this Frame's visual rendering (background, border, text).
336
+ *
337
+ * Selects which of the 6 themes to use from the resolved tokens.
338
+ * Does not affect scheme selection — use `scheme` for that.
339
+ *
340
+ * @default 'primary'
341
+ *
342
+ * @example
343
+ * ```tsx
344
+ * <Frame theme="error" appearance="tinted">
345
+ * <Text>Error banner</Text>
346
+ * </Frame>
347
+ * ```
348
+ */
349
+ readonly theme?: ThemeName;
350
+
351
+ /**
352
+ * Appearance variant within the selected theme.
353
+ *
354
+ * Controls the visual emphasis of the Frame's chrome (background, border):
355
+ * - `'main'` — default surface (passive contrast)
356
+ * - `'emphasis'` — prominent, filled surface (active contrast)
357
+ * - `'tinted'` — subtle tinted surface
358
+ * - `'strong'` — bold, high-contrast variant
359
+ *
360
+ * @default 'main'
361
+ *
362
+ * @example
363
+ * ```tsx
364
+ * <Frame theme="primary" appearance="emphasis">
365
+ * <Text>CTA section</Text>
366
+ * </Frame>
367
+ * ```
368
+ */
369
+ readonly appearance?: AppearanceName;
370
+
253
371
  /**
254
372
  * Border radius.
255
373
  *
@@ -17,5 +17,9 @@ export type {
17
17
  Direction,
18
18
  Alignment,
19
19
  Justification,
20
+ PositionType,
21
+ OffsetValue,
22
+ OverflowMode,
23
+ PointerEventsMode,
20
24
  } from './Frame.types';
21
25
  export type { ResolvedCorners } from './Frame.utils';
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Text, type TextStyle } from 'react-native';
3
- import { useTokens } from 'newtone-api';
3
+ import { useTokens, useFrameContext } from 'newtone-api';
4
4
  import type { IconProps } from './Icon.types';
5
5
 
6
6
  /**
@@ -17,8 +17,8 @@ import type { IconProps } from './Icon.types';
17
17
  * ```
18
18
  */
19
19
  export function Icon({
20
- name,
21
- size,
20
+ name = 'add',
21
+ size = 24,
22
22
  opticalSize,
23
23
  fill = 0,
24
24
  color,
@@ -32,6 +32,9 @@ export function Icon({
32
32
  }: IconProps) {
33
33
  // Inherit tokens from nearest parent Frame via FrameContext.
34
34
  const tokens = useTokens();
35
+ const frameCtx = useFrameContext();
36
+ const resolvedTheme = frameCtx?.theme ?? 'primary';
37
+ const resolvedAppearance = frameCtx?.appearance ?? 'main';
35
38
 
36
39
  // Build the icon's style from the theme tokens and props.
37
40
  // Wrapped in useMemo so it only recalculates when the inputs change,
@@ -53,8 +56,8 @@ export function Icon({
53
56
  // Use explicit opticalSize if provided, otherwise auto-calculate from fontSize.
54
57
  const opsz = opticalSize ?? getOpticalSize(fontSize);
55
58
 
56
- // Use the provided color, or fall back to the theme's primary text color.
57
- const iconColor = color ?? tokens.textPrimary[tokens.gamut];
59
+ // Use the provided color, or fall back to the inherited theme/appearance text color.
60
+ const iconColor = color ?? tokens.colors[resolvedTheme][resolvedAppearance].fontPrimary;
58
61
 
59
62
  // Build the font family name from the theme's icon variant setting.
60
63
  // Example: variant 'rounded' → 'Material Symbols Rounded'
@@ -80,7 +83,7 @@ export function Icon({
80
83
  fontVariationSettings, // web-only: controls the variable font axes listed above
81
84
  ...style,
82
85
  } as TextStyle; // Cast needed because web-only properties aren't in RN's type definitions
83
- }, [tokens, size, opticalSize, fill, color, style]);
86
+ }, [tokens, size, opticalSize, fill, color, style, resolvedTheme, resolvedAppearance]);
84
87
 
85
88
  // Material Symbols renders icons as text ligatures — the icon name (like "home")
86
89
  // is passed as text content, and the font renders it as the icon glyph.
@@ -23,9 +23,9 @@ export interface IconProps {
23
23
  * @example `'home'`, `'settings'`, `'check'`, `'expand_more'`, `'delete'`, `'add'`, `'search'`
24
24
  * @see {@link https://fonts.google.com/icons Browse all icons}
25
25
  */
26
- readonly name: string;
26
+ readonly name?: string;
27
27
 
28
- /** Font size in pixels. @default tokens.typography.fontSizes['05'] (16px) */
28
+ /** Font size in pixels. @default 24 */
29
29
  readonly size?: number;
30
30
 
31
31
  /** Optical size for variable font axis. Adjusts stroke weight for readability at small sizes. @default same as size */
@@ -1,7 +1,8 @@
1
1
  import React, { useContext, useMemo } from 'react';
2
2
  import { Text as RNText } from 'react-native';
3
3
  import type { TextStyle } from 'react-native';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
+ import type { ThemeName, AppearanceName } from 'newtone-api';
5
6
  import { TextScopeContext, resolveTextColor } from './Text';
6
7
  import type { TextSpanProps, TextWeight } from './Text.types';
7
8
 
@@ -11,18 +12,21 @@ import type { TextSpanProps, TextWeight } from './Text.types';
11
12
  * Only inline formatting properties (color, weight, italic, underline, highlight) are exposed.
12
13
  */
13
14
  export function TextSpan({ children, color, weight, italic, underline, highlight, style }: TextSpanProps) {
14
- const tokens = useTokens(1);
15
+ const tokens = useTokens();
15
16
  const scopeCtx = useContext(TextScopeContext);
17
+ const frameCtx = useFrameContext();
18
+ const resolvedTheme: ThemeName = frameCtx?.theme ?? 'primary';
19
+ const resolvedAppearance: AppearanceName = frameCtx?.appearance ?? 'main';
16
20
 
17
21
  const spanStyle = useMemo<TextStyle>(() => {
18
22
  const s: TextStyle = {};
19
- if (color) s.color = resolveTextColor(color, tokens);
23
+ if (color) s.color = resolveTextColor(color, tokens, resolvedTheme, resolvedAppearance);
20
24
  if (weight && scopeCtx) s.fontWeight = String(scopeCtx.weights[weight]) as TextStyle['fontWeight'];
21
25
  if (italic) s.fontStyle = 'italic';
22
26
  if (underline) s.textDecorationLine = 'underline';
23
- if (highlight) s.backgroundColor = resolveTextColor(highlight, tokens);
27
+ if (highlight) s.backgroundColor = resolveTextColor(highlight, tokens, resolvedTheme, resolvedAppearance);
24
28
  return s;
25
- }, [tokens, scopeCtx, color, weight, italic, underline, highlight]);
29
+ }, [tokens, scopeCtx, color, weight, italic, underline, highlight, resolvedTheme, resolvedAppearance]);
26
30
 
27
31
  return React.createElement(
28
32
  RNText,
@@ -4,8 +4,10 @@ import type { LayoutChangeEvent, TextStyle } from 'react-native';
4
4
  import { resolveResponsiveSize, estimateLineWidths, BREAKPOINT_ROLE_SCALE, scaleRoleStep, REFERENCE_LINE_HEIGHT_RATIO, buildFontFeatureSettings, SEMANTIC_WEIGHT_MAP, ROLE_DEFAULT_WEIGHTS } from '@newtonedev/fonts';
5
5
  import { useTokens } from 'newtone-api';
6
6
  import { useNewtoneTheme } from 'newtone-api';
7
+ import { useFrameContext } from 'newtone-api';
7
8
  import type { UseTokensResult } from 'newtone-api';
8
- import type { TextProps, TextColor } from './Text.types';
9
+ import type { ThemeName, AppearanceName } from 'newtone-api';
10
+ import type { TextProps, TextColor, TextRole } from './Text.types';
9
11
  import { useLocalCalibration } from 'newtone-api';
10
12
  import { useTypographyCalibrations } from 'newtone-api';
11
13
  import { enqueueObservation } from 'newtone-api';
@@ -21,21 +23,27 @@ export const TextScopeContext = createContext<{
21
23
  readonly weights: { readonly regular: number; readonly medium: number; readonly bold: number };
22
24
  } | null>(null);
23
25
 
26
+ /** Roles considered "large text" — accent uses accentLarge (lighter). */
27
+ const LARGE_TEXT_ROLES = new Set<TextRole>(['headline', 'title', 'heading', 'subheading']);
28
+
24
29
  /**
25
30
  * Resolve a semantic text color to a hex string from the current tokens.
26
- * Neutral text colors are top-level; palette colors use nested PaletteTokens.fill.
31
+ * Neutral colors use the inherited theme/appearance from the nearest Frame.
32
+ * Accent uses accentLarge (large text) or accentSmall (small text) from the inherited theme/appearance.
27
33
  */
28
- export function resolveTextColor(color: TextColor, tokens: UseTokensResult): string {
29
- const { gamut } = tokens;
34
+ export function resolveTextColor(
35
+ color: TextColor,
36
+ tokens: UseTokensResult,
37
+ theme: ThemeName = 'primary',
38
+ appearance: AppearanceName = 'main',
39
+ role: TextRole = 'body',
40
+ ): string {
30
41
  switch (color) {
31
- case 'primary': return tokens.textPrimary[gamut];
32
- case 'secondary': return tokens.textSecondary[gamut];
33
- case 'tertiary': return tokens.textTertiary[gamut];
34
- case 'disabled': return tokens.textDisabled[gamut];
35
- case 'accent': return tokens.accent.fill[gamut];
36
- case 'success': return tokens.success.fill[gamut];
37
- case 'warning': return tokens.warning.fill[gamut];
38
- case 'error': return tokens.error.fill[gamut];
42
+ case 'primary': return tokens.colors[theme][appearance].fontPrimary;
43
+ case 'secondary': return tokens.colors[theme][appearance].fontSecondary;
44
+ case 'tertiary': return tokens.colors[theme][appearance].fontTertiary;
45
+ case 'disabled': return tokens.colors[theme][appearance].fontDisabled;
46
+ case 'accent': return tokens.colors[theme][appearance][LARGE_TEXT_ROLES.has(role) ? 'accentLarge' : 'accentSmall'];
39
47
  }
40
48
  }
41
49
 
@@ -90,7 +98,7 @@ function TextBase({
90
98
  weight: weightOverride,
91
99
  align,
92
100
  numberOfLines,
93
- elevation = 1,
101
+ elevation,
94
102
  style,
95
103
  accessibilityRole: accessibilityRoleOverride,
96
104
  testID,
@@ -102,6 +110,9 @@ function TextBase({
102
110
  }: TextProps) {
103
111
  const tokens = useTokens(elevation);
104
112
  const { config, reportingEndpoint } = useNewtoneTheme();
113
+ const frameCtx = useFrameContext();
114
+ const resolvedTheme: ThemeName = frameCtx?.theme ?? 'primary';
115
+ const resolvedAppearance: AppearanceName = frameCtx?.appearance ?? 'main';
105
116
 
106
117
  const size = sizeOverride ?? 'md';
107
118
  const fontSlot = tokens.typography.fonts[scope];
@@ -195,13 +206,13 @@ function TextBase({
195
206
  fontFamily: fontSlot.family,
196
207
  fontSize: activeStep.fontSize,
197
208
  fontWeight: String(resolvedFontWeight) as TextStyle['fontWeight'],
198
- color: resolveTextColor(color, tokens),
209
+ color: resolveTextColor(color, tokens, resolvedTheme, resolvedAppearance, role),
199
210
  lineHeight: correctedLineHeight,
200
211
  textAlign: align,
201
212
  ...(vcOffset !== 0 ? { transform: [{ translateY: vcOffset }] } : {}),
202
213
  ...(featureSettings ? { fontFeatureSettings: featureSettings } as any : {}),
203
214
  };
204
- }, [tokens, fontSlot, step, resolvedStep, responsive, isAdaptive, resolvedFontWeight, color, align, config.typography.fontMetrics, centerVertically, features]);
215
+ }, [tokens, fontSlot, step, resolvedStep, responsive, isAdaptive, resolvedFontWeight, color, align, config.typography.fontMetrics, centerVertically, features, resolvedTheme, resolvedAppearance]);
205
216
 
206
217
  // Auto-derive accessibility role and heading level for heading-like typography roles.
207
218
  // react-native-web uses aria-level to render the correct <h1>/<h2>/<h3> element.
@@ -8,7 +8,7 @@ export type TextSize = 'sm' | 'md' | 'lg';
8
8
  export type TextWeight = 'regular' | 'medium' | 'bold';
9
9
 
10
10
  /** Semantic text color tokens — resolved from the current theme's token palette. */
11
- export type TextColor = 'primary' | 'secondary' | 'tertiary' | 'disabled' | 'accent' | 'success' | 'warning' | 'error';
11
+ export type TextColor = 'primary' | 'secondary' | 'tertiary' | 'disabled' | 'accent';
12
12
 
13
13
  /** Font scope — selects which font family slot to use. @default 'main' */
14
14
  export type TextScope = 'main' | 'display' | 'mono' | 'currency';
@@ -66,10 +66,7 @@ export interface TextProps {
66
66
  * - `'secondary'` — Subdued/muted text (captions, labels)
67
67
  * - `'tertiary'` — Hints, placeholders
68
68
  * - `'disabled'` — Disabled text elements
69
- * - `'accent'` — Accent palette color for links/actions
70
- * - `'success'` — Success palette color for positive indicators
71
- * - `'warning'` — Warning palette color for caution indicators
72
- * - `'error'` — Error palette color for destructive/error indicators
69
+ * - `'accent'` — Accent color from the inherited theme/appearance (accentLarge for large text, accentSmall for small text)
73
70
  *
74
71
  * @default 'primary'
75
72
  */
@@ -89,7 +86,7 @@ export interface TextProps {
89
86
  /** Maximum number of lines before truncation with ellipsis. When omitted, text wraps freely. */
90
87
  readonly numberOfLines?: number;
91
88
 
92
- /** Elevation level for token computation. @default 1 */
89
+ /** Elevation level for token computation. When omitted, inherits from nearest parent Frame. */
93
90
  readonly elevation?: ElevationLevel;
94
91
 
95
92
  /** Style overrides (applied last). Supports a single style or an array of styles. */
@@ -8,6 +8,9 @@ import type {
8
8
  PaddingProp,
9
9
  GapProp,
10
10
  SizingMode,
11
+ PositionType,
12
+ OffsetValue,
13
+ OverflowMode,
11
14
  } from '../Frame/Frame.types';
12
15
  import {
13
16
  resolvePadding,
@@ -33,6 +36,16 @@ export interface WrapperStyleInput {
33
36
  readonly maxWidth?: number;
34
37
  readonly minHeight?: number;
35
38
  readonly maxHeight?: number;
39
+
40
+ // Positioning
41
+ readonly position?: PositionType;
42
+ readonly top?: OffsetValue;
43
+ readonly right?: OffsetValue;
44
+ readonly bottom?: OffsetValue;
45
+ readonly left?: OffsetValue;
46
+ readonly zIndex?: number;
47
+ readonly overflow?: OverflowMode;
48
+ readonly opacity?: number;
36
49
  }
37
50
 
38
51
  /**
@@ -58,6 +71,14 @@ export function getWrapperStyles(input: WrapperStyleInput): ViewStyle {
58
71
  maxWidth,
59
72
  minHeight,
60
73
  maxHeight,
74
+ position,
75
+ top,
76
+ right,
77
+ bottom,
78
+ left,
79
+ zIndex,
80
+ overflow,
81
+ opacity,
61
82
  } = input;
62
83
 
63
84
  // We build styles as a plain object first, then validate it through
@@ -107,6 +128,17 @@ export function getWrapperStyles(input: WrapperStyleInput): ViewStyle {
107
128
  if (minHeight !== undefined) container.minHeight = minHeight;
108
129
  if (maxHeight !== undefined) container.maxHeight = maxHeight;
109
130
 
131
+ // ── Positioning ──
132
+ // Set CSS position mode and offsets for absolute/fixed/sticky positioning.
133
+ if (position) container.position = position;
134
+ if (top !== undefined) container.top = top;
135
+ if (right !== undefined) container.right = right;
136
+ if (bottom !== undefined) container.bottom = bottom;
137
+ if (left !== undefined) container.left = left;
138
+ if (zIndex !== undefined) container.zIndex = zIndex;
139
+ if (overflow) container.overflow = overflow;
140
+ if (opacity !== undefined) container.opacity = opacity;
141
+
110
142
  // Pass through StyleSheet.create() to validate and optimize the styles,
111
143
  // then extract the single style object with `.c`.
112
144
  return StyleSheet.create({ c: container as ViewStyle }).c;
@@ -44,6 +44,16 @@ export function Wrapper({
44
44
  maxWidth,
45
45
  minHeight,
46
46
  maxHeight,
47
+ // Positioning
48
+ position,
49
+ top,
50
+ right,
51
+ bottom,
52
+ left,
53
+ zIndex,
54
+ overflow,
55
+ pointerEvents,
56
+ opacity,
47
57
  style,
48
58
  // Testing & platform
49
59
  testID,
@@ -51,9 +61,8 @@ export function Wrapper({
51
61
  ref,
52
62
  }: WrapperProps) {
53
63
  // Get the theme's design tokens so we can convert spacing names (like 'md')
54
- // into pixel values. The "1" is the default elevation level Wrapper doesn't
55
- // have its own elevation, but tokens need one for the spacing lookups.
56
- const tokens = useTokens(1);
64
+ // into pixel values. Wrapper inherits elevation from FrameContext automatically.
65
+ const tokens = useTokens();
57
66
 
58
67
  // Calculate the layout styles (direction, spacing, alignment, sizing).
59
68
  // Wrapped in useMemo so it only recalculates when one of the props changes,
@@ -74,11 +83,20 @@ export function Wrapper({
74
83
  maxWidth,
75
84
  minHeight,
76
85
  maxHeight,
86
+ position,
87
+ top,
88
+ right,
89
+ bottom,
90
+ left,
91
+ zIndex,
92
+ overflow,
93
+ opacity,
77
94
  }),
78
95
  [
79
96
  tokens, direction, wrap, reverse,
80
97
  align, justify, padding, gap,
81
98
  width, height, minWidth, maxWidth, minHeight, maxHeight,
99
+ position, top, right, bottom, left, zIndex, overflow, opacity,
82
100
  ],
83
101
  );
84
102
 
@@ -93,6 +111,7 @@ export function Wrapper({
93
111
  ref={ref}
94
112
  testID={testID}
95
113
  nativeID={nativeID}
114
+ pointerEvents={pointerEvents}
96
115
  // Wrapper is a layout-only container with no semantic meaning.
97
116
  // "none" tells screen readers to skip this element and read its children directly.
98
117
  accessibilityRole="none"
@@ -6,6 +6,10 @@ import type {
6
6
  PaddingProp,
7
7
  GapProp,
8
8
  SizingMode,
9
+ PositionType,
10
+ OffsetValue,
11
+ OverflowMode,
12
+ PointerEventsMode,
9
13
  } from '../Frame/Frame.types';
10
14
 
11
15
  /**
@@ -131,6 +135,47 @@ export interface WrapperProps {
131
135
  /** Maximum height in pixels. */
132
136
  readonly maxHeight?: number;
133
137
 
138
+ // ── Positioning ──
139
+
140
+ /**
141
+ * CSS position mode.
142
+ *
143
+ * `'fixed'` and `'sticky'` are web-only (supported via react-native-web).
144
+ * React Native natively supports `'absolute'` and `'relative'`.
145
+ */
146
+ readonly position?: PositionType;
147
+
148
+ /** Offset from the top edge. Accepts pixels (number) or percentage string. */
149
+ readonly top?: OffsetValue;
150
+
151
+ /** Offset from the right edge. Accepts pixels (number) or percentage string. */
152
+ readonly right?: OffsetValue;
153
+
154
+ /** Offset from the bottom edge. Accepts pixels (number) or percentage string. */
155
+ readonly bottom?: OffsetValue;
156
+
157
+ /** Offset from the left edge. Accepts pixels (number) or percentage string. */
158
+ readonly left?: OffsetValue;
159
+
160
+ /** Stacking order. Higher values render above lower values. */
161
+ readonly zIndex?: number;
162
+
163
+ /** Content overflow behavior. */
164
+ readonly overflow?: OverflowMode;
165
+
166
+ /**
167
+ * Controls whether the element can be the target of touch/pointer events.
168
+ *
169
+ * - `'auto'` — default, element and children receive events
170
+ * - `'none'` — element and children are invisible to events (pass through)
171
+ * - `'box-none'` — element ignores events but children can receive them
172
+ * - `'box-only'` — element receives events but children cannot
173
+ */
174
+ readonly pointerEvents?: PointerEventsMode;
175
+
176
+ /** Opacity of the element (0 = fully transparent, 1 = fully opaque). */
177
+ readonly opacity?: number;
178
+
134
179
  // ── Testing & Platform ──
135
180
 
136
181
  /** Test identifier — maps to `data-testid` on web. Used by testing libraries. */