@ankhorage/surface 1.4.0 → 2.0.1

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 (223) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/components/action-sheet/ActionSheet.d.ts +4 -0
  3. package/dist/components/action-sheet/ActionSheet.d.ts.map +1 -0
  4. package/dist/components/action-sheet/ActionSheet.js +71 -0
  5. package/dist/components/action-sheet/ActionSheet.js.map +1 -0
  6. package/dist/components/action-sheet/ActionSheetItem.d.ts +4 -0
  7. package/dist/components/action-sheet/ActionSheetItem.d.ts.map +1 -0
  8. package/dist/components/action-sheet/ActionSheetItem.js +27 -0
  9. package/dist/components/action-sheet/ActionSheetItem.js.map +1 -0
  10. package/dist/components/action-sheet/index.d.ts +4 -0
  11. package/dist/components/action-sheet/index.d.ts.map +1 -0
  12. package/dist/components/action-sheet/index.js +3 -0
  13. package/dist/components/action-sheet/index.js.map +1 -0
  14. package/dist/components/action-sheet/types.d.ts +24 -0
  15. package/dist/components/action-sheet/types.d.ts.map +1 -0
  16. package/dist/components/action-sheet/types.js +2 -0
  17. package/dist/components/action-sheet/types.js.map +1 -0
  18. package/dist/components/badge/Badge.d.ts +1 -1
  19. package/dist/components/badge/Badge.d.ts.map +1 -1
  20. package/dist/components/badge/Badge.js +3 -3
  21. package/dist/components/badge/Badge.js.map +1 -1
  22. package/dist/components/badge/types.d.ts +2 -2
  23. package/dist/components/badge/types.d.ts.map +1 -1
  24. package/dist/components/badge/types.js.map +1 -1
  25. package/dist/components/button/Button.d.ts +1 -1
  26. package/dist/components/button/Button.d.ts.map +1 -1
  27. package/dist/components/button/Button.js +6 -3
  28. package/dist/components/button/Button.js.map +1 -1
  29. package/dist/components/button/types.d.ts +2 -2
  30. package/dist/components/button/types.d.ts.map +1 -1
  31. package/dist/components/button/types.js.map +1 -1
  32. package/dist/components/checkbox/Checkbox.d.ts +1 -1
  33. package/dist/components/checkbox/Checkbox.d.ts.map +1 -1
  34. package/dist/components/checkbox/Checkbox.js +7 -4
  35. package/dist/components/checkbox/Checkbox.js.map +1 -1
  36. package/dist/components/checkbox/types.d.ts +2 -2
  37. package/dist/components/checkbox/types.d.ts.map +1 -1
  38. package/dist/components/checkbox/types.js.map +1 -1
  39. package/dist/components/field/Field.d.ts.map +1 -1
  40. package/dist/components/field/Field.js +6 -2
  41. package/dist/components/field/Field.js.map +1 -1
  42. package/dist/components/helper-text/HelperText.d.ts +1 -1
  43. package/dist/components/helper-text/HelperText.d.ts.map +1 -1
  44. package/dist/components/helper-text/HelperText.js +2 -2
  45. package/dist/components/helper-text/HelperText.js.map +1 -1
  46. package/dist/components/helper-text/types.d.ts +3 -2
  47. package/dist/components/helper-text/types.d.ts.map +1 -1
  48. package/dist/components/helper-text/types.js.map +1 -1
  49. package/dist/components/icon-button/IconButton.d.ts +1 -1
  50. package/dist/components/icon-button/IconButton.d.ts.map +1 -1
  51. package/dist/components/icon-button/IconButton.js +2 -2
  52. package/dist/components/icon-button/IconButton.js.map +1 -1
  53. package/dist/components/icon-button/types.d.ts +2 -2
  54. package/dist/components/icon-button/types.d.ts.map +1 -1
  55. package/dist/components/icon-button/types.js.map +1 -1
  56. package/dist/components/label/Label.d.ts +1 -1
  57. package/dist/components/label/Label.d.ts.map +1 -1
  58. package/dist/components/label/Label.js +3 -3
  59. package/dist/components/label/Label.js.map +1 -1
  60. package/dist/components/label/types.d.ts +3 -2
  61. package/dist/components/label/types.d.ts.map +1 -1
  62. package/dist/components/label/types.js.map +1 -1
  63. package/dist/components/list-item/ListItem.js +1 -1
  64. package/dist/components/list-item/ListItem.js.map +1 -1
  65. package/dist/components/menu/Menu.d.ts.map +1 -1
  66. package/dist/components/menu/Menu.js +1 -3
  67. package/dist/components/menu/Menu.js.map +1 -1
  68. package/dist/components/navigation/NavigationItem.d.ts.map +1 -1
  69. package/dist/components/navigation/NavigationItem.js +1 -1
  70. package/dist/components/navigation/NavigationItem.js.map +1 -1
  71. package/dist/components/navigation/TabBarItem.d.ts.map +1 -1
  72. package/dist/components/navigation/TabBarItem.js +1 -1
  73. package/dist/components/navigation/TabBarItem.js.map +1 -1
  74. package/dist/components/radio/Radio.d.ts +1 -1
  75. package/dist/components/radio/Radio.d.ts.map +1 -1
  76. package/dist/components/radio/Radio.js +4 -3
  77. package/dist/components/radio/Radio.js.map +1 -1
  78. package/dist/components/radio/types.d.ts +2 -2
  79. package/dist/components/radio/types.d.ts.map +1 -1
  80. package/dist/components/radio/types.js.map +1 -1
  81. package/dist/components/switch/Switch.d.ts +1 -1
  82. package/dist/components/switch/Switch.d.ts.map +1 -1
  83. package/dist/components/switch/Switch.js +4 -3
  84. package/dist/components/switch/Switch.js.map +1 -1
  85. package/dist/components/switch/types.d.ts +2 -2
  86. package/dist/components/switch/types.d.ts.map +1 -1
  87. package/dist/components/switch/types.js.map +1 -1
  88. package/dist/components/tabs/Tab.d.ts.map +1 -1
  89. package/dist/components/tabs/Tab.js +1 -1
  90. package/dist/components/tabs/Tab.js.map +1 -1
  91. package/dist/components/toast/Toast.d.ts +1 -1
  92. package/dist/components/toast/Toast.d.ts.map +1 -1
  93. package/dist/components/toast/Toast.js +34 -9
  94. package/dist/components/toast/Toast.js.map +1 -1
  95. package/dist/components/toast/ToastProvider.js +1 -1
  96. package/dist/components/toast/ToastProvider.js.map +1 -1
  97. package/dist/components/toast/index.d.ts +1 -1
  98. package/dist/components/toast/index.d.ts.map +1 -1
  99. package/dist/components/toast/index.js.map +1 -1
  100. package/dist/components/toast/types.d.ts +3 -2
  101. package/dist/components/toast/types.d.ts.map +1 -1
  102. package/dist/components/toast/types.js.map +1 -1
  103. package/dist/components/tooltip/Tooltip.js +1 -1
  104. package/dist/components/tooltip/Tooltip.js.map +1 -1
  105. package/dist/examples/DocsExamples.js +4 -4
  106. package/dist/examples/DocsExamples.js.map +1 -1
  107. package/dist/index.d.ts +5 -1
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +2 -0
  110. package/dist/index.js.map +1 -1
  111. package/dist/internal/resolvers/index.d.ts +1 -1
  112. package/dist/internal/resolvers/index.d.ts.map +1 -1
  113. package/dist/internal/resolvers/index.js +1 -1
  114. package/dist/internal/resolvers/index.js.map +1 -1
  115. package/dist/internal/resolvers/resolveFieldPresentation.d.ts +5 -5
  116. package/dist/internal/resolvers/resolveFieldPresentation.d.ts.map +1 -1
  117. package/dist/internal/resolvers/resolveFieldPresentation.js +8 -6
  118. package/dist/internal/resolvers/resolveFieldPresentation.js.map +1 -1
  119. package/dist/internal/resolvers/resolveInteractiveColors.d.ts +3 -3
  120. package/dist/internal/resolvers/resolveInteractiveColors.d.ts.map +1 -1
  121. package/dist/internal/resolvers/resolveInteractiveColors.js +4 -6
  122. package/dist/internal/resolvers/resolveInteractiveColors.js.map +1 -1
  123. package/dist/internal/resolvers/resolveSelectionControlColors.d.ts +3 -3
  124. package/dist/internal/resolvers/resolveSelectionControlColors.d.ts.map +1 -1
  125. package/dist/internal/resolvers/resolveSelectionControlColors.js +4 -4
  126. package/dist/internal/resolvers/resolveSelectionControlColors.js.map +1 -1
  127. package/dist/internal/resolvers/resolveSurfaceColor.d.ts +4 -0
  128. package/dist/internal/resolvers/resolveSurfaceColor.d.ts.map +1 -0
  129. package/dist/internal/resolvers/resolveSurfaceColor.js +26 -0
  130. package/dist/internal/resolvers/resolveSurfaceColor.js.map +1 -0
  131. package/dist/internal/resolvers/resolveTextColor.d.ts +2 -3
  132. package/dist/internal/resolvers/resolveTextColor.d.ts.map +1 -1
  133. package/dist/internal/resolvers/resolveTextColor.js +7 -11
  134. package/dist/internal/resolvers/resolveTextColor.js.map +1 -1
  135. package/dist/primitives/heading/Heading.d.ts.map +1 -1
  136. package/dist/primitives/heading/Heading.js +2 -2
  137. package/dist/primitives/heading/Heading.js.map +1 -1
  138. package/dist/primitives/heading/resolveHeadingStyle.d.ts +2 -1
  139. package/dist/primitives/heading/resolveHeadingStyle.d.ts.map +1 -1
  140. package/dist/primitives/heading/resolveHeadingStyle.js +2 -2
  141. package/dist/primitives/heading/resolveHeadingStyle.js.map +1 -1
  142. package/dist/primitives/heading/types.d.ts +3 -0
  143. package/dist/primitives/heading/types.d.ts.map +1 -1
  144. package/dist/primitives/heading/types.js.map +1 -1
  145. package/dist/primitives/text/Text.d.ts +1 -1
  146. package/dist/primitives/text/Text.d.ts.map +1 -1
  147. package/dist/primitives/text/Text.js +2 -2
  148. package/dist/primitives/text/Text.js.map +1 -1
  149. package/dist/primitives/text/types.d.ts +3 -3
  150. package/dist/primitives/text/types.d.ts.map +1 -1
  151. package/dist/primitives/text/types.js.map +1 -1
  152. package/dist/surfaceColor.d.ts +9 -0
  153. package/dist/surfaceColor.d.ts.map +1 -0
  154. package/dist/surfaceColor.js +15 -0
  155. package/dist/surfaceColor.js.map +1 -0
  156. package/dist/theme/colorEngine.d.ts.map +1 -1
  157. package/dist/theme/colorEngine.js +9 -1
  158. package/dist/theme/colorEngine.js.map +1 -1
  159. package/dist/theme/types.d.ts +5 -0
  160. package/dist/theme/types.d.ts.map +1 -1
  161. package/dist/theme/types.js.map +1 -1
  162. package/package.json +2 -2
  163. package/src/components/action-sheet/ActionSheet.tsx +121 -0
  164. package/src/components/action-sheet/ActionSheetItem.tsx +57 -0
  165. package/src/components/action-sheet/index.ts +3 -0
  166. package/src/components/action-sheet/types.ts +26 -0
  167. package/src/components/badge/Badge.tsx +8 -3
  168. package/src/components/badge/types.ts +2 -2
  169. package/src/components/button/Button.tsx +9 -3
  170. package/src/components/button/types.ts +2 -2
  171. package/src/components/checkbox/Checkbox.tsx +13 -4
  172. package/src/components/checkbox/types.ts +2 -2
  173. package/src/components/field/Field.tsx +11 -3
  174. package/src/components/helper-text/HelperText.tsx +2 -2
  175. package/src/components/helper-text/types.ts +3 -2
  176. package/src/components/icon-button/IconButton.tsx +2 -2
  177. package/src/components/icon-button/types.ts +2 -2
  178. package/src/components/label/Label.tsx +9 -3
  179. package/src/components/label/types.ts +3 -2
  180. package/src/components/list-item/ListItem.tsx +1 -1
  181. package/src/components/menu/Menu.tsx +1 -8
  182. package/src/components/navigation/NavigationItem.tsx +2 -1
  183. package/src/components/navigation/TabBarItem.tsx +2 -1
  184. package/src/components/radio/Radio.tsx +5 -3
  185. package/src/components/radio/types.ts +2 -2
  186. package/src/components/switch/Switch.tsx +5 -3
  187. package/src/components/switch/types.ts +2 -2
  188. package/src/components/tabs/Tab.tsx +1 -5
  189. package/src/components/toast/Toast.tsx +38 -10
  190. package/src/components/toast/ToastProvider.tsx +1 -1
  191. package/src/components/toast/index.ts +1 -1
  192. package/src/components/toast/types.ts +4 -2
  193. package/src/components/tooltip/Tooltip.tsx +1 -1
  194. package/src/examples/DocsExamples.tsx +4 -4
  195. package/src/index.test.ts +1 -0
  196. package/src/index.ts +15 -1
  197. package/src/internal/resolvers/index.ts +1 -1
  198. package/src/internal/resolvers/resolveFieldPresentation.test.ts +12 -10
  199. package/src/internal/resolvers/resolveFieldPresentation.ts +13 -11
  200. package/src/internal/resolvers/resolveInteractiveColors.test.ts +4 -4
  201. package/src/internal/resolvers/resolveInteractiveColors.ts +6 -7
  202. package/src/internal/resolvers/resolveSelectionControlColors.test.ts +8 -8
  203. package/src/internal/resolvers/resolveSelectionControlColors.ts +6 -5
  204. package/src/internal/resolvers/resolveSurfaceColor.test.ts +21 -0
  205. package/src/internal/resolvers/resolveSurfaceColor.ts +31 -0
  206. package/src/internal/resolvers/resolveTextColor.test.ts +16 -5
  207. package/src/internal/resolvers/resolveTextColor.ts +10 -22
  208. package/src/primitives/heading/Heading.tsx +3 -1
  209. package/src/primitives/heading/resolveHeadingStyle.test.ts +1 -1
  210. package/src/primitives/heading/resolveHeadingStyle.ts +4 -1
  211. package/src/primitives/heading/types.ts +4 -0
  212. package/src/primitives/text/Text.tsx +2 -2
  213. package/src/primitives/text/types.ts +3 -3
  214. package/src/surfaceColor.test.ts +46 -0
  215. package/src/surfaceColor.ts +22 -0
  216. package/src/theme/colorEngine.test.ts +6 -0
  217. package/src/theme/colorEngine.ts +9 -1
  218. package/src/theme/types.ts +5 -0
  219. package/dist/internal/resolvers/resolveTone.d.ts +0 -4
  220. package/dist/internal/resolvers/resolveTone.d.ts.map +0 -1
  221. package/dist/internal/resolvers/resolveTone.js +0 -16
  222. package/dist/internal/resolvers/resolveTone.js.map +0 -1
  223. package/src/internal/resolvers/resolveTone.ts +0 -19
