@newtonedev/components 0.1.13 → 0.1.15

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 (173) hide show
  1. package/dist/composites/actions/Button/Button.d.ts +17 -20
  2. package/dist/composites/actions/Button/Button.d.ts.map +1 -1
  3. package/dist/composites/actions/Button/Button.styles.d.ts +12 -24
  4. package/dist/composites/actions/Button/Button.styles.d.ts.map +1 -1
  5. package/dist/composites/actions/Button/Button.types.d.ts +14 -13
  6. package/dist/composites/actions/Button/Button.types.d.ts.map +1 -1
  7. package/dist/composites/actions/Button/index.d.ts +1 -1
  8. package/dist/composites/actions/Button/index.d.ts.map +1 -1
  9. package/dist/composites/branding/LogoMonogram/LogoMonogram.d.ts +10 -0
  10. package/dist/composites/branding/LogoMonogram/LogoMonogram.d.ts.map +1 -0
  11. package/dist/composites/branding/LogoMonogram/LogoMonogram.types.d.ts +35 -0
  12. package/dist/composites/branding/LogoMonogram/LogoMonogram.types.d.ts.map +1 -0
  13. package/dist/composites/branding/LogoMonogram/index.d.ts +3 -0
  14. package/dist/composites/branding/LogoMonogram/index.d.ts.map +1 -0
  15. package/dist/composites/branding/LogoWordmark/LogoWordmark.d.ts +9 -0
  16. package/dist/composites/branding/LogoWordmark/LogoWordmark.d.ts.map +1 -0
  17. package/dist/composites/branding/LogoWordmark/LogoWordmark.types.d.ts +26 -0
  18. package/dist/composites/branding/LogoWordmark/LogoWordmark.types.d.ts.map +1 -0
  19. package/dist/composites/branding/LogoWordmark/index.d.ts +3 -0
  20. package/dist/composites/branding/LogoWordmark/index.d.ts.map +1 -0
  21. package/dist/composites/display/Chip/Chip.d.ts +25 -0
  22. package/dist/composites/display/Chip/Chip.d.ts.map +1 -0
  23. package/dist/composites/display/Chip/Chip.styles.d.ts +29 -0
  24. package/dist/composites/display/Chip/Chip.styles.d.ts.map +1 -0
  25. package/dist/composites/display/Chip/Chip.types.d.ts +63 -0
  26. package/dist/composites/display/Chip/Chip.types.d.ts.map +1 -0
  27. package/dist/composites/display/Chip/index.d.ts +3 -0
  28. package/dist/composites/display/Chip/index.d.ts.map +1 -0
  29. package/dist/composites/form-controls/Select/Select.d.ts.map +1 -1
  30. package/dist/composites/form-controls/Select/Select.styles.d.ts +2 -2
  31. package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -1
  32. package/dist/composites/form-controls/Select/SelectOption.d.ts.map +1 -1
  33. package/dist/composites/form-controls/TextInput/TextInput.d.ts.map +1 -1
  34. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts +2 -2
  35. package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -1
  36. package/dist/composites/form-controls/Toggle/Toggle.d.ts.map +1 -1
  37. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts +2 -2
  38. package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -1
  39. package/dist/composites/layout/AppShell/AppShell.d.ts.map +1 -1
  40. package/dist/composites/layout/AppShell/AppShell.styles.d.ts +2 -2
  41. package/dist/composites/layout/AppShell/AppShell.styles.d.ts.map +1 -1
  42. package/dist/composites/layout/Card/Card.d.ts.map +1 -1
  43. package/dist/composites/layout/Card/Card.styles.d.ts +2 -2
  44. package/dist/composites/layout/Card/Card.styles.d.ts.map +1 -1
  45. package/dist/composites/layout/ContentCard/ContentCard.d.ts +33 -0
  46. package/dist/composites/layout/ContentCard/ContentCard.d.ts.map +1 -0
  47. package/dist/composites/layout/ContentCard/ContentCard.styles.d.ts +10 -0
  48. package/dist/composites/layout/ContentCard/ContentCard.styles.d.ts.map +1 -0
  49. package/dist/composites/layout/ContentCard/ContentCard.types.d.ts +52 -0
  50. package/dist/composites/layout/ContentCard/ContentCard.types.d.ts.map +1 -0
  51. package/dist/composites/layout/ContentCard/index.d.ts +3 -0
  52. package/dist/composites/layout/ContentCard/index.d.ts.map +1 -0
  53. package/dist/composites/layout/Divider/Divider.d.ts +25 -0
  54. package/dist/composites/layout/Divider/Divider.d.ts.map +1 -0
  55. package/dist/composites/layout/Divider/Divider.styles.d.ts +8 -0
  56. package/dist/composites/layout/Divider/Divider.styles.d.ts.map +1 -0
  57. package/dist/composites/layout/Divider/Divider.types.d.ts +25 -0
  58. package/dist/composites/layout/Divider/Divider.types.d.ts.map +1 -0
  59. package/dist/composites/layout/Divider/index.d.ts +3 -0
  60. package/dist/composites/layout/Divider/index.d.ts.map +1 -0
  61. package/dist/composites/layout/Navbar/Navbar.d.ts.map +1 -1
  62. package/dist/composites/layout/Navbar/Navbar.styles.d.ts +4 -3
  63. package/dist/composites/layout/Navbar/Navbar.styles.d.ts.map +1 -1
  64. package/dist/composites/layout/Sidebar/Sidebar.d.ts.map +1 -1
  65. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts +4 -3
  66. package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts.map +1 -1
  67. package/dist/composites/overlays/Popover/Popover.d.ts.map +1 -1
  68. package/dist/composites/overlays/Popover/Popover.styles.d.ts +2 -2
  69. package/dist/composites/overlays/Popover/Popover.styles.d.ts.map +1 -1
  70. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts.map +1 -1
  71. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts +2 -2
  72. package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -1
  73. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts +2 -2
  74. package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -1
  75. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts +2 -2
  76. package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -1
  77. package/dist/index.cjs +935 -523
  78. package/dist/index.cjs.map +1 -1
  79. package/dist/index.d.ts +13 -3
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +860 -473
  82. package/dist/index.js.map +1 -1
  83. package/dist/primitives/Frame/Frame.d.ts +1 -35
  84. package/dist/primitives/Frame/Frame.d.ts.map +1 -1
  85. package/dist/primitives/Frame/Frame.styles.d.ts +13 -4
  86. package/dist/primitives/Frame/Frame.styles.d.ts.map +1 -1
  87. package/dist/primitives/Frame/Frame.types.d.ts +99 -1
  88. package/dist/primitives/Frame/Frame.types.d.ts.map +1 -1
  89. package/dist/primitives/Frame/index.d.ts +1 -1
  90. package/dist/primitives/Frame/index.d.ts.map +1 -1
  91. package/dist/primitives/Icon/Icon.d.ts.map +1 -1
  92. package/dist/primitives/Icon/Icon.types.d.ts +2 -2
  93. package/dist/primitives/Icon/Icon.types.d.ts.map +1 -1
  94. package/dist/primitives/Text/Text.d.ts +5 -3
  95. package/dist/primitives/Text/Text.d.ts.map +1 -1
  96. package/dist/primitives/Text/Text.spans.d.ts.map +1 -1
  97. package/dist/primitives/Text/Text.types.d.ts +3 -6
  98. package/dist/primitives/Text/Text.types.d.ts.map +1 -1
  99. package/dist/primitives/Wrapper/Wrapper.d.ts +1 -1
  100. package/dist/primitives/Wrapper/Wrapper.d.ts.map +1 -1
  101. package/dist/primitives/Wrapper/Wrapper.styles.d.ts +9 -1
  102. package/dist/primitives/Wrapper/Wrapper.styles.d.ts.map +1 -1
  103. package/dist/primitives/Wrapper/Wrapper.types.d.ts +31 -1
  104. package/dist/primitives/Wrapper/Wrapper.types.d.ts.map +1 -1
  105. package/dist/registry/registry.d.ts.map +1 -1
  106. package/package.json +1 -1
  107. package/src/composites/actions/Button/Button.styles.ts +90 -182
  108. package/src/composites/actions/Button/Button.tsx +37 -33
  109. package/src/composites/actions/Button/Button.types.ts +16 -15
  110. package/src/composites/actions/Button/index.ts +1 -1
  111. package/src/composites/branding/LogoMonogram/LogoMonogram.tsx +29 -0
  112. package/src/composites/branding/LogoMonogram/LogoMonogram.types.ts +35 -0
  113. package/src/composites/branding/LogoMonogram/index.ts +2 -0
  114. package/src/composites/branding/LogoWordmark/LogoWordmark.tsx +29 -0
  115. package/src/composites/branding/LogoWordmark/LogoWordmark.types.ts +25 -0
  116. package/src/composites/branding/LogoWordmark/index.ts +2 -0
  117. package/src/composites/display/Chip/Chip.styles.ts +189 -0
  118. package/src/composites/display/Chip/Chip.tsx +97 -0
  119. package/src/composites/display/Chip/Chip.types.ts +74 -0
  120. package/src/composites/display/Chip/index.ts +2 -0
  121. package/src/composites/form-controls/Select/Select.styles.ts +10 -10
  122. package/src/composites/form-controls/Select/Select.tsx +9 -6
  123. package/src/composites/form-controls/Select/SelectOption.tsx +10 -7
  124. package/src/composites/form-controls/TextInput/TextInput.styles.ts +12 -8
  125. package/src/composites/form-controls/TextInput/TextInput.tsx +7 -4
  126. package/src/composites/form-controls/Toggle/Toggle.styles.ts +10 -7
  127. package/src/composites/form-controls/Toggle/Toggle.tsx +4 -3
  128. package/src/composites/layout/AppShell/AppShell.styles.ts +8 -3
  129. package/src/composites/layout/AppShell/AppShell.tsx +6 -2
  130. package/src/composites/layout/Card/Card.styles.ts +10 -4
  131. package/src/composites/layout/Card/Card.tsx +4 -3
  132. package/src/composites/layout/ContentCard/ContentCard.styles.ts +44 -0
  133. package/src/composites/layout/ContentCard/ContentCard.tsx +71 -0
  134. package/src/composites/layout/ContentCard/ContentCard.types.ts +60 -0
  135. package/src/composites/layout/ContentCard/index.ts +2 -0
  136. package/src/composites/layout/Divider/Divider.styles.ts +30 -0
  137. package/src/composites/layout/Divider/Divider.tsx +46 -0
  138. package/src/composites/layout/Divider/Divider.types.ts +28 -0
  139. package/src/composites/layout/Divider/index.ts +2 -0
  140. package/src/composites/layout/Navbar/Navbar.styles.ts +7 -5
  141. package/src/composites/layout/Navbar/Navbar.tsx +4 -3
  142. package/src/composites/layout/Sidebar/Sidebar.styles.ts +7 -5
  143. package/src/composites/layout/Sidebar/Sidebar.tsx +4 -3
  144. package/src/composites/overlays/Popover/Popover.styles.ts +7 -5
  145. package/src/composites/overlays/Popover/Popover.tsx +4 -3
  146. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.ts +5 -5
  147. package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.tsx +4 -3
  148. package/src/composites/range-inputs/HueSlider/HueSlider.styles.ts +7 -7
  149. package/src/composites/range-inputs/HueSlider/HueSlider.tsx +1 -1
  150. package/src/composites/range-inputs/Slider/Slider.styles.ts +9 -9
  151. package/src/composites/range-inputs/Slider/Slider.tsx +1 -1
  152. package/src/index.ts +49 -10
  153. package/src/primitives/Frame/Frame.styles.ts +55 -12
  154. package/src/primitives/Frame/Frame.tsx +139 -140
  155. package/src/primitives/Frame/Frame.types.ts +119 -1
  156. package/src/primitives/Frame/index.ts +4 -0
  157. package/src/primitives/Icon/Icon.tsx +9 -6
  158. package/src/primitives/Icon/Icon.types.ts +2 -2
  159. package/src/primitives/Text/Text.spans.ts +9 -5
  160. package/src/primitives/Text/Text.tsx +26 -15
  161. package/src/primitives/Text/Text.types.ts +3 -6
  162. package/src/primitives/Wrapper/Wrapper.styles.ts +32 -0
  163. package/src/primitives/Wrapper/Wrapper.tsx +22 -3
  164. package/src/primitives/Wrapper/Wrapper.types.ts +45 -0
  165. package/src/registry/registry.ts +5 -21
  166. package/dist/_COMPONENT_TEMPLATE/ComponentName.d.ts +0 -70
  167. package/dist/_COMPONENT_TEMPLATE/ComponentName.d.ts.map +0 -1
  168. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts +0 -23
  169. package/dist/_COMPONENT_TEMPLATE/ComponentName.styles.d.ts.map +0 -1
  170. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts +0 -45
  171. package/dist/_COMPONENT_TEMPLATE/ComponentName.types.d.ts.map +0 -1
  172. package/dist/_COMPONENT_TEMPLATE/index.d.ts +0 -3
  173. package/dist/_COMPONENT_TEMPLATE/index.d.ts.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
