@ankhorage/zora 1.5.0 → 2.0.0

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 (306) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +125 -123
  3. package/dist/components/app-bar/AppBar.js +4 -4
  4. package/dist/components/app-bar/AppBar.js.map +1 -1
  5. package/dist/components/avatar/Avatar.d.ts.map +1 -1
  6. package/dist/components/avatar/Avatar.js +19 -9
  7. package/dist/components/avatar/Avatar.js.map +1 -1
  8. package/dist/components/avatar/types.d.ts +2 -2
  9. package/dist/components/avatar/types.d.ts.map +1 -1
  10. package/dist/components/avatar/types.js.map +1 -1
  11. package/dist/components/avatar-group/AvatarGroup.js +2 -2
  12. package/dist/components/avatar-group/AvatarGroup.js.map +1 -1
  13. package/dist/components/avatar-group/types.d.ts +2 -2
  14. package/dist/components/avatar-group/types.d.ts.map +1 -1
  15. package/dist/components/avatar-group/types.js.map +1 -1
  16. package/dist/components/badge/Badge.js +3 -3
  17. package/dist/components/badge/Badge.js.map +1 -1
  18. package/dist/components/badge/types.d.ts +4 -4
  19. package/dist/components/badge/types.d.ts.map +1 -1
  20. package/dist/components/badge/types.js.map +1 -1
  21. package/dist/components/button/Button.js +3 -3
  22. package/dist/components/button/Button.js.map +1 -1
  23. package/dist/components/button/meta.d.ts +7 -7
  24. package/dist/components/button/meta.d.ts.map +1 -1
  25. package/dist/components/button/meta.js +8 -7
  26. package/dist/components/button/meta.js.map +1 -1
  27. package/dist/components/button/types.d.ts +4 -4
  28. package/dist/components/button/types.d.ts.map +1 -1
  29. package/dist/components/button/types.js.map +1 -1
  30. package/dist/components/card/Card.js +2 -2
  31. package/dist/components/card/Card.js.map +1 -1
  32. package/dist/components/checkbox/CheckboxGroup.js +5 -5
  33. package/dist/components/checkbox/CheckboxGroup.js.map +1 -1
  34. package/dist/components/checkbox/types.d.ts +1 -1
  35. package/dist/components/checkbox/types.d.ts.map +1 -1
  36. package/dist/components/checkbox/types.js.map +1 -1
  37. package/dist/components/chip/Chip.d.ts.map +1 -1
  38. package/dist/components/chip/Chip.js +9 -10
  39. package/dist/components/chip/Chip.js.map +1 -1
  40. package/dist/components/chip/resolveChipColors.d.ts +3 -3
  41. package/dist/components/chip/resolveChipColors.d.ts.map +1 -1
  42. package/dist/components/chip/resolveChipColors.js +14 -4
  43. package/dist/components/chip/resolveChipColors.js.map +1 -1
  44. package/dist/components/chip/types.d.ts +2 -2
  45. package/dist/components/chip/types.d.ts.map +1 -1
  46. package/dist/components/chip/types.js.map +1 -1
  47. package/dist/components/chip-group/ChipGroup.js +2 -2
  48. package/dist/components/chip-group/ChipGroup.js.map +1 -1
  49. package/dist/components/chip-group/types.d.ts +2 -2
  50. package/dist/components/chip-group/types.d.ts.map +1 -1
  51. package/dist/components/chip-group/types.js.map +1 -1
  52. package/dist/components/drawer/Drawer.js +1 -1
  53. package/dist/components/drawer/Drawer.js.map +1 -1
  54. package/dist/components/form/FormError.js +1 -1
  55. package/dist/components/form/FormError.js.map +1 -1
  56. package/dist/components/form/FormField.js +1 -1
  57. package/dist/components/form/FormField.js.map +1 -1
  58. package/dist/components/heading/Heading.d.ts.map +1 -1
  59. package/dist/components/heading/Heading.js +5 -3
  60. package/dist/components/heading/Heading.js.map +1 -1
  61. package/dist/components/heading/index.d.ts +1 -1
  62. package/dist/components/heading/index.d.ts.map +1 -1
  63. package/dist/components/heading/index.js.map +1 -1
  64. package/dist/components/heading/meta.d.ts +9 -3
  65. package/dist/components/heading/meta.d.ts.map +1 -1
  66. package/dist/components/heading/meta.js +10 -3
  67. package/dist/components/heading/meta.js.map +1 -1
  68. package/dist/components/heading/resolveHeadingRecipe.d.ts +4 -3
  69. package/dist/components/heading/resolveHeadingRecipe.d.ts.map +1 -1
  70. package/dist/components/heading/resolveHeadingRecipe.js +33 -12
  71. package/dist/components/heading/resolveHeadingRecipe.js.map +1 -1
  72. package/dist/components/heading/types.d.ts +5 -2
  73. package/dist/components/heading/types.d.ts.map +1 -1
  74. package/dist/components/heading/types.js.map +1 -1
  75. package/dist/components/icon-button/IconButton.js +3 -3
  76. package/dist/components/icon-button/IconButton.js.map +1 -1
  77. package/dist/components/icon-button/types.d.ts +3 -3
  78. package/dist/components/icon-button/types.d.ts.map +1 -1
  79. package/dist/components/icon-button/types.js.map +1 -1
  80. package/dist/components/input/Input.js +1 -1
  81. package/dist/components/input/Input.js.map +1 -1
  82. package/dist/components/media-card/MediaCard.js +2 -2
  83. package/dist/components/media-card/MediaCard.js.map +1 -1
  84. package/dist/components/metric-card/MetricCard.js +5 -5
  85. package/dist/components/metric-card/MetricCard.js.map +1 -1
  86. package/dist/components/metric-card/types.d.ts +2 -2
  87. package/dist/components/metric-card/types.d.ts.map +1 -1
  88. package/dist/components/metric-card/types.js.map +1 -1
  89. package/dist/components/modal/Modal.js +1 -1
  90. package/dist/components/modal/Modal.js.map +1 -1
  91. package/dist/components/progress/Progress.js +2 -2
  92. package/dist/components/progress/Progress.js.map +1 -1
  93. package/dist/components/progress/types.d.ts +3 -3
  94. package/dist/components/progress/types.d.ts.map +1 -1
  95. package/dist/components/progress/types.js +12 -2
  96. package/dist/components/progress/types.js.map +1 -1
  97. package/dist/components/radio/RadioGroup.js +5 -5
  98. package/dist/components/radio/RadioGroup.js.map +1 -1
  99. package/dist/components/radio/types.d.ts +1 -1
  100. package/dist/components/radio/types.d.ts.map +1 -1
  101. package/dist/components/radio/types.js.map +1 -1
  102. package/dist/components/rating/Rating.js +2 -2
  103. package/dist/components/rating/Rating.js.map +1 -1
  104. package/dist/components/rating/types.d.ts +3 -3
  105. package/dist/components/rating/types.d.ts.map +1 -1
  106. package/dist/components/rating/types.js +12 -2
  107. package/dist/components/rating/types.js.map +1 -1
  108. package/dist/components/tabs/Tabs.d.ts.map +1 -1
  109. package/dist/components/tabs/Tabs.js +4 -4
  110. package/dist/components/tabs/Tabs.js.map +1 -1
  111. package/dist/components/text/Text.d.ts.map +1 -1
  112. package/dist/components/text/Text.js +3 -2
  113. package/dist/components/text/Text.js.map +1 -1
  114. package/dist/components/text/index.d.ts +1 -1
  115. package/dist/components/text/index.d.ts.map +1 -1
  116. package/dist/components/text/index.js.map +1 -1
  117. package/dist/components/text/meta.d.ts +10 -4
  118. package/dist/components/text/meta.d.ts.map +1 -1
  119. package/dist/components/text/meta.js +11 -4
  120. package/dist/components/text/meta.js.map +1 -1
  121. package/dist/components/text/resolveTextRecipe.d.ts +4 -3
  122. package/dist/components/text/resolveTextRecipe.d.ts.map +1 -1
  123. package/dist/components/text/resolveTextRecipe.js +35 -13
  124. package/dist/components/text/resolveTextRecipe.js.map +1 -1
  125. package/dist/components/text/types.d.ts +5 -2
  126. package/dist/components/text/types.d.ts.map +1 -1
  127. package/dist/components/text/types.js.map +1 -1
  128. package/dist/components/toolbar/ToolbarAction.js +1 -1
  129. package/dist/components/toolbar/ToolbarAction.js.map +1 -1
  130. package/dist/index.d.ts +4 -2
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +1 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/internal/colorModel.d.ts +10 -0
  135. package/dist/internal/colorModel.d.ts.map +1 -0
  136. package/dist/internal/colorModel.js +25 -0
  137. package/dist/internal/colorModel.js.map +1 -0
  138. package/dist/internal/recipes.d.ts +12 -11
  139. package/dist/internal/recipes.d.ts.map +1 -1
  140. package/dist/internal/recipes.js +6 -6
  141. package/dist/internal/recipes.js.map +1 -1
  142. package/dist/layout/screen/Screen.d.ts.map +1 -1
  143. package/dist/layout/screen/Screen.js +7 -3
  144. package/dist/layout/screen/Screen.js.map +1 -1
  145. package/dist/patterns/auth/ForgotPasswordForm.js +2 -2
  146. package/dist/patterns/auth/ForgotPasswordForm.js.map +1 -1
  147. package/dist/patterns/auth/OtpForm.js +2 -2
  148. package/dist/patterns/auth/OtpForm.js.map +1 -1
  149. package/dist/patterns/auth/SignInForm.js +4 -4
  150. package/dist/patterns/auth/SignInForm.js.map +1 -1
  151. package/dist/patterns/auth/SignUpForm.js +2 -2
  152. package/dist/patterns/auth/SignUpForm.js.map +1 -1
  153. package/dist/patterns/chat-list-item/ChatListItem.d.ts.map +1 -1
  154. package/dist/patterns/chat-list-item/ChatListItem.js +6 -6
  155. package/dist/patterns/chat-list-item/ChatListItem.js.map +1 -1
  156. package/dist/patterns/chat-list-item/types.d.ts +2 -2
  157. package/dist/patterns/chat-list-item/types.d.ts.map +1 -1
  158. package/dist/patterns/chat-list-item/types.js.map +1 -1
  159. package/dist/patterns/collection-editor/CollectionEditor.js +5 -5
  160. package/dist/patterns/collection-editor/CollectionEditor.js.map +1 -1
  161. package/dist/patterns/confirm-dialog/ConfirmDialog.js +3 -3
  162. package/dist/patterns/confirm-dialog/ConfirmDialog.js.map +1 -1
  163. package/dist/patterns/confirm-dialog/types.d.ts +3 -3
  164. package/dist/patterns/confirm-dialog/types.d.ts.map +1 -1
  165. package/dist/patterns/confirm-dialog/types.js.map +1 -1
  166. package/dist/patterns/disclosure-section/DisclosureSection.js +1 -1
  167. package/dist/patterns/disclosure-section/DisclosureSection.js.map +1 -1
  168. package/dist/patterns/empty-state/EmptyState.js +2 -2
  169. package/dist/patterns/empty-state/EmptyState.js.map +1 -1
  170. package/dist/patterns/empty-state/types.d.ts +3 -3
  171. package/dist/patterns/empty-state/types.d.ts.map +1 -1
  172. package/dist/patterns/empty-state/types.js.map +1 -1
  173. package/dist/patterns/form-field/FormField.js +1 -1
  174. package/dist/patterns/form-field/FormField.js.map +1 -1
  175. package/dist/patterns/hero/Hero.js +3 -3
  176. package/dist/patterns/hero/Hero.js.map +1 -1
  177. package/dist/patterns/hero/types.d.ts +3 -3
  178. package/dist/patterns/hero/types.d.ts.map +1 -1
  179. package/dist/patterns/hero/types.js.map +1 -1
  180. package/dist/patterns/image-preview/ImagePreview.js +1 -1
  181. package/dist/patterns/image-preview/ImagePreview.js.map +1 -1
  182. package/dist/patterns/image-upload-field/ImageUploadField.js +7 -7
  183. package/dist/patterns/image-upload-field/ImageUploadField.js.map +1 -1
  184. package/dist/patterns/list/ListRow.js +2 -2
  185. package/dist/patterns/list/ListRow.js.map +1 -1
  186. package/dist/patterns/message-bubble/MessageBubble.d.ts.map +1 -1
  187. package/dist/patterns/message-bubble/MessageBubble.js +6 -6
  188. package/dist/patterns/message-bubble/MessageBubble.js.map +1 -1
  189. package/dist/patterns/message-bubble/types.d.ts +2 -2
  190. package/dist/patterns/message-bubble/types.d.ts.map +1 -1
  191. package/dist/patterns/message-bubble/types.js.map +1 -1
  192. package/dist/patterns/notice/Notice.js +2 -2
  193. package/dist/patterns/notice/Notice.js.map +1 -1
  194. package/dist/patterns/notice/types.d.ts +2 -2
  195. package/dist/patterns/notice/types.d.ts.map +1 -1
  196. package/dist/patterns/notice/types.js.map +1 -1
  197. package/dist/patterns/post-card/PostCard.js +4 -4
  198. package/dist/patterns/post-card/PostCard.js.map +1 -1
  199. package/dist/patterns/post-card/types.d.ts +2 -2
  200. package/dist/patterns/post-card/types.d.ts.map +1 -1
  201. package/dist/patterns/post-card/types.js.map +1 -1
  202. package/dist/patterns/section-header/SectionHeader.js +2 -2
  203. package/dist/patterns/section-header/SectionHeader.js.map +1 -1
  204. package/dist/patterns/settings-row/SettingsRow.js +1 -1
  205. package/dist/patterns/settings-row/SettingsRow.js.map +1 -1
  206. package/dist/patterns/theme-composer/ThemeComposer.js +14 -14
  207. package/dist/patterns/theme-composer/ThemeComposer.js.map +1 -1
  208. package/dist/patterns/tile-grid/PaletteItem.js +1 -1
  209. package/dist/patterns/tile-grid/PaletteItem.js.map +1 -1
  210. package/dist/patterns/timeline/Timeline.d.ts.map +1 -1
  211. package/dist/patterns/timeline/Timeline.js +14 -4
  212. package/dist/patterns/timeline/Timeline.js.map +1 -1
  213. package/dist/patterns/timeline/types.d.ts +2 -2
  214. package/dist/patterns/timeline/types.d.ts.map +1 -1
  215. package/dist/patterns/timeline/types.js.map +1 -1
  216. package/dist/patterns/tree-view/TreeItem.js +1 -1
  217. package/dist/patterns/tree-view/TreeItem.js.map +1 -1
  218. package/dist/patterns/zora-tab-bar/ZoraTabBar.d.ts.map +1 -1
  219. package/dist/patterns/zora-tab-bar/ZoraTabBar.js +64 -15
  220. package/dist/patterns/zora-tab-bar/ZoraTabBar.js.map +1 -1
  221. package/package.json +2 -2
  222. package/src/components/app-bar/AppBar.tsx +6 -6
  223. package/src/components/avatar/Avatar.tsx +21 -11
  224. package/src/components/avatar/types.ts +2 -2
  225. package/src/components/avatar-group/AvatarGroup.tsx +2 -2
  226. package/src/components/avatar-group/types.ts +2 -2
  227. package/src/components/badge/Badge.tsx +4 -4
  228. package/src/components/badge/types.ts +4 -4
  229. package/src/components/button/Button.tsx +4 -4
  230. package/src/components/button/meta.ts +8 -7
  231. package/src/components/button/types.ts +4 -4
  232. package/src/components/card/Card.tsx +2 -2
  233. package/src/components/checkbox/CheckboxGroup.tsx +6 -6
  234. package/src/components/checkbox/types.ts +1 -1
  235. package/src/components/chip/Chip.tsx +9 -10
  236. package/src/components/chip/resolveChipColors.ts +16 -6
  237. package/src/components/chip/types.ts +2 -2
  238. package/src/components/chip-group/ChipGroup.tsx +2 -2
  239. package/src/components/chip-group/types.ts +2 -2
  240. package/src/components/drawer/Drawer.tsx +1 -1
  241. package/src/components/form/FormError.tsx +1 -1
  242. package/src/components/form/FormField.tsx +1 -1
  243. package/src/components/heading/Heading.tsx +6 -3
  244. package/src/components/heading/index.ts +2 -1
  245. package/src/components/heading/meta.ts +10 -3
  246. package/src/components/heading/resolveHeadingRecipe.test.ts +13 -10
  247. package/src/components/heading/resolveHeadingRecipe.ts +58 -15
  248. package/src/components/heading/types.ts +5 -10
  249. package/src/components/icon-button/IconButton.tsx +4 -4
  250. package/src/components/icon-button/types.ts +3 -3
  251. package/src/components/input/Input.tsx +2 -2
  252. package/src/components/media-card/MediaCard.tsx +2 -2
  253. package/src/components/metric-card/MetricCard.tsx +6 -6
  254. package/src/components/metric-card/types.ts +2 -2
  255. package/src/components/modal/Modal.tsx +1 -1
  256. package/src/components/progress/Progress.tsx +2 -2
  257. package/src/components/progress/types.ts +14 -4
  258. package/src/components/radio/RadioGroup.tsx +6 -6
  259. package/src/components/radio/types.ts +1 -1
  260. package/src/components/rating/Rating.tsx +2 -2
  261. package/src/components/rating/types.ts +14 -4
  262. package/src/components/tabs/Tabs.tsx +11 -7
  263. package/src/components/text/Text.tsx +4 -2
  264. package/src/components/text/index.ts +8 -1
  265. package/src/components/text/meta.ts +11 -4
  266. package/src/components/text/resolveTextRecipe.test.ts +18 -14
  267. package/src/components/text/resolveTextRecipe.ts +42 -15
  268. package/src/components/text/types.ts +5 -10
  269. package/src/components/toolbar/ToolbarAction.tsx +2 -2
  270. package/src/index.ts +22 -2
  271. package/src/internal/colorModel.ts +39 -0
  272. package/src/internal/recipes.test.ts +2 -2
  273. package/src/internal/recipes.ts +18 -18
  274. package/src/layout/screen/Screen.tsx +11 -3
  275. package/src/patterns/auth/ForgotPasswordForm.tsx +2 -2
  276. package/src/patterns/auth/OtpForm.tsx +2 -2
  277. package/src/patterns/auth/SignInForm.tsx +4 -4
  278. package/src/patterns/auth/SignUpForm.tsx +2 -2
  279. package/src/patterns/chat-list-item/ChatListItem.tsx +7 -6
  280. package/src/patterns/chat-list-item/types.ts +2 -2
  281. package/src/patterns/collection-editor/CollectionEditor.tsx +6 -6
  282. package/src/patterns/confirm-dialog/ConfirmDialog.tsx +4 -4
  283. package/src/patterns/confirm-dialog/types.ts +3 -3
  284. package/src/patterns/disclosure-section/DisclosureSection.tsx +2 -2
  285. package/src/patterns/empty-state/EmptyState.tsx +4 -4
  286. package/src/patterns/empty-state/types.ts +3 -3
  287. package/src/patterns/form-field/FormField.tsx +1 -1
  288. package/src/patterns/hero/Hero.tsx +4 -4
  289. package/src/patterns/hero/types.ts +3 -3
  290. package/src/patterns/image-preview/ImagePreview.tsx +1 -1
  291. package/src/patterns/image-upload-field/ImageUploadField.tsx +8 -8
  292. package/src/patterns/list/ListRow.tsx +2 -2
  293. package/src/patterns/message-bubble/MessageBubble.tsx +10 -6
  294. package/src/patterns/message-bubble/types.ts +2 -2
  295. package/src/patterns/notice/Notice.tsx +2 -2
  296. package/src/patterns/notice/types.ts +2 -2
  297. package/src/patterns/post-card/PostCard.tsx +5 -5
  298. package/src/patterns/post-card/types.ts +2 -2
  299. package/src/patterns/section-header/SectionHeader.tsx +2 -2
  300. package/src/patterns/settings-row/SettingsRow.tsx +1 -1
  301. package/src/patterns/theme-composer/ThemeComposer.tsx +15 -15
  302. package/src/patterns/tile-grid/PaletteItem.tsx +1 -1
  303. package/src/patterns/timeline/Timeline.tsx +15 -5
  304. package/src/patterns/timeline/types.ts +2 -2
  305. package/src/patterns/tree-view/TreeItem.tsx +1 -1
  306. package/src/patterns/zora-tab-bar/ZoraTabBar.tsx +104 -15