@@ -3,12 +3,18 @@ import React from 'react';
3
3
  import { Text } from '../../primitives/text';
4
4
  import type { LabelProps } from './types';
5
5
 
6
- export function Label({ children, required = false, tone = 'default', testID }: LabelProps) {
6
+ export function Label({
7
+ children,
8
+ required = false,
9
+ emphasis = 'default',
10
+ color,
11
+ testID,
12
+ }: LabelProps) {
7
13
  return (
8
- <Text testID={testID} tone={tone} variant="label" weight="medium">
14
+ <Text color={color} emphasis={emphasis} testID={testID} variant="label" weight="medium">
9
15
  {children}
10
16
  {required ? (
11
- <Text tone="danger" variant="label" weight="medium">
17
+ <Text color="error" variant="label" weight="medium">
12
18
  {' *'}
13
19
  </Text>
14
20
  ) : null}
@@ -1,10 +1,11 @@
1
1
  import type React from 'react';
2
2
 
3
- import type { TextTone } from '../../internal/resolvers/resolveTextColor';
3
+ import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
4
4
 
5
5
  export interface LabelProps {
6
6
  children?: React.ReactNode;
7
7
  required?: boolean;
8
- tone?: Extract<TextTone, 'default' | 'muted' | 'danger'>;
8
+ emphasis?: Extract<SurfaceEmphasis, 'default' | 'muted'>;
9
+ color?: Extract<SurfaceColor, 'error'>;
9
10
  testID?: string;
10
11
  }
@@ -34,7 +34,7 @@ function ListItemContent({
34
34
  </Text>
35
35
  ) : null}
36
36
  {description ? (
37
- <Text numberOfLines={2} tone="muted" variant="bodySmall">
37
+ <Text emphasis="muted" numberOfLines={2} variant="bodySmall">
38
38
  {description}
39
39
  </Text>
40
40
  ) : null}
@@ -156,14 +156,7 @@ export function Menu({ trigger, items, onDismiss, closeOnSelect = true, testID }
156
156
  }}
157
157
  testID={testID ? `${testID}-item-${item.id}` : undefined}
158
158
  >
159
- <Text
160
- color={
161
- selected
162
- ? theme.semantics.action.neutral.base
163
- : theme.semantics.content.default
164
- }
165
- variant="bodySmall"
166
- >
159
+ <Text color={selected ? 'neutral' : undefined} variant="bodySmall">
167
160
  {item.label}
168
161
  </Text>
169
162
  </Box>
@@ -60,7 +60,8 @@ export function NavigationItem({ item, compact = false, testID }: NavigationItem
60
60
  ) : null}
61
61
  <Box flex={1}>
62
62
  <Text
63
- color={presentation.contentColor}
63
+ color={active && !disabled ? 'primary' : undefined}
64
+ emphasis={disabled ? 'muted' : 'default'}
64
65
  numberOfLines={1}
65
66
  variant={compact ? 'bodySmall' : 'body'}
66
67
  weight="medium"
@@ -66,7 +66,8 @@ export function TabBarItem({ item, compact = false, testID }: TabBarItemProps) {
66
66
  ) : null}