4
  const TRACK_WIDTH = 40;
5
5
  const TRACK_HEIGHT = 22;
@@ -8,10 +8,13 @@ const THUMB_OFFSET = 2;
8
8
 
9
9
  export function getToggleStyles(
10
10
  tokens: ResolvedTokens,
11
- gamut: ColorGamut,
12
11
  value: boolean,
13
- disabled: boolean
12
+ disabled: boolean,
13
+ theme: ThemeName = 'primary',
14
+ appearance: AppearanceName = 'main',
14
15
  ) {
16
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
17
+ const emphasisAt: AppearanceTokens = tokens.colors[theme].emphasis;
15
18
  return StyleSheet.create({
16
19
  container: {
17
20
  flexDirection: 'row',
@@ -23,15 +26,15 @@ export function getToggleStyles(
23
26
  fontFamily: tokens.typography.fonts.main.family,
24
27
  fontSize: tokens.typography.fontSizes['04'],
25
28
  fontWeight: tokens.typography.fonts.main.weights.medium as any,
26
- color: tokens.textSecondary[gamut],
29
+ color: at.fontTertiary,
27
30
  },
28
31
  track: {
29
32
  width: TRACK_WIDTH,
30
33
  height: TRACK_HEIGHT,
31
34
  borderRadius: TRACK_HEIGHT / 2,
32
35
  backgroundColor: value
33
- ? tokens.accent.fill[gamut]
34
- : tokens.border[gamut],
36
+ ? emphasisAt.divider
37
+ : at.fontSecondary,
35
38
  justifyContent: 'center',
36
39
  paddingHorizontal: THUMB_OFFSET,
37
40
  },
@@ -39,7 +42,7 @@ export function getToggleStyles(
39
42
  width: THUMB_SIZE,
40
43
  height: THUMB_SIZE,
41
44
  borderRadius: THUMB_SIZE / 2,
42
- backgroundColor: tokens.background[gamut],
45
+ backgroundColor: at.background,
43
46
  alignSelf: value ? 'flex-end' : 'flex-start',
44
47
  },
45
48
  });
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View, Text, Pressable } from 'react-native';
3
3
  import type { ToggleProps } from './Toggle.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getToggleStyles } from './Toggle.styles';
6
6
 
7
7
  export function Toggle({
@@ -12,10 +12,11 @@ export function Toggle({
12
12
  style,
13
13
  }: ToggleProps) {
14
14
  const tokens = useTokens(1);
15
+ const frameCtx = useFrameContext();
15
16
 
16
17
  const styles = React.useMemo(
17
- () => getToggleStyles(tokens, tokens.gamut, value, disabled),
18
- [tokens, value, disabled]
18
+ () => getToggleStyles(tokens, value, disabled, frameCtx?.theme, frameCtx?.appearance),
19
+ [tokens, value, disabled, frameCtx?.theme, frameCtx?.appearance]
19
20
  );
20
21
 
21
22
  const handlePress = React.useCallback(() => {
@@ -1,13 +1,18 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
- export function getAppShellStyles(tokens: ResolvedTokens, gamut: ColorGamut) {
4
+ export function getAppShellStyles(
5
+ tokens: ResolvedTokens,
6
+ theme: ThemeName = 'primary',
7
+ appearance: AppearanceName = 'main',
8
+ ) {
9
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
5
10
  return StyleSheet.create({
6
11
  container: {
7
12
  flex: 1,
8
13
  flexDirection: 'row',
9
14
  overflow: 'hidden',
10
- backgroundColor: tokens.background[gamut],
15
+ backgroundColor: at.background,
11
16
  },
12
17
  main: {
13
18
  flex: 1,
@@ -1,12 +1,16 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { AppShellProps } from './AppShell.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getAppShellStyles } from './AppShell.styles';
6
6
 
7
7
  export function AppShell({ sidebar, children }: AppShellProps) {
8
8
  const tokens = useTokens();
9
- const styles = React.useMemo(() => getAppShellStyles(tokens, tokens.gamut), [tokens]);
9
+ const frameCtx = useFrameContext();
10
+ const styles = React.useMemo(
11
+ () => getAppShellStyles(tokens, frameCtx?.theme, frameCtx?.appearance),
12
+ [tokens, frameCtx?.theme, frameCtx?.appearance]
13
+ );
10
14
 
11
15
  return (
12
16
  <View style={styles.container}>
@@ -1,12 +1,18 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
- export function getCardStyles(tokens: ResolvedTokens, gamut: ColorGamut, disabled: boolean) {
4
+ export function getCardStyles(
5
+ tokens: ResolvedTokens,
6
+ disabled: boolean,
7
+ theme: ThemeName = 'primary',
8
+ appearance: AppearanceName = 'main',
9
+ ) {
10
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
5
11
  return StyleSheet.create({
6
12
  container: {
7
- backgroundColor: tokens.background[gamut],
13
+ backgroundColor: at.background,
8
14
  borderWidth: 1,
9
- borderColor: tokens.border[gamut],
15
+ borderColor: at.fontSecondary,
10
16
  borderRadius: tokens.radius.lg,
11
17
  padding: tokens.spacing['16'],
12
18
  opacity: disabled ? 0.5 : 1,
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { CardProps } from './Card.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getCardStyles } from './Card.styles';
6
6
 
7
7
  export function Card({
@@ -11,10 +11,11 @@ export function Card({
11
11
  disabled = false,
12
12
  }: CardProps) {
13
13
  const tokens = useTokens(elevation);
14
+ const frameCtx = useFrameContext();
14
15
 
15
16
  const styles = React.useMemo(
16
- () => getCardStyles(tokens, tokens.gamut, disabled),
17
- [tokens, disabled]
17
+ () => getCardStyles(tokens, disabled, frameCtx?.theme, frameCtx?.appearance),
18
+ [tokens, disabled, frameCtx?.theme, frameCtx?.appearance]
18
19
  );
19
20
 
20
21
  return (
@@ -0,0 +1,44 @@
1
+ import type { ViewStyle } from 'react-native';
2
+ import type { UseTokensResult } from 'newtone-api';
3
+ import type { ContentCardVariant } from './ContentCard.types';
4
+
5
+ /**
6
+ * Compute variant-specific styles for ContentCard.
7
+ * Uses `as ViewStyle` for web-only properties (cursor, borderBottomStyle)
8
+ * that react-native-web supports but RN types don't include.
9
+ */
10
+ export function getContentCardStyles(
11
+ variant: ContentCardVariant,
12
+ isInteractive: boolean,
13
+ tokens: UseTokensResult
14
+ ): ViewStyle {
15
+ const dividerColor = tokens.colors.primary.main.divider;
16
+
17
+ const interactiveStyles = isInteractive
18
+ ? { cursor: 'pointer', textDecorationLine: 'none' } as ViewStyle
19
+ : {} as ViewStyle;
20
+
21
+ if (variant === 'elevated') {
22
+ return {
23
+ borderRadius: 12,
24
+ ...interactiveStyles,
25
+ } as ViewStyle;
26
+ }
27
+
28
+ if (variant === 'bordered') {
29
+ return {
30
+ borderWidth: 1,
31
+ borderColor: dividerColor,
32
+ borderStyle: 'solid',
33
+ borderRadius: 12,
34
+ ...interactiveStyles,
35
+ } as ViewStyle;
36
+ }
37
+
38
+ // flat variant — bottom border only
39
+ return {
40
+ borderBottomWidth: 1,
41
+ borderBottomColor: dividerColor,
42
+ ...interactiveStyles,
43
+ } as ViewStyle;
44
+ }
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import type { ContentCardProps } from './ContentCard.types';
3
+ import { getContentCardStyles } from './ContentCard.styles';
4
+ import { useTokens } from 'newtone-api';
5
+ import { Frame } from '../../../primitives/Frame/Frame';
6
+
7
+ /**
8
+ * ContentCard — A content container with three visual treatments.
9
+ *
10
+ * **Variants:**
11
+ * - `elevated` — raised surface with tinted background (hero cards, featured content)
12
+ * - `bordered` — outlined container (related items, previews)
13
+ * - `flat` — bottom-border only (list rows, compact items)
14
+ *
15
+ * Delegates to Frame for layout, elevation, appearance, and interactivity.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // Elevated hero card
20
+ * <ContentCard variant="elevated" href="/articles/intro">
21
+ * <Text role="heading" weight="bold">Featured Article</Text>
22
+ * <Text role="body" color="secondary">Article excerpt...</Text>
23
+ * </ContentCard>
24
+ *
25
+ * // Bordered card
26
+ * <ContentCard variant="bordered" onPress={() => navigate(slug)}>
27
+ * <Text role="body" weight="bold">Related Article</Text>
28
+ * </ContentCard>
29
+ *
30
+ * // Flat list item
31
+ * <ContentCard variant="flat" href={`/articles/${slug}`}>
32
+ * <Text role="body" weight="bold">{title}</Text>
33
+ * </ContentCard>
34
+ * ```
35
+ */
36
+ export function ContentCard({
37
+ children,
38
+ variant = 'bordered',
39
+ href,
40
+ onPress,
41
+ padding = 20,
42
+ gap = 8,
43
+ disabled = false,
44
+ style,
45
+ }: ContentCardProps) {
46
+ const tokens = useTokens();
47
+ const isInteractive = !!(href || onPress);
48
+
49
+ const variantStyles = React.useMemo(
50
+ () => getContentCardStyles(variant, isInteractive, tokens),
51
+ [variant, isInteractive, tokens]
52
+ );
53
+
54
+ return (
55
+ <Frame
56
+ elevation={variant === 'elevated' ? 2 : undefined}
57
+ appearance={variant === 'elevated' ? 'tinted' : undefined}
58
+ href={href}
59
+ onPress={onPress}
60
+ disabled={disabled}
61
+ padding={padding}
62
+ gap={gap}
63
+ style={[
64
+ variantStyles,
65
+ ...(Array.isArray(style) ? style : style ? [style] : []),
66
+ ]}
67
+ >
68
+ {children}
69
+ </Frame>
70
+ );
71
+ }
@@ -0,0 +1,60 @@
1
+ import type { ViewStyle } from 'react-native';
2
+ import type { PaddingProp, GapProp } from '../../../primitives/Frame/Frame.types';
3
+
4
+ /**
5
+ * Visual variant for the ContentCard component
6
+ */
7
+ export type ContentCardVariant = 'elevated' | 'bordered' | 'flat';
8
+
9
+ /**
10
+ * Props for the ContentCard component
11
+ */
12
+ export interface ContentCardProps {
13
+ /**
14
+ * Card content.
15
+ */
16
+ readonly children: React.ReactNode;
17
+
18
+ /**
19
+ * Visual variant:
20
+ * - `'elevated'` — raised surface with tinted background and elevation shadow
21
+ * - `'bordered'` — outlined container with border and rounded corners
22
+ * - `'flat'` — minimal, bottom-border only (for list rows)
23
+ *
24
+ * @default 'bordered'
25
+ */
26
+ readonly variant?: ContentCardVariant;
27
+
28
+ /**
29
+ * Navigation URL — makes the card a link.
30
+ */
31
+ readonly href?: string;
32
+
33
+ /**
34
+ * Press handler — makes the card interactive.
35
+ */
36
+ readonly onPress?: () => void;
37
+
38
+ /**
39
+ * Padding inside the card.
40
+ * @default 20
41
+ */
42
+ readonly padding?: PaddingProp;
43
+
44
+ /**
45
+ * Gap between children.
46
+ * @default 8
47
+ */
48
+ readonly gap?: GapProp;
49
+
50
+ /**
51
+ * Disabled state
52
+ * @default false
53
+ */
54
+ readonly disabled?: boolean;
55
+
56
+ /**
57
+ * Custom style overrides
58
+ */
59
+ readonly style?: ViewStyle | ViewStyle[];
60
+ }
@@ -0,0 +1,2 @@
1
+ export { ContentCard } from './ContentCard';
2
+ export type { ContentCardProps, ContentCardVariant } from './ContentCard.types';
@@ -0,0 +1,30 @@
1
+ import type { ViewStyle } from 'react-native';
2
+ import type { UseTokensResult } from 'newtone-api';
3
+ import type { DividerOrientation } from './Divider.types';
4
+
5
+ /**
6
+ * Compute divider styles based on orientation, spacing, and tokens.
7
+ */
8
+ export function getDividerStyles(
9
+ orientation: DividerOrientation,
10
+ spacing: number | undefined,
11
+ tokens: UseTokensResult
12
+ ): ViewStyle {
13
+ const color = tokens.colors.primary.main.divider;
14
+
15
+ if (orientation === 'vertical') {
16
+ return {
17
+ width: 1,
18
+ height: '100%' as any,
19
+ backgroundColor: color,
20
+ ...(spacing != null && { marginLeft: spacing, marginRight: spacing }),
21
+ };
22
+ }
23
+
24
+ return {
25
+ height: 1,
26
+ width: '100%' as any,
27
+ backgroundColor: color,
28
+ ...(spacing != null && { marginTop: spacing, marginBottom: spacing }),
29
+ };
30
+ }
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import type { DividerProps } from './Divider.types';
4
+ import { getDividerStyles } from './Divider.styles';
5
+ import { useTokens } from 'newtone-api';
6
+
7
+ /**
8
+ * Divider — A horizontal or vertical separator line.
9
+ *
10
+ * Uses the theme's divider color from tokens automatically.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * // Horizontal divider
15
+ * <Divider />
16
+ *
17
+ * // With spacing
18
+ * <Divider spacing={16} />
19
+ *
20
+ * // Vertical divider (inside a horizontal Wrapper)
21
+ * <Wrapper direction="horizontal" align="center">
22
+ * <Text>Left</Text>
23
+ * <Divider orientation="vertical" spacing={12} />
24
+ * <Text>Right</Text>
25
+ * </Wrapper>
26
+ * ```
27
+ */
28
+ export function Divider({
29
+ orientation = 'horizontal',
30
+ spacing,
31
+ style,
32
+ }: DividerProps) {
33
+ const tokens = useTokens();
34
+
35
+ const dividerStyle = React.useMemo(
36
+ () => getDividerStyles(orientation, spacing, tokens),
37
+ [orientation, spacing, tokens]
38
+ );
39
+
40
+ return (
41
+ <View
42
+ style={[dividerStyle, ...(Array.isArray(style) ? style : style ? [style] : [])]}
43
+ accessibilityRole="none"
44
+ />
45
+ );
46
+ }
@@ -0,0 +1,28 @@
1
+ import type { ViewStyle } from 'react-native';
2
+
3
+ /**
4
+ * Orientation of the divider line
5
+ */
6
+ export type DividerOrientation = 'horizontal' | 'vertical';
7
+
8
+ /**
9
+ * Props for the Divider component
10
+ */
11
+ export interface DividerProps {
12
+ /**
13
+ * Orientation of the divider line.
14
+ * @default 'horizontal'
15
+ */
16
+ readonly orientation?: DividerOrientation;
17
+
18
+ /**
19
+ * Spacing around the divider (margin above+below for horizontal, left+right for vertical).
20
+ * Accepts a pixel number.
21
+ */
22
+ readonly spacing?: number;
23
+
24
+ /**
25
+ * Custom style overrides
26
+ */
27
+ readonly style?: ViewStyle | ViewStyle[];
28
+ }
@@ -0,0 +1,2 @@
1
+ export { Divider } from './Divider';
2
+ export type { DividerProps, DividerOrientation } from './Divider.types';
@@ -1,15 +1,17 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
4
  interface NavbarStyleInput {
5
5
  readonly tokens: ResolvedTokens;
6
- readonly gamut: ColorGamut;
7
6
  readonly height: number;
8
7
  readonly bordered: boolean;
8
+ readonly theme?: ThemeName;
9
+ readonly appearance?: AppearanceName;
9
10
  }
10
11
 
11
- export function getNavbarStyles({ tokens, gamut, height, bordered }: NavbarStyleInput) {
12
- const borderColor = tokens.border[gamut];
12
+ export function getNavbarStyles({ tokens, height, bordered, theme = 'primary', appearance = 'main' }: NavbarStyleInput) {
13
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
14
+ const borderColor = at.fontSecondary;
13
15
 
14
16
  return StyleSheet.create({
15
17
  container: {
@@ -18,7 +20,7 @@ export function getNavbarStyles({ tokens, gamut, height, bordered }: NavbarStyle
18
20
  height,
19
21
  flexShrink: 0,
20
22
  paddingHorizontal: 24,
21
- backgroundColor: tokens.background[gamut],
23
+ backgroundColor: at.background,
22
24
  borderBottomWidth: bordered ? 1 : 0,
23
25
  borderBottomColor: borderColor,
24
26
  },
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { NavbarProps } from './Navbar.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getNavbarStyles } from './Navbar.styles';
6
6
 
7
7
  export function Navbar({
@@ -12,9 +12,10 @@ export function Navbar({
12
12
  bordered = true,
13
13
  }: NavbarProps) {
14
14
  const tokens = useTokens();
15
+ const frameCtx = useFrameContext();
15
16
  const styles = React.useMemo(
16
- () => getNavbarStyles({ tokens, gamut: tokens.gamut, height, bordered }),
17
- [tokens, height, bordered]
17
+ () => getNavbarStyles({ tokens, height, bordered, theme: frameCtx?.theme, appearance: frameCtx?.appearance }),
18
+ [tokens, height, bordered, frameCtx?.theme, frameCtx?.appearance]
18
19
  );
19
20
 
20
21
  return (
@@ -1,22 +1,24 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
4
  interface SidebarStyleInput {
5
5
  readonly tokens: ResolvedTokens;
6
- readonly gamut: ColorGamut;
7
6
  readonly width: number;
8
7
  readonly bordered: boolean;
8
+ readonly theme?: ThemeName;
9
+ readonly appearance?: AppearanceName;
9
10
  }
10
11
 
11
- export function getSidebarStyles({ tokens, gamut, width, bordered }: SidebarStyleInput) {
12
- const borderColor = tokens.border[gamut];
12
+ export function getSidebarStyles({ tokens, width, bordered, theme = 'primary', appearance = 'main' }: SidebarStyleInput) {
13
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
14
+ const borderColor = at.fontSecondary;
13
15
 
14
16
  return StyleSheet.create({
15
17
  container: {
16
18
  width,
17
19
  flexShrink: 0,
18
20
  flexDirection: 'column',
19
- backgroundColor: tokens.background[gamut],
21
+ backgroundColor: at.background,
20
22
  borderRightWidth: bordered ? 1 : 0,
21
23
  borderRightColor: borderColor,
22
24
  },
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View, ScrollView } from 'react-native';
3
3
  import type { SidebarProps } from './Sidebar.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getSidebarStyles } from './Sidebar.styles';
6
6
 
7
7
  export function Sidebar({
@@ -12,9 +12,10 @@ export function Sidebar({
12
12
  bordered = true,
13
13
  }: SidebarProps) {
14
14
  const tokens = useTokens();
15
+ const frameCtx = useFrameContext();
15
16
  const styles = React.useMemo(
16
- () => getSidebarStyles({ tokens, gamut: tokens.gamut, width, bordered }),
17
- [tokens, width, bordered]
17
+ () => getSidebarStyles({ tokens, width, bordered, theme: frameCtx?.theme, appearance: frameCtx?.appearance }),
18
+ [tokens, width, bordered, frameCtx?.theme, frameCtx?.appearance]
18
19
  );
19
20
 
20
21
  return (
@@ -1,15 +1,17 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens, AppearanceTokens, ThemeName, AppearanceName } from 'newtone-api';
3
3
 
4
4
  export function getPopoverStyles(
5
5
  tokens: ResolvedTokens,
6
- gamut: ColorGamut,
7
6
  triggerHeight: number,
8
7
  offset: number,
9
8
  maxHeight: number,
10
9
  width: 'trigger' | 'auto' | number,
11
- isOpen: boolean
10
+ isOpen: boolean,
11
+ theme: ThemeName = 'primary',
12
+ appearance: AppearanceName = 'main',
12
13
  ) {
14
+ const at: AppearanceTokens = tokens.colors[theme][appearance];
13
15
  const widthStyle =
14
16
  width === 'trigger'
15
17
  ? { left: 0 as const, right: 0 as const }
@@ -26,9 +28,9 @@ export function getPopoverStyles(
26
28
  position: 'absolute',
27
29
  top: triggerHeight + offset,
28
30
  ...widthStyle,
29
- backgroundColor: tokens.backgroundElevated[gamut],
31
+ backgroundColor: at.fontPrimary,
30
32
  borderWidth: 1,
31
- borderColor: tokens.border[gamut],
33
+ borderColor: at.fontSecondary,
32
34
  borderRadius: tokens.radius.md,
33
35
  maxHeight,
34
36
  zIndex: 1000,
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { PopoverProps } from './Popover.types';
4
- import { useTokens } from 'newtone-api';
4
+ import { useTokens, useFrameContext } from 'newtone-api';
5
5
  import { getPopoverStyles } from './Popover.styles';
6
6
 
7
7
  // Module-level: set of close callbacks for all open Popovers.
@@ -21,6 +21,7 @@ export function Popover({
21
21
  contentStyle,
22
22
  }: PopoverProps) {
23
23
  const tokens = useTokens(1);
24
+ const frameCtx = useFrameContext();
24
25
  const containerRef = useRef<View>(null);
25
26
  const [triggerHeight, setTriggerHeight] = useState(0);
26
27
 
@@ -68,8 +69,8 @@ export function Popover({
68
69
  );
69
70
 
70
71
  const styles = useMemo(
71
- () => getPopoverStyles(tokens, tokens.gamut, triggerHeight, offset, maxHeight, width, isOpen),
72
- [tokens, triggerHeight, offset, maxHeight, width, isOpen]
72
+ () => getPopoverStyles(tokens, triggerHeight, offset, maxHeight, width, isOpen, frameCtx?.theme, frameCtx?.appearance),
73
+ [tokens, triggerHeight, offset, maxHeight, width, isOpen, frameCtx?.theme, frameCtx?.appearance]
73
74
  );
74
75
 
75
76
  const containerStyles = useMemo(
@@ -1,10 +1,10 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import type { ResolvedTokens, ColorGamut } from 'newtone-api';
2
+ import type { ResolvedTokens } from 'newtone-api';
3
3
 
4
4
  const TRACK_HEIGHT = 22;
5
5
  export const THUMB_SIZE = 18;
6
6
 
7
- export function getColorScaleSliderStyles(tokens: ResolvedTokens, gamut: ColorGamut, disabled: boolean) {
7
+ export function getColorScaleSliderStyles(tokens: ResolvedTokens, disabled: boolean) {
8
8
  return StyleSheet.create({
9
9
  container: {
10
10
  gap: tokens.spacing['04'],
@@ -19,7 +19,7 @@ export function getColorScaleSliderStyles(tokens: ResolvedTokens, gamut: ColorGa
19
19
  fontFamily: tokens.typography.fonts.main.family,
20
20
  fontSize: tokens.typography.fontSizes['04'],
21
21
  fontWeight: tokens.typography.fonts.main.weights.medium as any,
22
- color: tokens.textSecondary[gamut],
22
+ color: tokens.colors.primary.main.fontTertiary,
23
23
  },
24
24
  trackContainer: {
25
25
  height: TRACK_HEIGHT + THUMB_SIZE,
@@ -45,13 +45,13 @@ export function getColorScaleSliderStyles(tokens: ResolvedTokens, gamut: ColorGa
45
45
  borderRadius: THUMB_SIZE / 2,
46
46
  backgroundColor: '#ffffff',
47
47
  borderWidth: 2,
48
- borderColor: tokens.border[gamut],
48
+ borderColor: tokens.colors.primary.main.fontSecondary,
49
49
  },
50
50
  warning: {
51
51
  fontFamily: tokens.typography.fonts.main.family,
52
52
  fontSize: tokens.typography.fontSizes['01'],
53
53
  fontWeight: tokens.typography.fonts.main.weights.medium as any,
54
- color: tokens.error.fill[gamut],
54
+ color: tokens.colors.error.emphasis.divider,
55
55
  },
56
56
  });
57
57
  }