@@ -3,11 +3,11 @@ import React from 'react';
3
3
  import { Image } from 'react-native';
4
4
 
5
5
  import { Box } from '../../foundation';
6
- import type { ZoraTone } from '../../internal/recipes';
6
+ import type { ZoraColor } from '../../internal/recipes';
7
7
  import { useZoraTheme } from '../../theme/useZoraTheme';
8
8
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
9
9
  import { Icon } from '../icon';
10
- import { Text, type TextTone, type TextVariant } from '../text';
10
+ import { Text, type TextVariant } from '../text';
11
11
  import { resolveAvatarInitials } from './resolveAvatarInitials';
12
12
  import type { AvatarProps, AvatarShape, AvatarSize } from './types';
13
13
 
@@ -19,10 +19,20 @@ const AVATAR_SIZES: Record<AvatarSize, number> = {
19
19
  xl: 64,
20
20
  };
21
21
 
22
- function resolveRoleSemantics(theme: SurfaceTheme, tone: ZoraTone): RoleSemantics {
23
- switch (tone) {
22
+ function resolveRoleSemantics(theme: SurfaceTheme, color: ZoraColor): RoleSemantics {
23
+ switch (color) {
24
+ case 'secondary':
25
+ return theme.semantics.secondary;
26
+ case 'tertiary':
27
+ return theme.semantics.accent;
28
+ case 'quaternary':
29
+ return theme.semantics.highlight;
24
30
  case 'primary':
25
31
  return theme.semantics.action.primary;
32
+ case 'error':
33
+ return theme.semantics.error;
34
+ case 'info':
35
+ return theme.semantics.info;
26
36
  case 'danger':
27
37
  return theme.semantics.action.danger;
28
38
  case 'success':
@@ -35,8 +45,8 @@ function resolveRoleSemantics(theme: SurfaceTheme, tone: ZoraTone): RoleSemantic
35
45
  }
36
46
  }
37
47
 
38
- function resolveTextTone(tone: ZoraTone): TextTone {
39
- return tone === 'neutral' ? 'default' : tone;
48
+ function resolveTextColor(color: ZoraColor): ZoraColor | undefined {
49
+ return color === 'neutral' ? undefined : color;
40
50
  }
41
51
 
42
52
  function resolveTextVariant(size: AvatarSize): TextVariant {
@@ -69,20 +79,20 @@ function AvatarInner({
69
79
  label,
70
80
  size = 'm',
71
81
  shape = 'circle',
72
- tone = 'neutral',
82
+ color = 'neutral',
73
83
  }: AvatarProps) {
74
84
  const { theme } = useZoraTheme();
75
85
  const resolvedSize = AVATAR_SIZES[size];
76
86
  const resolvedInitials = initials ?? resolveAvatarInitials(name);
77
- const role = resolveRoleSemantics(theme, tone);
78
- const backgroundColor = tone === 'neutral' ? theme.semantics.neutral.surface : role.softBg;
79
- const contentColor = tone === 'neutral' ? theme.semantics.content.default : role.base;
87
+ const role = resolveRoleSemantics(theme, color);
88
+ const backgroundColor = color === 'neutral' ? theme.semantics.neutral.surface : role.softBg;
89
+ const contentColor = color === 'neutral' ? theme.semantics.content.default : role.base;
80
90
  const radius = resolveRadius(shape);
81
91
 
82
92
  const renderFallback = () => {
83
93
  if (resolvedInitials) {
84
94
  return (
85
- <Text tone={resolveTextTone(tone)} variant={resolveTextVariant(size)} weight="semiBold">
95
+ <Text color={resolveTextColor(color)} variant={resolveTextVariant(size)} weight="semiBold">
86
96
  {resolvedInitials}
87
97
  </Text>
88
98
  );
@@ -1,7 +1,7 @@
1
1
  import type { ButtonIconSpec } from '@ankhorage/surface';
2
2
  import type { ImageSourcePropType } from 'react-native';
3
3
 
4
- import type { ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraColor } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
 
7
7
  export type AvatarSize = 'xs' | 's' | 'm' | 'l' | 'xl';
@@ -16,5 +16,5 @@ export interface AvatarProps extends ZoraBaseProps {
16
16
  label?: string;
17
17
  size?: AvatarSize;
18
18
  shape?: AvatarShape;
19
- tone?: ZoraTone;
19
+ color?: ZoraColor;
20
20
  }
@@ -44,7 +44,7 @@ function AvatarGroupInner({
44
44
  shape={shape}
45
45
  size={size}
46
46
  source={item.source}
47
- tone={item.tone}
47
+ color={item.color}
48
48
  />
49
49
  </Box>
50
50
  );
@@ -63,7 +63,7 @@ function AvatarGroupInner({
63
63
  initials={overflowLabel(overflowCount)}
64
64
  size={size}
65
65
  shape={shape}
66
- tone="neutral"
66
+ color="neutral"
67
67
  />
68
68
  </Box>
69
69
  ) : null}
@@ -1,7 +1,7 @@
1
1
  import type { ButtonIconSpec } from '@ankhorage/surface';
2
2
  import type { ImageSourcePropType } from 'react-native';
3
3
 
4
- import type { ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraColor } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
  import type { AvatarShape, AvatarSize } from '../avatar';
7
7
 
@@ -12,7 +12,7 @@ export interface AvatarGroupItem {
12
12
  initials?: string;
13
13
  iconFallback?: ButtonIconSpec;
14
14
  label?: string;
15
- tone?: ZoraTone;
15
+ color?: ZoraColor;
16
16
  }
17
17
 
18
18
  export interface AvatarGroupProps extends ZoraBaseProps {
@@ -9,19 +9,19 @@ function BadgeInner({
9
9
  themeId: _themeId,
10
10
  mode: _mode,
11
11
  children,
12
- tone,
13
- emphasis,
12
+ color,
13
+ variant,
14
14
  size,
15
15
  ...props
16
16
  }: BadgeProps) {
17
- const recipe = resolveBadgeRecipe({ tone, emphasis, size });
17
+ const recipe = resolveBadgeRecipe({ color, variant, size });
18
18
 
19
19
  return (
20
20
  <SurfaceBadge
21
21
  {...props}
22
22
  content={children}
23
+ color={recipe.color}
23
24
  size={recipe.size}
24
- tone={recipe.tone}
25
25
  variant={recipe.variant}
26
26
  />
27
27
  );
@@ -1,15 +1,15 @@
1
1
  import type { BadgeProps as SurfaceBadgeProps } from '@ankhorage/surface';
2
2
  import type React from 'react';
3
3
 
4
- import type { ZoraBadgeEmphasis, ZoraControlSize, ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraBadgeVariant, ZoraColor, ZoraControlSize } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
 
7
7
  export interface BadgeProps
8
8
  extends
9
9
  ZoraBaseProps,
10
- Omit<SurfaceBadgeProps, 'content' | 'size' | 'tone' | 'variant' | 'mode' | 'themeId'> {
10
+ Omit<SurfaceBadgeProps, 'content' | 'size' | 'color' | 'variant' | 'mode' | 'themeId'> {
11
11
  children?: React.ReactNode;
12
- tone?: ZoraTone;
13
- emphasis?: ZoraBadgeEmphasis;
12
+ color?: ZoraColor;
13
+ variant?: ZoraBadgeVariant;
14
14
  size?: ZoraControlSize;
15
15
  }
@@ -8,15 +8,15 @@ import type { ButtonProps } from './types';
8
8
  function ButtonInner({
9
9
  themeId: _themeId,
10
10
  mode: _mode,
11
- tone,
12
- emphasis,
11
+ color,
12
+ variant,
13
13
  size,
14
14
  ...props
15
15
  }: ButtonProps) {
16
- const recipe = resolveButtonRecipe({ tone, emphasis, size });
16
+ const recipe = resolveButtonRecipe({ color, variant, size });
17
17
 
18
18
  return (
19
- <SurfaceButton {...props} size={recipe.size} tone={recipe.tone} variant={recipe.variant} />
19
+ <SurfaceButton {...props} color={recipe.color} size={recipe.size} variant={recipe.variant} />
20
20
  );
21
21
  }
22
22
 
@@ -1,3 +1,4 @@
1
+ import { ZORA_COLORS } from '../../internal/colorModel';
1
2
  import type { ZoraComponentMeta } from '../../metadata';
2
3
 
3
4
  export const buttonMeta = {
@@ -9,8 +10,8 @@ export const buttonMeta = {
9
10
  label: 'Button',
10
11
  defaultProps: {
11
12
  children: 'Continue',
12
- tone: 'primary',
13
- emphasis: 'solid',
13
+ color: 'primary',
14
+ variant: 'solid',
14
15
  size: 'm',
15
16
  },
16
17
  },
@@ -21,17 +22,17 @@ export const buttonMeta = {
21
22
  label: 'Label',
22
23
  default: 'Continue',
23
24
  },
24
- tone: {
25
+ color: {
25
26
  type: 'enum',
26
27
  category: 'Style',
27
- label: 'Tone',
28
- enum: ['primary', 'neutral', 'danger', 'success', 'warning'],
28
+ label: 'Color',
29
+ enum: [...ZORA_COLORS],
29
30
  default: 'primary',
30
31
  },
31
- emphasis: {
32
+ variant: {
32
33
  type: 'enum',
33
34
  category: 'Style',
34
- label: 'Emphasis',
35
+ label: 'Variant',
35
36
  enum: ['solid', 'outline', 'ghost', 'soft'],
36
37
  default: 'solid',
37
38
  },
@@ -1,14 +1,14 @@
1
1
  import type { ButtonIconSpec, ButtonProps as SurfaceButtonProps } from '@ankhorage/surface';
2
2
  import type React from 'react';
3
3
 
4
- import type { ZoraControlSize, ZoraEmphasis, ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraButtonVariant, ZoraColor, ZoraControlSize } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
 
7
7
  export interface ButtonProps
8
- extends ZoraBaseProps, Omit<SurfaceButtonProps, 'children' | 'size' | 'tone' | 'variant'> {
8
+ extends ZoraBaseProps, Omit<SurfaceButtonProps, 'children' | 'size' | 'color' | 'variant'> {
9
9
  children?: React.ReactNode;
10
- tone?: ZoraTone;
11
- emphasis?: ZoraEmphasis;
10
+ color?: ZoraColor;
11
+ variant?: ZoraButtonVariant;
12
12
  size?: ZoraControlSize;
13
13
  leadingIcon?: ButtonIconSpec;
14
14
  trailingIcon?: ButtonIconSpec;
@@ -46,13 +46,13 @@ function CardInner({
46
46
  <Box flex={{ md: 1 }} width={{ base: '100%', md: 'auto' }}>
47
47
  <Stack gap="xs">
48
48
  {eyebrow ? (
49
- <Text tone="muted" variant="caption" weight="semiBold">
49
+ <Text emphasis="muted" variant="caption" weight="semiBold">
50
50
  {eyebrow}
51
51
  </Text>
52
52
  ) : null}
53
53
  {title ? <Heading level={compact ? 4 : 3}>{title}</Heading> : null}
54
54
  {description ? (
55
- <Text tone="muted" variant="bodySmall">
55
+ <Text emphasis="muted" variant="bodySmall">
56
56
  {description}
57
57
  </Text>
58
58
  ) : null}
@@ -15,7 +15,7 @@ function CheckboxGroupInner<TValue extends string>({
15
15
  options,
16
16
  orientation = 'vertical',
17
17
  gap = 's',
18
- tone = 'primary',
18
+ color = 'primary',
19
19
  size = 'm',
20
20
  invalid = false,
21
21
  readOnly = false,
@@ -47,7 +47,7 @@ function CheckboxGroupInner<TValue extends string>({
47
47
  invalid={invalid}
48
48
  readOnly={readOnly}
49
49
  size={size}
50
- tone={tone}
50
+ color={color}
51
51
  value={value}
52
52
  onValueChange={onValueChange}
53
53
  />
@@ -66,7 +66,7 @@ function CheckboxGroupItem<TValue extends string>({
66
66
  invalid,
67
67
  readOnly,
68
68
  size,
69
- tone,
69
+ color,
70
70
  value,
71
71
  onValueChange,
72
72
  }: {
@@ -76,7 +76,7 @@ function CheckboxGroupItem<TValue extends string>({
76
76
  invalid: boolean;
77
77
  readOnly: boolean;
78
78
  size: NonNullable<CheckboxGroupProps<TValue>['size']>;
79
- tone: NonNullable<CheckboxGroupProps<TValue>['tone']>;
79
+ color: NonNullable<CheckboxGroupProps<TValue>['color']>;
80
80
  value: readonly TValue[];
81
81
  onValueChange: (value: TValue[]) => void;
82
82
  }) {
@@ -87,7 +87,7 @@ function CheckboxGroupItem<TValue extends string>({
87
87
  invalid={invalid}
88
88
  readOnly={readOnly}
89
89
  size={size}
90
- tone={tone}
90
+ color={color}
91
91
  testID={option.testID}
92
92
  onCheckedChange={(nextChecked) => {
93
93
  const nextValue = nextChecked
@@ -100,7 +100,7 @@ function CheckboxGroupItem<TValue extends string>({
100
100
  <Stack gap="xs">
101
101
  <Text>{option.label}</Text>
102
102
  {option.description ? (
103
- <Text variant="caption" tone="muted">
103
+ <Text emphasis="muted" variant="caption">
104
104
  {option.description}
105
105
  </Text>
106
106
  ) : null}
@@ -19,7 +19,7 @@ export interface CheckboxGroupProps<TValue extends string>
19
19
  ZoraBaseProps,
20
20
  Pick<
21
21
  Omit<SurfaceCheckboxProps, 'mode' | 'themeId'>,
22
- 'tone' | 'size' | 'invalid' | 'readOnly' | 'disabled'
22
+ 'color' | 'size' | 'invalid' | 'readOnly' | 'disabled'
23
23
  > {
24
24
  value: readonly TValue[];
25
25
  onValueChange: (value: TValue[]) => void;
@@ -33,7 +33,7 @@ function ChipInner({
33
33
  icon,
34
34
  selected = false,
35
35
  disabled = false,
36
- tone = 'neutral',
36
+ color = 'neutral',
37
37
  size = 's',
38
38
  onPress,
39
39
  }: ChipProps) {
@@ -42,14 +42,13 @@ function ChipInner({
42
42
  const iconSize = resolveIconSize(size);
43
43
 
44
44
  const renderContent = (state: ChipInteractionState) => {
45
- const colors = resolveChipColors({ theme, tone, selected, state });
46
- const textTone = state.disabled
47
- ? 'muted'
48
- : selected
49
- ? tone === 'neutral'
50
- ? 'default'
51
- : tone
52
- : 'default';
45
+ const colors = resolveChipColors({ theme, color, selected, state });
46
+ const textColor = state.disabled
47
+ ? undefined
48
+ : selected && color !== 'neutral'
49
+ ? color
50
+ : undefined;
51
+ const textEmphasis = state.disabled ? 'muted' : 'default';
53
52
 
54
53
  return (
55
54
  <Box
@@ -73,7 +72,7 @@ function ChipInner({
73
72
  size={iconSize}
74
73
  />
75
74
  ) : null}
76
- <Text tone={textTone} variant="label">
75
+ <Text color={textColor} emphasis={textEmphasis} variant="label">
77
76
  {children}
78
77
  </Text>
79
78
  </Inline>
@@ -1,10 +1,20 @@
1
1
  import type { RoleSemantics, SurfaceTheme } from '@ankhorage/surface';
2
2
 
3
- import type { ZoraTone } from '../../internal/recipes';
3
+ import type { ZoraColor } from '../../internal/recipes';
4
4
  import type { ChipColors, ChipInteractionState } from './types';
5
5
 
6
- function resolveChipRole(theme: SurfaceTheme, tone: ZoraTone): RoleSemantics {
7
- switch (tone) {
6
+ function resolveChipRole(theme: SurfaceTheme, color: ZoraColor): RoleSemantics {
7
+ switch (color) {
8
+ case 'secondary':
9
+ return theme.semantics.secondary;
10
+ case 'tertiary':
11
+ return theme.semantics.accent;
12
+ case 'quaternary':
13
+ return theme.semantics.highlight;
14
+ case 'error':
15
+ return theme.semantics.error;
16
+ case 'info':
17
+ return theme.semantics.info;
8
18
  case 'primary':
9
19
  return theme.semantics.action.primary;
10
20
  case 'danger':
@@ -21,12 +31,12 @@ function resolveChipRole(theme: SurfaceTheme, tone: ZoraTone): RoleSemantics {
21
31
 
22
32
  export function resolveChipColors({
23
33
  theme,
24
- tone,
34
+ color,
25
35
  selected,
26
36
  state,
27
37
  }: {
28
38
  theme: SurfaceTheme;
29
- tone: ZoraTone;
39
+ color: ZoraColor;
30
40
  selected: boolean;
31
41
  state: ChipInteractionState;
32
42
  }): ChipColors {
@@ -39,7 +49,7 @@ export function resolveChipColors({
39
49
  };
40
50
  }
41
51
 
42
- const role = resolveChipRole(theme, tone);
52
+ const role = resolveChipRole(theme, color);
43
53
 
44
54
  if (selected) {
45
55
  return {
@@ -1,7 +1,7 @@
1
1
  import type { ButtonIconSpec } from '@ankhorage/surface';
2
2
  import type React from 'react';
3
3
 
4
- import type { ZoraControlSize, ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraColor, ZoraControlSize } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
 
7
7
  export interface ChipProps extends ZoraBaseProps {
@@ -9,7 +9,7 @@ export interface ChipProps extends ZoraBaseProps {
9
9
  icon?: ButtonIconSpec;
10
10
  selected?: boolean;
11
11
  disabled?: boolean;
12
- tone?: ZoraTone;
12
+ color?: ZoraColor;
13
13
  size?: ZoraControlSize;
14
14
  onPress?: () => void;
15
15
  }
@@ -21,7 +21,7 @@ function ChipGroupInner<TValue extends string = string>({
21
21
  value,
22
22
  onValueChange,
23
23
  multiple,
24
- tone = 'neutral',
24
+ color = 'neutral',
25
25
  size = 's',
26
26
  wrap = true,
27
27
  disabled,
@@ -49,7 +49,7 @@ function ChipGroupInner<TValue extends string = string>({
49
49
  selected={isSelected}
50
50
  size={size}
51
51
  testID={item.testID}
52
- tone={tone}
52
+ color={color}
53
53
  >
54
54
  {item.label}
55
55
  </Chip>
@@ -1,7 +1,7 @@
1
1
  import type { ButtonIconSpec } from '@ankhorage/surface';
2
2
  import type React from 'react';
3
3
 
4
- import type { ZoraControlSize, ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraColor, ZoraControlSize } from '../../internal/recipes';
5
5
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
6
6
 
7
7
  export interface ChipGroupItem<TValue extends string = string> {
@@ -14,7 +14,7 @@ export interface ChipGroupItem<TValue extends string = string> {
14
14
 
15
15
  interface ChipGroupBaseProps<TValue extends string> extends ZoraBaseProps {
16
16
  items: readonly ChipGroupItem<TValue>[];
17
- tone?: ZoraTone;
17
+ color?: ZoraColor;
18
18
  size?: ZoraControlSize;
19
19
  wrap?: boolean;
20
20
  disabled?: boolean;
@@ -39,7 +39,7 @@ function DrawerInner({
39
39
  <Stack gap="xs">
40
40
  {title ? <Heading level={3}>{title}</Heading> : null}
41
41
  {description ? (
42
- <Text tone="muted" variant="bodySmall">
42
+ <Text emphasis="muted" variant="bodySmall">
43
43
  {description}
44
44
  </Text>
45
45
  ) : null}
@@ -15,7 +15,7 @@ function FormErrorInner({ themeId: _themeId, mode: _mode, error, testID }: FormE
15
15
 
16
16
  return (
17
17
  <Box borderColor={theme.colors.error} borderWidth={1} p="s" radius="m" testID={testID}>
18
- <Text tone="danger" variant="bodySmall">
18
+ <Text color="error" variant="bodySmall">
19
19
  {error}
20
20
  </Text>
21
21
  </Box>
@@ -77,7 +77,7 @@ function renderLabel(label: React.ReactNode, description: React.ReactNode | unde
77
77
  {label}
78
78
  </Text>
79
79
  {description ? (
80
- <Text tone="muted" variant="bodySmall">
80
+ <Text emphasis="muted" variant="bodySmall">
81
81
  {description}
82
82
  </Text>
83
83
  ) : null}
@@ -39,7 +39,8 @@ function HeadingInner({
39
39
  i18nKey,
40
40
  level = 2,
41
41
  size,
42
- tone = 'default',
42
+ color,
43
+ emphasis = 'default',
43
44
  align,
44
45
  weight,
45
46
  italic = false,
@@ -56,7 +57,8 @@ function HeadingInner({
56
57
  const { breakpoint } = useResponsiveRuntime();
57
58
  const content = resolveHeadingContent({ children, text, i18nKey });
58
59
  const resolvedSize = resolveResponsive(size, breakpoint) ?? resolveHeadingSizeFromLevel(level);
59
- const resolvedTone = resolveResponsive(tone, breakpoint) ?? 'default';
60
+ const resolvedColor = resolveResponsive(color, breakpoint);
61
+ const resolvedEmphasis = resolveResponsive(emphasis, breakpoint) ?? 'default';
60
62
  const resolvedAlign = resolveResponsive(align, breakpoint);
61
63
  const resolvedWeight = resolveResponsive(weight, breakpoint);
62
64
 
@@ -79,7 +81,8 @@ function HeadingInner({
79
81
  italic,
80
82
  level,
81
83
  size: resolvedSize,
82
- tone: resolvedTone,
84
+ color: resolvedColor,
85
+ emphasis: resolvedEmphasis,
83
86
  weight: resolvedWeight,
84
87
  })}
85
88
  >
@@ -1,9 +1,10 @@
1
1
  export { Heading } from './Heading';
2
2
  export type {
3
3
  HeadingAlign,
4
+ HeadingColor,
5
+ HeadingEmphasis,
4
6
  HeadingLevel,
5
7
  HeadingProps,
6
8
  HeadingSize,
7
- HeadingTone,
8
9
  HeadingWeight,
9
10
  } from './types';
@@ -1,3 +1,4 @@
1
+ import { ZORA_COLORS, ZORA_EMPHASES } from '../../internal/colorModel';
1
2
  import type { ZoraComponentMeta } from '../../metadata';
2
3
 
3
4
  export const headingMeta = {
@@ -34,11 +35,17 @@ export const headingMeta = {
34
35
  enum: [1, 2, 3, 4, 5, 6],
35
36
  default: 2,
36
37
  },
37
- tone: {
38
+ color: {
38
39
  type: 'enum',
39
40
  category: 'Style',
40
- label: 'Tone',
41
- enum: ['default', 'muted', 'subtle', 'inverse', 'primary', 'danger', 'success', 'warning'],
41
+ label: 'Color',
42
+ enum: ZORA_COLORS,
43
+ },
44
+ emphasis: {
45
+ type: 'enum',
46
+ category: 'Style',
47
+ label: 'Emphasis',
48
+ enum: ZORA_EMPHASES,
42
49
  },
43
50
  align: {
44
51
  type: 'enum',
@@ -230,28 +230,31 @@ describe('resolveHeadingRecipe', () => {
230
230
  expect(style.fontWeight).toBe(theme.typography.weights.bold);
231
231
  });
232
232
 
233
- test('maps semantic tones to theme colors', () => {
234
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'primary' }).color).toBe(
235
- theme.semantics.brand.base,
233
+ test('maps semantic emphasis and colors to theme colors', () => {
234
+ expect(resolveHeadingRecipe(theme, { level: 2, color: 'primary' }).color).toBe(
235
+ theme.semantics.action.primary.base,
236
236
  );
237
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'muted' }).color).toBe(
237
+ expect(resolveHeadingRecipe(theme, { level: 2, emphasis: 'muted' }).color).toBe(
238
238
  theme.semantics.content.muted,
239
239
  );
240
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'subtle' }).color).toBe(
240
+ expect(resolveHeadingRecipe(theme, { level: 2, emphasis: 'subtle' }).color).toBe(
241
241
  theme.semantics.content.subtle,
242
242
  );
243
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'inverse' }).color).toBe(
243
+ expect(resolveHeadingRecipe(theme, { level: 2, emphasis: 'inverse' }).color).toBe(
244
244
  theme.semantics.content.inverse,
245
245
  );
246
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'danger' }).color).toBe(
247
- theme.semantics.danger.base,
246
+ expect(resolveHeadingRecipe(theme, { level: 2, color: 'danger' }).color).toBe(
247
+ theme.semantics.action.danger.base,
248
248
  );
249
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'success' }).color).toBe(
249
+ expect(resolveHeadingRecipe(theme, { level: 2, color: 'success' }).color).toBe(
250
250
  theme.semantics.success.base,
251
251
  );
252
- expect(resolveHeadingRecipe(theme, { level: 2, tone: 'warning' }).color).toBe(
252
+ expect(resolveHeadingRecipe(theme, { level: 2, color: 'warning' }).color).toBe(
253
253
  theme.semantics.warning.base,
254
254
  );
255
+ expect(
256
+ resolveHeadingRecipe(theme, { level: 2, color: 'primary', emphasis: 'inverse' }).color,
257
+ ).toBe(theme.semantics.action.primary.onSolidText);
255
258
  });
256
259
 
257
260
  test('applies alignment', () => {