67
67
  {item.label ? (
68
68
  <Text
69
- color={contentColor}
69
+ color={active && !disabled ? 'primary' : undefined}
70
+ emphasis={active && !disabled ? 'default' : 'muted'}
70
71
  numberOfLines={1}
71
72
  variant={compact ? 'bodySmall' : 'label'}
72
73
  weight="medium"
@@ -18,7 +18,7 @@ export function Radio({
18
18
  checked,
19
19
  defaultChecked = false,
20
20
  onCheckedChange,
21
- tone = 'primary',
21
+ color = 'primary',
22
22
  size = 'm',
23
23
  disabled = false,
24
24
  invalid = false,
@@ -69,8 +69,10 @@ export function Radio({
69
69
  fieldState,
70
70
  hovered: interactionState.hovered,
71
71
  pressed: interactionState.pressed,
72
- tone,
72
+ color,
73
73
  });
74
+ const labelEmphasis =
75
+ colors.labelColor === theme.semantics.content.muted ? 'muted' : 'default';
74
76
 
75
77
  return (
76
78
  <Box
@@ -105,7 +107,7 @@ export function Radio({
105
107
  </Box>
106
108
  {children ? (
107
109
  <Box ml="s">
108
- <Text color={colors.labelColor}>{children}</Text>
110
+ <Text emphasis={labelEmphasis}>{children}</Text>
109
111
  </Box>
110
112
  ) : null}
111
113
  </Box>
@@ -1,8 +1,8 @@
1
1
  import type React from 'react';
2
2
 
3
3
  import type { ControlSize } from '../../internal/resolvers/resolveControlSize';
4
- import type { ComponentTone } from '../../internal/resolvers/resolveTone';
5
4
  import type { ButtonBaseProps } from '../../primitives/button-base';
5
+ import type { SurfaceColor } from '../../surfaceColor';
6
6
 
7
7
  export interface RadioProps extends Omit<
8
8
  ButtonBaseProps,
@@ -12,7 +12,7 @@ export interface RadioProps extends Omit<
12
12
  checked?: boolean;
13
13
  defaultChecked?: boolean;
14
14
  onCheckedChange?: ((checked: boolean) => void) | undefined;
15
- tone?: ComponentTone;
15
+ color?: SurfaceColor;
16
16
  size?: ControlSize;
17
17
  invalid?: boolean;
18
18
  readOnly?: boolean;
@@ -18,7 +18,7 @@ export function Switch({
18
18
  checked,
19
19
  defaultChecked = false,
20
20
  onCheckedChange,
21
- tone = 'primary',
21
+ color = 'primary',
22
22
  size = 'm',
23
23
  disabled = false,
24
24
  invalid = false,
@@ -69,8 +69,10 @@ export function Switch({
69
69
  fieldState,
70
70
  hovered: interactionState.hovered,
71
71
  pressed: interactionState.pressed,
72
- tone,
72
+ color,
73
73
  });
74
+ const labelEmphasis =
75
+ colors.labelColor === theme.semantics.content.muted ? 'muted' : 'default';
74
76
 
75
77
  return (
76
78
  <Box
@@ -105,7 +107,7 @@ export function Switch({
105
107
  </Box>
106
108
  {children ? (
107
109
  <Box ml="s">
108
- <Text color={colors.labelColor}>{children}</Text>
110
+ <Text emphasis={labelEmphasis}>{children}</Text>
109
111
  </Box>
110
112
  ) : null}
111
113
  </Box>
@@ -1,8 +1,8 @@
1
1
  import type React from 'react';
2
2
 
3
3
  import type { ControlSize } from '../../internal/resolvers/resolveControlSize';
4
- import type { ComponentTone } from '../../internal/resolvers/resolveTone';
5
4
  import type { ButtonBaseProps } from '../../primitives/button-base';
5
+ import type { SurfaceColor } from '../../surfaceColor';
6
6
 
7
7
  export interface SwitchProps extends Omit<
8
8
  ButtonBaseProps,
@@ -12,7 +12,7 @@ export interface SwitchProps extends Omit<
12
12
  checked?: boolean;
13
13
  defaultChecked?: boolean;
14
14
  onCheckedChange?: ((checked: boolean) => void) | undefined;
15
- tone?: ComponentTone;
15
+ color?: SurfaceColor;
16
16
  size?: ControlSize;
17
17
  invalid?: boolean;
18
18
  readOnly?: boolean;
@@ -69,11 +69,7 @@ export function Tab({ value, children, disabled = false, testID }: TabProps) {
69
69
  opacity: disabled ? 0.64 : 1,
70
70
  }}
71
71
  >
72
- <Text
73
- color={selected ? theme.semantics.action.primary.base : theme.semantics.content.default}
74
- variant="label"
75
- weight="medium"
76
- >
72
+ <Text color={selected ? 'primary' : undefined} variant="label" weight="medium">
77
73
  {children}
78
74
  </Text>
79
75
  </Box>
@@ -3,23 +3,51 @@ import { Pressable } from 'react-native';
3
3
 
4
4
  import { Box, Inline, Surface } from '../../layout';
5
5
  import { Text } from '../../primitives/text';
6
+ import type { SurfaceColor } from '../../surfaceColor';
6
7
  import { useTheme } from '../../theme/ThemeContext';
8
+ import type { SurfaceTheme } from '../../theme/types';
7
9
  import type { ToastProps } from './types';
8
10
 
9
- export function Toast({ title, description, tone = 'default', onDismiss, testID }: ToastProps) {
11
+ function resolveToastStatusColor(theme: SurfaceTheme, status: ToastProps['status']) {
12
+ switch (status) {
13
+ case 'success':
14
+ return theme.semantics.success.base;
15
+ case 'warning':
16
+ return theme.semantics.warning.base;
17
+ case 'error':
18
+ return theme.semantics.error.base;
19
+ case 'info':
20
+ return theme.semantics.info.base;
21
+ default:
22
+ return theme.semantics.action.primary.base;
23
+ }
24
+ }
25
+
26
+ function resolveToastStatusTextColor(status: ToastProps['status']): SurfaceColor {
27
+ switch (status) {
28
+ case 'success':
29
+ return 'success';
30
+ case 'warning':
31
+ return 'warning';
32
+ case 'error':
33
+ return 'error';
34
+ case 'info':
35
+ return 'info';
36
+ default:
37
+ return 'primary';
38
+ }
39
+ }
40
+
41
+ export function Toast({ title, description, status = 'default', onDismiss, testID }: ToastProps) {
10
42
  const { theme } = useTheme();
11
- const toneColor =
12
- tone === 'success'
13
- ? theme.semantics.success.base
14
- : tone === 'danger'
15
- ? theme.semantics.danger.base
16
- : theme.semantics.action.primary.base;
43
+ const statusColor = resolveToastStatusColor(theme, status);
44
+ const statusTextColor = resolveToastStatusTextColor(status);
17
45
 
18
46
  return (
19
47
  <Surface
20
48
  p="m"
21
49
  style={{
22
- borderLeftColor: toneColor,
50
+ borderLeftColor: statusColor,
23
51
  borderLeftWidth: 3,
24
52
  minWidth: 280,
25
53
  shadowOpacity: 0.14,
@@ -36,7 +64,7 @@ export function Toast({ title, description, tone = 'default', onDismiss, testID
36
64
  {title}
37
65
  </Text>
38
66
  ) : null}
39
- {description ? <Text tone="muted">{description}</Text> : null}
67
+ {description ? <Text emphasis="muted">{description}</Text> : null}
40
68
  </Box>
41
69
  {onDismiss ? (
42
70
  <Pressable
@@ -45,7 +73,7 @@ export function Toast({ title, description, tone = 'default', onDismiss, testID
45
73
  onPress={onDismiss}
46
74
  testID={testID ? `${testID}-dismiss` : undefined}
47
75
  >
48
- <Text color={toneColor}>×</Text>
76
+ <Text color={statusTextColor}>×</Text>
49
77
  </Pressable>
50
78
  ) : null}
51
79
  </Inline>
@@ -92,9 +92,9 @@ export function ToastProvider({
92
92
  description={toast.description}
93
93
  key={toast.id}
94
94
  onDismiss={() => dismissToast(toast.id)}
95
+ status={toast.status}
95
96
  testID={toast.testID}
96
97
  title={toast.title}
97
- tone={toast.tone}
98
98
  />
99
99
  ))}
100
100
  </Stack>
@@ -1,3 +1,3 @@
1
1
  export { Toast } from './Toast';
2
2
  export { ToastProvider, useToast } from './ToastProvider';
3
- export type { ToastOptions, ToastProps, ToastTone } from './types';
3
+ export type { ToastOptions, ToastProps, ToastStatus } from './types';
@@ -1,11 +1,13 @@
1
1
  import type React from 'react';
2
2
 
3
- export type ToastTone = 'default' | 'success' | 'danger';
3
+ import type { SurfaceStatusColor } from '../../surfaceColor';
4
+
5
+ export type ToastStatus = 'default' | SurfaceStatusColor;
4
6
 
5
7
  export interface ToastProps {
6
8
  title?: React.ReactNode;
7
9
  description?: React.ReactNode;
8
- tone?: ToastTone;
10
+ status?: ToastStatus;
9
11
  onDismiss?: (() => void) | undefined;
10
12
  testID?: string;
11
13
  }
@@ -98,7 +98,7 @@ export function Tooltip({
98
98
  testID={testID}
99
99
  variant="raised"
100
100
  >
101
- <Text color={theme.semantics.content.inverse} variant="caption">
101
+ <Text emphasis="inverse" variant="caption">
102
102
  {content}
103
103
  </Text>
104
104
  </Surface>
@@ -42,8 +42,8 @@ export function ProviderExample() {
42
42
  <ThemeProvider initialConfig={docsThemeConfig}>
43
43
  <Stack gap="m" p="l">
44
44
  <Text variant="body">Surface starter</Text>
45
- <Badge content="Foundation" tone="success" />
46
- <Button tone="warning" variant="soft">
45
+ <Badge color="success" content="Foundation" />
46
+ <Button color="warning" variant="soft">
47
47
  Continue
48
48
  </Button>
49
49
  </Stack>
@@ -66,7 +66,7 @@ export function FormAndOverlayExample() {
66
66
  <Checkbox defaultChecked>Weekly updates</Checkbox>
67
67
  <Radio>Product announcements</Radio>
68
68
  <Switch readOnly>Read-only setting</Switch>
69
- <HelperText tone="danger">Invalid fields should reuse the same danger tone.</HelperText>
69
+ <HelperText color="error">Invalid fields should reuse the same error color.</HelperText>
70
70
  </Stack>
71
71
  <Modal visible={false}>
72
72
  <Text>Modal content</Text>
@@ -106,7 +106,7 @@ export function NavigationExample() {
106
106
  trigger={<Text>Open menu</Text>}
107
107
  />
108
108
  <Box>
109
- <Text tone="success">Theme overrides can stay semantic.</Text>
109
+ <Text color="success">Theme overrides can stay semantic.</Text>
110
110
  </Box>
111
111
  </Stack>
112
112
  </ThemeProvider>
package/src/index.test.ts CHANGED
@@ -34,6 +34,7 @@ const expectedRootExports = [
34
34
  "export * from './core/responsive';",
35
35
  "export * from './layout';",
36
36
  "export { Image } from './primitives/image';",
37
+ "export {\n SURFACE_COLORS,\n SURFACE_EMPHASES,\n SURFACE_PALETTE_COLORS,\n SURFACE_STATUS_COLORS,\n} from './surfaceColor';",
37
38
  "export * from './theme';",
38
39
  ] as const;
39
40
 
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export type { ActionSheetItemProps, ActionSheetProps } from './components/action-sheet';
2
+ export { ActionSheet, ActionSheetItem } from './components/action-sheet';
1
3
  export type { BadgeProps } from './components/badge';
2
4
  export { Badge } from './components/badge';
3
5
  export type { ButtonIconSpec, ButtonProps } from './components/button';
@@ -50,7 +52,7 @@ export type { TextInputProps } from './components/text-input';
50
52
  export { TextInput } from './components/text-input';
51
53
  export type { TextareaProps } from './components/textarea';
52
54
  export { Textarea } from './components/textarea';
53
- export type { ToastOptions, ToastProps, ToastTone } from './components/toast';
55
+ export type { ToastOptions, ToastProps, ToastStatus } from './components/toast';
54
56
  export { Toast, ToastProvider, useToast } from './components/toast';
55
57
  export type { TooltipProps } from './components/tooltip';
56
58
  export { Tooltip } from './components/tooltip';
@@ -70,6 +72,18 @@ export type { ImageFit, ImageProps, SurfaceImageSource } from './primitives/imag
70
72
  export { Image } from './primitives/image';
71
73
  export type { TextProps } from './primitives/text';
72
74
  export { Text } from './primitives/text';
75
+ export type {
76
+ SurfaceColor,
77
+ SurfaceEmphasis,
78
+ SurfacePaletteColor,
79
+ SurfaceStatusColor,
80
+ } from './surfaceColor';
81
+ export {
82
+ SURFACE_COLORS,
83
+ SURFACE_EMPHASES,
84
+ SURFACE_PALETTE_COLORS,
85
+ SURFACE_STATUS_COLORS,
86
+ } from './surfaceColor';
73
87
  export * from './theme';
74
88
  export { isDeepEqual } from './utils/deepEqual';
75
89
  export { deepMerge } from './utils/deepMerge';
@@ -10,6 +10,6 @@ export * from './resolveOverlayAnimation';
10
10
  export * from './resolveOverlayZIndex';
11
11
  export * from './resolveSelectionControlBehavior';
12
12
  export * from './resolveSelectionControlColors';
13
+ export * from './resolveSurfaceColor';
13
14
  export * from './resolveTextColor';
14
15
  export * from './resolveTextStyles';
15
- export * from './resolveTone';
@@ -4,28 +4,30 @@ import { resolveFieldPresentation } from './resolveFieldPresentation';
4
4
  import { resolveFieldState } from './resolveFieldState';
5
5
 
6
6
  describe('resolveFieldPresentation', () => {
7
- it('keeps label and helper tones aligned for default fields', () => {
7
+ it('keeps label and helper text presentation aligned for default fields', () => {
8
8
  expect(resolveFieldPresentation(resolveFieldState({}))).toEqual({
9
- helperTone: 'default',
10
- labelTone: 'default',
9
+ helperEmphasis: 'default',
10
+ labelEmphasis: 'default',
11
11
  });
12
12
  });
13
13
 
14
14
  it('mutes both label and helper text for disabled and read-only fields', () => {
15
15
  expect(resolveFieldPresentation(resolveFieldState({ disabled: true }))).toEqual({
16
- helperTone: 'muted',
17
- labelTone: 'muted',
16
+ helperEmphasis: 'muted',
17
+ labelEmphasis: 'muted',
18
18
  });
19
19
  expect(resolveFieldPresentation(resolveFieldState({ readOnly: true }))).toEqual({
20
- helperTone: 'muted',
21
- labelTone: 'muted',
20
+ helperEmphasis: 'muted',
21
+ labelEmphasis: 'muted',
22
22
  });
23
23
  });
24
24
 
25
- it('elevates invalid fields to the danger tone', () => {
25
+ it('elevates invalid fields to the error color', () => {
26
26
  expect(resolveFieldPresentation(resolveFieldState({ invalid: true, readOnly: true }))).toEqual({
27
- helperTone: 'danger',
28
- labelTone: 'danger',
27
+ helperColor: 'error',
28
+ helperEmphasis: 'default',
29
+ labelColor: 'error',
30
+ labelEmphasis: 'default',
29
31
  });
30
32
  });
31
33
  });
@@ -1,30 +1,32 @@
1
+ import type { SurfaceColor, SurfaceEmphasis } from '../../surfaceColor';
1
2
  import type { FieldState } from './resolveFieldState';
2
- import type { TextTone } from './resolveTextColor';
3
-
4
- type FieldPresentationTone = Extract<TextTone, 'default' | 'muted' | 'danger'>;
5
3
 
6
4
  export interface ResolvedFieldPresentation {
7
- helperTone: FieldPresentationTone;
8
- labelTone: FieldPresentationTone;
5
+ helperColor?: Extract<SurfaceColor, 'error'>;
6
+ helperEmphasis: Extract<SurfaceEmphasis, 'default' | 'muted'>;
7
+ labelColor?: Extract<SurfaceColor, 'error'>;
8
+ labelEmphasis: Extract<SurfaceEmphasis, 'default' | 'muted'>;
9
9
  }
10
10
 
11
11
  export function resolveFieldPresentation(fieldState: FieldState): ResolvedFieldPresentation {
12
12
  if (fieldState.invalid) {
13
13
  return {
14
- helperTone: 'danger',
15
- labelTone: 'danger',
14
+ helperColor: 'error',
15
+ helperEmphasis: 'default',
16
+ labelColor: 'error',
17
+ labelEmphasis: 'default',
16
18
  };
17
19
  }
18
20
 
19
21
  if (fieldState.disabled || fieldState.readOnly) {
20
22
  return {
21
- helperTone: 'muted',
22
- labelTone: 'muted',
23
+ helperEmphasis: 'muted',
24
+ labelEmphasis: 'muted',
23
25
  };
24
26
  }
25
27
 
26
28
  return {
27
- helperTone: 'default',
28
- labelTone: 'default',
29
+ helperEmphasis: 'default',
30
+ labelEmphasis: 'default',
29
31
  };
30
32
  }
@@ -5,11 +5,11 @@ import { resolveFieldState } from './resolveFieldState';
5
5
  import { resolveButtonColors, resolveInputColors } from './resolveInteractiveColors';
6
6
 
7
7
  describe('resolveInteractiveColors', () => {
8
- it('maps button variant, tone, and state through semantic slots', () => {
8
+ it('maps button variant, color, and state through semantic slots', () => {
9
9
  const theme = createTheme();
10
10
  const solid = resolveButtonColors(theme, {
11
11
  variant: 'solid',
12
- tone: 'primary',
12
+ color: 'primary',
13
13
  state: {
14
14
  disabled: false,
15
15
  focused: false,
@@ -19,7 +19,7 @@ describe('resolveInteractiveColors', () => {
19
19
  });
20
20
  const outline = resolveButtonColors(theme, {
21
21
  variant: 'outline',
22
- tone: 'danger',
22
+ color: 'danger',
23
23
  state: {
24
24
  disabled: false,
25
25
  focused: false,
@@ -50,7 +50,7 @@ describe('resolveInteractiveColors', () => {
50
50
  }),
51
51
  );
52
52
 
53
- expect(focusedInvalid.borderColor).toBe(theme.semantics.danger.base);
53
+ expect(focusedInvalid.borderColor).toBe(theme.semantics.error.base);
54
54
  expect(readOnly.backgroundColor).toBe(theme.semantics.surface.subtle);
55
55
  expect(readOnly.placeholderColor).toBe(theme.semantics.content.muted);
56
56
  });
@@ -1,7 +1,8 @@
1
+ import type { SurfaceColor } from '../../surfaceColor';
1
2
  import type { SurfaceTheme } from '../../theme/types';
2
3
  import type { FieldState } from './resolveFieldState';
3
4
  import type { InteractionState } from './resolveInteractiveState';
4
- import { type ComponentTone, resolveTone } from './resolveTone';
5
+ import { resolveSurfaceColor } from './resolveSurfaceColor';
5
6
 
6
7
  export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'soft';
7
8
 
@@ -16,11 +17,11 @@ export function resolveButtonColors(
16
17
  theme: SurfaceTheme,
17
18
  {
18
19
  variant,
19
- tone,
20
+ color,
20
21
  state,
21
22
  }: {
22
23
  variant: ButtonVariant;
23
- tone: ComponentTone;
24
+ color: SurfaceColor;
24
25
  state: InteractionState;
25
26
  },
26
27
  ): ResolvedInteractiveColors {
@@ -33,7 +34,7 @@ export function resolveButtonColors(
33
34
  };
34
35
  }
35
36
 
36
- const semanticTone = resolveTone(theme, tone);
37
+ const semanticTone = resolveSurfaceColor(theme, color);
37
38
 
38
39
  switch (variant) {
39
40
  case 'outline':
@@ -99,9 +100,7 @@ export function resolveInputColors(
99
100
  backgroundColor: fieldState.readOnly
100
101
  ? theme.semantics.surface.subtle
101
102
  : theme.semantics.surface.default,
102
- borderColor: fieldState.focused
103
- ? theme.semantics.danger.base
104
- : theme.semantics.danger.outline,
103
+ borderColor: fieldState.focused ? theme.semantics.error.base : theme.semantics.error.outline,
105
104
  contentColor: theme.semantics.content.default,
106
105
  placeholderColor: theme.semantics.content.muted,
107
106
  };
@@ -5,12 +5,12 @@ import { resolveFieldState } from './resolveFieldState';
5
5
  import { resolveSelectionControlColors } from './resolveSelectionControlColors';
6
6
 
7
7
  describe('resolveSelectionControlColors', () => {
8
- it('maps checked controls through the selected tone semantics', () => {
8
+ it('maps checked controls through the selected color semantics', () => {
9
9
  const theme = createTheme();
10
10
  const colors = resolveSelectionControlColors(theme, {
11
11
  checked: true,
12
12
  fieldState: resolveFieldState({ focused: true }),
13
- tone: 'primary',
13
+ color: 'primary',
14
14
  });
15
15
 
16
16
  expect(colors.borderColor).toBe(theme.semantics.action.primary.base);
@@ -18,24 +18,24 @@ describe('resolveSelectionControlColors', () => {
18
18
  expect(colors.labelColor).toBe(theme.semantics.content.default);
19
19
  });
20
20
 
21
- it('maps invalid unchecked controls through danger/border semantics', () => {
21
+ it('maps invalid unchecked controls through error/border semantics', () => {
22
22
  const theme = createTheme();
23
23
  const colors = resolveSelectionControlColors(theme, {
24
24
  checked: false,
25
25
  fieldState: resolveFieldState({ invalid: true }),
26
- tone: 'primary',
26
+ color: 'primary',
27
27
  });
28
28
 
29
- expect(colors.borderColor).toBe(theme.semantics.danger.outline);
30
- expect(colors.trackColor).toBe(theme.semantics.danger.outline);
29
+ expect(colors.borderColor).toBe(theme.semantics.error.outline);
30
+ expect(colors.trackColor).toBe(theme.semantics.error.outline);
31
31
  });
32
32
 
33
- it('mutes disabled controls regardless of tone', () => {
33
+ it('mutes disabled controls regardless of color', () => {
34
34
  const theme = createTheme();
35
35
  const colors = resolveSelectionControlColors(theme, {
36
36
  checked: true,
37
37
  fieldState: resolveFieldState({ disabled: true }),
38
- tone: 'danger',
38
+ color: 'danger',
39
39
  });
40
40
 
41
41
  expect(colors.labelColor).toBe(theme.semantics.content.muted);