@ankhorage/surface 5.0.0 → 6.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 (313) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -3
  3. package/dist/components/field/Field.d.ts +1 -0
  4. package/dist/components/field/Field.d.ts.map +1 -1
  5. package/dist/components/field/Field.js +5 -4
  6. package/dist/components/field/Field.js.map +1 -1
  7. package/dist/components/list-item/ListItem.d.ts +1 -0
  8. package/dist/components/list-item/ListItem.d.ts.map +1 -1
  9. package/dist/components/list-item/ListItem.js +13 -12
  10. package/dist/components/list-item/ListItem.js.map +1 -1
  11. package/dist/components/switch/Switch.d.ts +1 -0
  12. package/dist/components/switch/Switch.d.ts.map +1 -1
  13. package/dist/components/switch/Switch.js +10 -13
  14. package/dist/components/switch/Switch.js.map +1 -1
  15. package/dist/{layout → core/responsive}/Show.d.ts +2 -1
  16. package/dist/core/responsive/Show.d.ts.map +1 -0
  17. package/dist/{layout → core/responsive}/Show.js +3 -1
  18. package/dist/core/responsive/Show.js.map +1 -0
  19. package/dist/core/responsive/index.d.ts +1 -0
  20. package/dist/core/responsive/index.d.ts.map +1 -1
  21. package/dist/core/responsive/index.js +1 -0
  22. package/dist/core/responsive/index.js.map +1 -1
  23. package/dist/features/app-bar/adapters/inbound/AppBar.d.ts +5 -0
  24. package/dist/features/app-bar/adapters/inbound/AppBar.d.ts.map +1 -0
  25. package/dist/features/app-bar/adapters/inbound/AppBar.js +40 -0
  26. package/dist/features/app-bar/adapters/inbound/AppBar.js.map +1 -0
  27. package/dist/features/app-bar/public.d.ts +3 -0
  28. package/dist/features/app-bar/public.d.ts.map +1 -0
  29. package/dist/features/app-bar/public.js +2 -0
  30. package/dist/features/app-bar/public.js.map +1 -0
  31. package/dist/features/badge/adapters/inbound/Badge.js +3 -3
  32. package/dist/features/badge/adapters/inbound/Badge.js.map +1 -1
  33. package/dist/features/button/adapters/inbound/Button.js +8 -8
  34. package/dist/features/button/adapters/inbound/Button.js.map +1 -1
  35. package/dist/features/button/adapters/inbound/IconButton.js +3 -3
  36. package/dist/features/button/adapters/inbound/IconButton.js.map +1 -1
  37. package/dist/features/form/checkbox/adapters/inbound/Checkbox.js +7 -7
  38. package/dist/features/form/checkbox/adapters/inbound/Checkbox.js.map +1 -1
  39. package/dist/features/form/radio/adapters/inbound/Radio.js +8 -8
  40. package/dist/features/form/radio/adapters/inbound/Radio.js.map +1 -1
  41. package/dist/features/layout/adapters/inbound/Divider.js +2 -2
  42. package/dist/features/layout/adapters/inbound/Divider.js.map +1 -1
  43. package/dist/features/layout/adapters/inbound/Grid.d.ts.map +1 -1
  44. package/dist/features/layout/adapters/inbound/Grid.js +7 -9
  45. package/dist/features/layout/adapters/inbound/Grid.js.map +1 -1
  46. package/dist/features/layout/adapters/inbound/ScrollView.d.ts +5 -0
  47. package/dist/features/layout/adapters/inbound/ScrollView.d.ts.map +1 -0
  48. package/dist/features/layout/adapters/inbound/ScrollView.js +69 -0
  49. package/dist/features/layout/adapters/inbound/ScrollView.js.map +1 -0
  50. package/dist/features/layout/adapters/inbound/View.d.ts +5 -0
  51. package/dist/features/layout/adapters/inbound/View.d.ts.map +1 -0
  52. package/dist/features/layout/adapters/inbound/View.js +17 -0
  53. package/dist/features/layout/adapters/inbound/View.js.map +1 -0
  54. package/dist/features/layout/public.d.ts +3 -4
  55. package/dist/features/layout/public.d.ts.map +1 -1
  56. package/dist/features/layout/public.js +2 -3
  57. package/dist/features/layout/public.js.map +1 -1
  58. package/dist/{components/modal → features/modal/adapters/inbound}/Modal.d.ts +2 -1
  59. package/dist/features/modal/adapters/inbound/Modal.d.ts.map +1 -0
  60. package/dist/features/modal/adapters/inbound/Modal.js +51 -0
  61. package/dist/features/modal/adapters/inbound/Modal.js.map +1 -0
  62. package/dist/features/modal/public.d.ts +3 -0
  63. package/dist/features/modal/public.d.ts.map +1 -0
  64. package/dist/features/modal/public.js +2 -0
  65. package/dist/features/modal/public.js.map +1 -0
  66. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts.map +1 -1
  67. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js +11 -12
  68. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js.map +1 -1
  69. package/dist/features/surface/adapters/inbound/Surface.d.ts +1 -1
  70. package/dist/features/surface/adapters/inbound/Surface.d.ts.map +1 -1
  71. package/dist/features/surface/adapters/inbound/Surface.js +3 -3
  72. package/dist/features/surface/adapters/inbound/Surface.js.map +1 -1
  73. package/dist/features/tabs/adapters/inbound/Tab.d.ts +5 -0
  74. package/dist/features/tabs/adapters/inbound/Tab.d.ts.map +1 -0
  75. package/dist/features/tabs/adapters/inbound/Tab.js +33 -0
  76. package/dist/features/tabs/adapters/inbound/Tab.js.map +1 -0
  77. package/dist/features/tabs/adapters/inbound/TabList.d.ts +5 -0
  78. package/dist/features/tabs/adapters/inbound/TabList.d.ts.map +1 -0
  79. package/dist/features/tabs/adapters/inbound/TabList.js +40 -0
  80. package/dist/features/tabs/adapters/inbound/TabList.js.map +1 -0
  81. package/dist/features/tabs/adapters/inbound/TabPanel.d.ts +5 -0
  82. package/dist/features/tabs/adapters/inbound/TabPanel.d.ts.map +1 -0
  83. package/dist/features/tabs/adapters/inbound/TabPanel.js +14 -0
  84. package/dist/features/tabs/adapters/inbound/TabPanel.js.map +1 -0
  85. package/dist/features/tabs/adapters/inbound/Tabs.d.ts +5 -0
  86. package/dist/features/tabs/adapters/inbound/Tabs.d.ts.map +1 -0
  87. package/dist/features/tabs/adapters/inbound/Tabs.js +12 -0
  88. package/dist/features/tabs/adapters/inbound/Tabs.js.map +1 -0
  89. package/dist/features/tabs/composition/TabsContext.d.ts +4 -0
  90. package/dist/features/tabs/composition/TabsContext.d.ts.map +1 -0
  91. package/dist/features/tabs/composition/TabsContext.js +3 -0
  92. package/dist/features/tabs/composition/TabsContext.js.map +1 -0
  93. package/dist/features/tabs/composition/useTabRegistration.d.ts +7 -0
  94. package/dist/features/tabs/composition/useTabRegistration.d.ts.map +1 -0
  95. package/dist/features/tabs/composition/useTabRegistration.js +20 -0
  96. package/dist/features/tabs/composition/useTabRegistration.js.map +1 -0
  97. package/dist/features/tabs/composition/useTabsContext.d.ts +4 -0
  98. package/dist/features/tabs/composition/useTabsContext.d.ts.map +1 -0
  99. package/dist/{components/tabs/context.js → features/tabs/composition/useTabsContext.js} +4 -4
  100. package/dist/features/tabs/composition/useTabsContext.js.map +1 -0
  101. package/dist/features/tabs/composition/useTabsController.d.ts +4 -0
  102. package/dist/features/tabs/composition/useTabsController.d.ts.map +1 -0
  103. package/dist/features/tabs/composition/useTabsController.js +43 -0
  104. package/dist/features/tabs/composition/useTabsController.js.map +1 -0
  105. package/dist/features/tabs/public.d.ts +6 -0
  106. package/dist/features/tabs/public.d.ts.map +1 -0
  107. package/dist/features/tabs/public.js +5 -0
  108. package/dist/features/tabs/public.js.map +1 -0
  109. package/dist/features/tabs/utils/resolveNextTabValue.d.ts +4 -0
  110. package/dist/features/tabs/utils/resolveNextTabValue.d.ts.map +1 -0
  111. package/dist/{components/tabs/navigation.js → features/tabs/utils/resolveNextTabValue.js} +10 -13
  112. package/dist/features/tabs/utils/resolveNextTabValue.js.map +1 -0
  113. package/dist/features/tabs/utils/resolveTabElementId.d.ts +3 -0
  114. package/dist/features/tabs/utils/resolveTabElementId.d.ts.map +1 -0
  115. package/dist/features/tabs/utils/resolveTabElementId.js +10 -0
  116. package/dist/features/tabs/utils/resolveTabElementId.js.map +1 -0
  117. package/dist/features/toast/adapters/inbound/Toast.js +5 -5
  118. package/dist/features/toast/adapters/inbound/Toast.js.map +1 -1
  119. package/dist/features/toast/adapters/inbound/ToastProvider.js +3 -3
  120. package/dist/features/toast/adapters/inbound/ToastProvider.js.map +1 -1
  121. package/dist/index.d.ts +8 -7
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +4 -4
  124. package/dist/index.js.map +1 -1
  125. package/dist/primitives/button-base/ButtonBase.d.ts +1 -0
  126. package/dist/primitives/button-base/ButtonBase.d.ts.map +1 -1
  127. package/dist/primitives/button-base/ButtonBase.js +6 -5
  128. package/dist/primitives/button-base/ButtonBase.js.map +1 -1
  129. package/dist/primitives/button-base/types.d.ts +2 -2
  130. package/dist/primitives/button-base/types.d.ts.map +1 -1
  131. package/dist/primitives/button-base/types.js.map +1 -1
  132. package/dist/types/app-bar.d.ts +12 -0
  133. package/dist/types/app-bar.d.ts.map +1 -0
  134. package/dist/types/app-bar.js +2 -0
  135. package/dist/types/app-bar.js.map +1 -0
  136. package/dist/types/layout.d.ts +15 -17
  137. package/dist/types/layout.d.ts.map +1 -1
  138. package/dist/types/layout.js.map +1 -1
  139. package/dist/{components/modal/types.d.ts → types/modal.d.ts} +2 -2
  140. package/dist/types/modal.d.ts.map +1 -0
  141. package/dist/types/modal.js +2 -0
  142. package/dist/types/modal.js.map +1 -0
  143. package/dist/types/surface.d.ts +2 -2
  144. package/dist/types/surface.d.ts.map +1 -1
  145. package/dist/types/surface.js.map +1 -1
  146. package/dist/types/tabs.d.ts +43 -0
  147. package/dist/types/tabs.d.ts.map +1 -0
  148. package/dist/types/tabs.js +2 -0
  149. package/dist/types/tabs.js.map +1 -0
  150. package/dist/utils/resolveViewStyles.d.ts +7 -0
  151. package/dist/utils/resolveViewStyles.d.ts.map +1 -0
  152. package/dist/utils/{resolveBoxStyles.js → resolveViewStyles.js} +11 -4
  153. package/dist/utils/resolveViewStyles.js.map +1 -0
  154. package/package.json +1 -1
  155. package/src/components/field/Field.tsx +5 -4
  156. package/src/components/list-item/ListItem.tsx +17 -13
  157. package/src/components/switch/Switch.tsx +10 -15
  158. package/src/{layout → core/responsive}/Show.tsx +4 -1
  159. package/src/core/responsive/index.ts +1 -0
  160. package/src/features/app-bar/adapters/inbound/AppBar.tsx +69 -0
  161. package/src/features/app-bar/public.ts +2 -0
  162. package/src/features/badge/adapters/inbound/Badge.tsx +3 -3
  163. package/src/features/button/adapters/inbound/Button.tsx +8 -8
  164. package/src/features/button/adapters/inbound/IconButton.tsx +3 -3
  165. package/src/features/form/checkbox/adapters/inbound/Checkbox.tsx +7 -7
  166. package/src/features/form/radio/adapters/inbound/Radio.tsx +8 -8
  167. package/src/features/layout/adapters/inbound/Divider.tsx +2 -2
  168. package/src/features/layout/adapters/inbound/Grid.tsx +12 -14
  169. package/src/features/layout/adapters/inbound/ScrollView.tsx +102 -0
  170. package/src/features/layout/adapters/inbound/{Box.tsx → View.tsx} +9 -9
  171. package/src/features/layout/public.ts +3 -10
  172. package/src/features/modal/adapters/inbound/Modal.tsx +77 -0
  173. package/src/features/modal/public.ts +2 -0
  174. package/src/features/popover-menu/adapters/inbound/PopoverMenu.tsx +11 -14
  175. package/src/features/surface/adapters/inbound/Surface.tsx +3 -3
  176. package/src/features/tabs/adapters/inbound/Tab.tsx +67 -0
  177. package/src/features/tabs/adapters/inbound/TabList.tsx +47 -0
  178. package/src/{components/tabs → features/tabs/adapters/inbound}/TabPanel.tsx +6 -10
  179. package/src/features/tabs/adapters/inbound/Tabs.tsx +17 -0
  180. package/src/features/tabs/composition/TabsContext.tsx +5 -0
  181. package/src/features/tabs/composition/useTabRegistration.ts +27 -0
  182. package/src/features/tabs/composition/useTabsContext.ts +13 -0
  183. package/src/features/tabs/composition/useTabsController.ts +55 -0
  184. package/src/features/tabs/public.ts +5 -0
  185. package/src/{components/tabs/navigation.test.ts → features/tabs/utils/resolveNextTabValue.test.ts} +2 -2
  186. package/src/features/tabs/utils/resolveNextTabValue.ts +24 -0
  187. package/src/features/tabs/utils/resolveTabElementId.test.ts +19 -0
  188. package/src/features/tabs/utils/resolveTabElementId.ts +14 -0
  189. package/src/features/toast/adapters/inbound/Toast.tsx +5 -5
  190. package/src/features/toast/adapters/inbound/ToastProvider.tsx +3 -3
  191. package/src/index.test.ts +14 -38
  192. package/src/index.ts +8 -13
  193. package/src/primitives/button-base/ButtonBase.tsx +6 -8
  194. package/src/primitives/button-base/types.ts +2 -2
  195. package/src/types/app-bar.ts +13 -0
  196. package/src/types/layout.ts +25 -20
  197. package/src/{components/modal/types.ts → types/modal.ts} +1 -1
  198. package/src/types/surface.ts +2 -2
  199. package/src/types/tabs.ts +51 -0
  200. package/src/utils/resolveViewStyles.test.ts +71 -0
  201. package/src/utils/{resolveBoxStyles.ts → resolveViewStyles.ts} +16 -9
  202. package/src/webAcceptance.test.tsx +8 -9
  203. package/dist/components/modal/Modal.d.ts.map +0 -1
  204. package/dist/components/modal/Modal.js +0 -59
  205. package/dist/components/modal/Modal.js.map +0 -1
  206. package/dist/components/modal/index.d.ts +0 -3
  207. package/dist/components/modal/index.d.ts.map +0 -1
  208. package/dist/components/modal/index.js +0 -2
  209. package/dist/components/modal/index.js.map +0 -1
  210. package/dist/components/modal/types.d.ts.map +0 -1
  211. package/dist/components/modal/types.js +0 -2
  212. package/dist/components/modal/types.js.map +0 -1
  213. package/dist/components/tabs/Tab.d.ts +0 -4
  214. package/dist/components/tabs/Tab.d.ts.map +0 -1
  215. package/dist/components/tabs/Tab.js +0 -48
  216. package/dist/components/tabs/Tab.js.map +0 -1
  217. package/dist/components/tabs/TabList.d.ts +0 -4
  218. package/dist/components/tabs/TabList.d.ts.map +0 -1
  219. package/dist/components/tabs/TabList.js +0 -37
  220. package/dist/components/tabs/TabList.js.map +0 -1
  221. package/dist/components/tabs/TabPanel.d.ts +0 -4
  222. package/dist/components/tabs/TabPanel.d.ts.map +0 -1
  223. package/dist/components/tabs/TabPanel.js +0 -16
  224. package/dist/components/tabs/TabPanel.js.map +0 -1
  225. package/dist/components/tabs/Tabs.d.ts +0 -4
  226. package/dist/components/tabs/Tabs.d.ts.map +0 -1
  227. package/dist/components/tabs/Tabs.js +0 -54
  228. package/dist/components/tabs/Tabs.js.map +0 -1
  229. package/dist/components/tabs/a11y.d.ts +0 -3
  230. package/dist/components/tabs/a11y.d.ts.map +0 -1
  231. package/dist/components/tabs/a11y.js +0 -13
  232. package/dist/components/tabs/a11y.js.map +0 -1
  233. package/dist/components/tabs/context.d.ts +0 -20
  234. package/dist/components/tabs/context.d.ts.map +0 -1
  235. package/dist/components/tabs/context.js.map +0 -1
  236. package/dist/components/tabs/index.d.ts +0 -6
  237. package/dist/components/tabs/index.d.ts.map +0 -1
  238. package/dist/components/tabs/index.js +0 -5
  239. package/dist/components/tabs/index.js.map +0 -1
  240. package/dist/components/tabs/navigation.d.ts +0 -3
  241. package/dist/components/tabs/navigation.d.ts.map +0 -1
  242. package/dist/components/tabs/navigation.js.map +0 -1
  243. package/dist/components/tabs/types.d.ts +0 -26
  244. package/dist/components/tabs/types.d.ts.map +0 -1
  245. package/dist/components/tabs/types.js +0 -2
  246. package/dist/components/tabs/types.js.map +0 -1
  247. package/dist/features/layout/adapters/inbound/Box.d.ts +0 -5
  248. package/dist/features/layout/adapters/inbound/Box.d.ts.map +0 -1
  249. package/dist/features/layout/adapters/inbound/Box.js +0 -17
  250. package/dist/features/layout/adapters/inbound/Box.js.map +0 -1
  251. package/dist/features/layout/adapters/inbound/Container.d.ts +0 -5
  252. package/dist/features/layout/adapters/inbound/Container.d.ts.map +0 -1
  253. package/dist/features/layout/adapters/inbound/Container.js +0 -28
  254. package/dist/features/layout/adapters/inbound/Container.js.map +0 -1
  255. package/dist/features/layout/adapters/inbound/Stack.d.ts +0 -5
  256. package/dist/features/layout/adapters/inbound/Stack.d.ts.map +0 -1
  257. package/dist/features/layout/adapters/inbound/Stack.js +0 -27
  258. package/dist/features/layout/adapters/inbound/Stack.js.map +0 -1
  259. package/dist/layout/AppBar.d.ts +0 -13
  260. package/dist/layout/AppBar.d.ts.map +0 -1
  261. package/dist/layout/AppBar.js +0 -30
  262. package/dist/layout/AppBar.js.map +0 -1
  263. package/dist/layout/Center.d.ts +0 -7
  264. package/dist/layout/Center.d.ts.map +0 -1
  265. package/dist/layout/Center.js +0 -12
  266. package/dist/layout/Center.js.map +0 -1
  267. package/dist/layout/Inline.d.ts +0 -5
  268. package/dist/layout/Inline.d.ts.map +0 -1
  269. package/dist/layout/Inline.js +0 -6
  270. package/dist/layout/Inline.js.map +0 -1
  271. package/dist/layout/ScrollArea.d.ts +0 -9
  272. package/dist/layout/ScrollArea.d.ts.map +0 -1
  273. package/dist/layout/ScrollArea.js +0 -52
  274. package/dist/layout/ScrollArea.js.map +0 -1
  275. package/dist/layout/Show.d.ts.map +0 -1
  276. package/dist/layout/Show.js.map +0 -1
  277. package/dist/layout/Spacer.d.ts +0 -9
  278. package/dist/layout/Spacer.d.ts.map +0 -1
  279. package/dist/layout/Spacer.js +0 -12
  280. package/dist/layout/Spacer.js.map +0 -1
  281. package/dist/layout/Template.d.ts +0 -18
  282. package/dist/layout/Template.d.ts.map +0 -1
  283. package/dist/layout/Template.js +0 -36
  284. package/dist/layout/Template.js.map +0 -1
  285. package/dist/layout/index.d.ts +0 -15
  286. package/dist/layout/index.d.ts.map +0 -1
  287. package/dist/layout/index.js +0 -8
  288. package/dist/layout/index.js.map +0 -1
  289. package/dist/utils/resolveBoxStyles.d.ts +0 -7
  290. package/dist/utils/resolveBoxStyles.d.ts.map +0 -1
  291. package/dist/utils/resolveBoxStyles.js.map +0 -1
  292. package/src/components/modal/Modal.tsx +0 -96
  293. package/src/components/modal/index.ts +0 -2
  294. package/src/components/tabs/Tab.tsx +0 -89
  295. package/src/components/tabs/TabList.tsx +0 -51
  296. package/src/components/tabs/Tabs.tsx +0 -67
  297. package/src/components/tabs/a11y.test.ts +0 -15
  298. package/src/components/tabs/a11y.ts +0 -15
  299. package/src/components/tabs/context.tsx +0 -31
  300. package/src/components/tabs/index.ts +0 -5
  301. package/src/components/tabs/navigation.ts +0 -32
  302. package/src/components/tabs/types.ts +0 -30
  303. package/src/features/layout/adapters/inbound/Container.tsx +0 -43
  304. package/src/features/layout/adapters/inbound/Stack.test.ts +0 -13
  305. package/src/features/layout/adapters/inbound/Stack.tsx +0 -44
  306. package/src/layout/AppBar.tsx +0 -60
  307. package/src/layout/Center.tsx +0 -22
  308. package/src/layout/Inline.tsx +0 -9
  309. package/src/layout/ScrollArea.tsx +0 -116
  310. package/src/layout/Spacer.tsx +0 -22
  311. package/src/layout/Template.tsx +0 -86
  312. package/src/layout/index.ts +0 -14
  313. package/src/utils/resolveBoxStyles.test.ts +0 -54
@@ -14,7 +14,7 @@ import type { ButtonBaseProps } from '../../../../../primitives/button-base/type
14
14
  import { useTheme } from '../../../../../theme/ThemeContext';
15
15
  import type { SurfaceTheme } from '../../../../../theme/types';
16
16
  import type { RadioProps } from '../../../../../types/radio';
17
- import { Box } from '../../../../layout/public';
17
+ import { View } from '../../../../layout/public';
18
18
  import { Text } from '../../../../typography/public';
19
19
  import { isRadioTextContent } from '../../utils/isRadioTextContent';
20
20
 
@@ -130,8 +130,8 @@ function renderRadioContent(input: RadioContentInput) {
130
130
  input.children !== undefined && input.children !== null && input.children !== false;
131
131
 
132
132
  return (
133
- <Box style={resolveSelectionRowStyle(colors.opacity)}>
134
- <Box
133
+ <View style={resolveSelectionRowStyle(colors.opacity)}>
134
+ <View
135
135
  radius="full"
136
136
  style={resolveRadioIndicatorStyle(
137
137
  colors.backgroundColor,
@@ -140,22 +140,22 @@ function renderRadioContent(input: RadioContentInput) {
140
140
  )}
141
141
  >
142
142
  {input.isChecked ? (
143
- <Box
143
+ <View
144
144
  radius="full"
145
145
  style={resolveRadioDotStyle(colors.indicatorColor, indicatorSize.radioDot)}
146
146
  />
147
147
  ) : null}
148
- </Box>
148
+ </View>
149
149
  {hasContent ? (
150
- <Box flex={1} ml="s">
150
+ <View flex={1} ml="s">
151
151
  {isRadioTextContent(input.children) ? (
152
152
  <Text emphasis={labelEmphasis}>{input.children}</Text>
153
153
  ) : (
154
154
  input.children
155
155
  )}
156
- </Box>
156
+ </View>
157
157
  ) : null}
158
- </Box>
158
+ </View>
159
159
  );
160
160
  }
161
161
 
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import type { DividerProps } from '../../../../types/layout';
4
- import { Box } from './Box';
4
+ import { View } from './View';
5
5
 
6
6
  /*** Renders a horizontal or vertical separator using layout tokens. */
7
7
  export function Divider({
@@ -11,7 +11,7 @@ export function Divider({
11
11
  ...props
12
12
  }: DividerProps) {
13
13
  return (
14
- <Box
14
+ <View
15
15
  {...props}
16
16
  bg={color}
17
17
  height={orientation === 'horizontal' ? thickness : '100%'}
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { View, type ViewStyle } from 'react-native';
2
+ import { View as ReactNativeView, type ViewStyle } from 'react-native';
3
3
 
4
4
  import { resolveResponsive, useResponsiveRuntime } from '../../../../core/responsive';
5
5
  import { useTheme } from '../../../../theme/ThemeContext';
6
6
  import type { GridProps } from '../../../../types/layout';
7
7
  import { resolveSpacing } from '../../../../utils/resolveSpacing';
8
- import { Box } from './Box';
8
+ import { View } from './View';
9
9
 
10
10
  /*** Lays out children in a responsive wrapping grid. */
11
11
  export function Grid({
@@ -31,18 +31,16 @@ export function Grid({
31
31
  const basisPercent: `${number}%` = `${100 / activeCols}%`;
32
32
 
33
33
  return (
34
- <Box {...props}>
35
- <View style={resolveGridStyle(rowSpacing, colSpacing)}>
36
- {React.Children.toArray(children).map((node, index) => (
37
- <View
38
- key={String(index)}
39
- style={resolveGridItemStyle(activeMinItemWidth, basisPercent, rowSpacing, colSpacing)}
40
- >
41
- {node}
42
- </View>
43
- ))}
44
- </View>
45
- </Box>
34
+ <View {...props} style={[resolveGridStyle(rowSpacing, colSpacing), props.style]}>
35
+ {React.Children.toArray(children).map((node, index) => (
36
+ <ReactNativeView
37
+ key={React.isValidElement(node) && node.key !== null ? String(node.key) : String(index)}
38
+ style={resolveGridItemStyle(activeMinItemWidth, basisPercent, rowSpacing, colSpacing)}
39
+ >
40
+ {node}
41
+ </ReactNativeView>
42
+ ))}
43
+ </View>
46
44
  );
47
45
  }
48
46
 
@@ -0,0 +1,102 @@
1
+ import React from 'react';
2
+ import { ScrollView as ReactNativeScrollView } from 'react-native';
3
+
4
+ import { useResponsiveRuntime } from '../../../../core/responsive';
5
+ import { useTheme } from '../../../../theme/ThemeContext';
6
+ import type { ScrollViewProps } from '../../../../types/layout';
7
+ import { resolveViewStyles } from '../../../../utils/resolveViewStyles';
8
+
9
+ /*** Renders the token-aware responsive Surface adapter for React Native ScrollView. */
10
+ export function ScrollView(props: ScrollViewProps) {
11
+ const { theme } = useTheme();
12
+ const { breakpoint } = useResponsiveRuntime();
13
+ const spacing = splitSpacingProps(props);
14
+ const visual = splitVisualProps(spacing.rest);
15
+ const dimensions = splitDimensionProps(visual.rest);
16
+ const layout = splitLayoutProps(dimensions.rest);
17
+ const { children, contentContainerStyle, style, ...scrollProps } = layout.rest;
18
+ const resolved = resolveViewStyles(theme, breakpoint, {
19
+ ...spacing.styleProps,
20
+ ...visual.styleProps,
21
+ ...dimensions.styleProps,
22
+ ...layout.styleProps,
23
+ });
24
+
25
+ return (
26
+ <ReactNativeScrollView
27
+ {...scrollProps}
28
+ contentContainerStyle={contentContainerStyle}
29
+ style={[resolved, style]}
30
+ >
31
+ {children}
32
+ </ReactNativeScrollView>
33
+ );
34
+ }
35
+
36
+ /*** Splits spacing-aware Surface props from native ScrollView props. */
37
+ function splitSpacingProps(props: ScrollViewProps) {
38
+ const { p, px, py, pt, pb, pl, pr, m, mx, my, mt, mb, ml, mr, gap, rowGap, columnGap, ...rest } =
39
+ props;
40
+ return {
41
+ rest,
42
+ styleProps: { p, px, py, pt, pb, pl, pr, m, mx, my, mt, mb, ml, mr, gap, rowGap, columnGap },
43
+ };
44
+ }
45
+
46
+ /*** Splits token-aware visual Surface props from native ScrollView props. */
47
+ function splitVisualProps(props: ReturnType<typeof splitSpacingProps>['rest']) {
48
+ const { bg, radius, borderWidth, borderColor, ...rest } = props;
49
+ return { rest, styleProps: { bg, radius, borderWidth, borderColor } };
50
+ }
51
+
52
+ /*** Splits responsive dimension Surface props from native ScrollView props. */
53
+ function splitDimensionProps(props: ReturnType<typeof splitVisualProps>['rest']) {
54
+ const { width, height, minWidth, maxWidth, minHeight, maxHeight, ...rest } = props;
55
+ return { rest, styleProps: { width, height, minWidth, maxWidth, minHeight, maxHeight } };
56
+ }
57
+
58
+ /*** Splits responsive flex and positioning Surface props from native ScrollView props. */
59
+ function splitLayoutProps(props: ReturnType<typeof splitDimensionProps>['rest']) {
60
+ const {
61
+ flex,
62
+ flexGrow,
63
+ flexShrink,
64
+ flexBasis,
65
+ direction,
66
+ align,
67
+ justify,
68
+ wrap,
69
+ alignSelf,
70
+ position,
71
+ top,
72
+ bottom,
73
+ left,
74
+ right,
75
+ overflow,
76
+ zIndex,
77
+ opacity,
78
+ ...rest
79
+ } = props;
80
+ return {
81
+ rest,
82
+ styleProps: {
83
+ flex,
84
+ flexGrow,
85
+ flexShrink,
86
+ flexBasis,
87
+ direction,
88
+ align,
89
+ justify,
90
+ wrap,
91
+ alignSelf,
92
+ position,
93
+ top,
94
+ bottom,
95
+ left,
96
+ right,
97
+ overflow,
98
+ zIndex,
99
+ opacity,
100
+ },
101
+ };
102
+ }
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
- import { View } from 'react-native';
2
+ import { View as ReactNativeView } from 'react-native';
3
3
 
4
4
  import { useResponsiveRuntime } from '../../../../core/responsive';
5
5
  import { resolvePointerEvents } from '../../../../internal/resolvePointerEvents';
6
6
  import { useTheme } from '../../../../theme/ThemeContext';
7
- import type { BoxProps } from '../../../../types/layout';
8
- import { resolveBoxStyles } from '../../../../utils/resolveBoxStyles';
7
+ import type { ViewProps } from '../../../../types/layout';
8
+ import { resolveViewStyles } from '../../../../utils/resolveViewStyles';
9
9
 
10
- /*** Renders the responsive foundational layout box. */
11
- export function Box({
10
+ /*** Renders the token-aware responsive Surface adapter for React Native View. */
11
+ export function View({
12
12
  accessible,
13
13
  accessibilityLabel,
14
14
  accessibilityRole,
@@ -18,14 +18,14 @@ export function Box({
18
18
  style,
19
19
  testID,
20
20
  ...props
21
- }: BoxProps) {
21
+ }: ViewProps) {
22
22
  const { theme } = useTheme();
23
23
  const { breakpoint } = useResponsiveRuntime();
24
- const resolved = resolveBoxStyles(theme, breakpoint, props);
24
+ const resolved = resolveViewStyles(theme, breakpoint, props);
25
25
  const resolvedPointerEvents = pointerEvents ? resolvePointerEvents(pointerEvents) : null;
26
26
 
27
27
  return (
28
- <View
28
+ <ReactNativeView
29
29
  {...resolvedPointerEvents?.props}
30
30
  accessible={accessible}
31
31
  accessibilityLabel={accessibilityLabel}
@@ -35,6 +35,6 @@ export function Box({
35
35
  style={[resolved, resolvedPointerEvents?.style, style]}
36
36
  >
37
37
  {children}
38
- </View>
38
+ </ReactNativeView>
39
39
  );
40
40
  }
@@ -1,12 +1,5 @@
1
- export type {
2
- BoxProps,
3
- ContainerProps,
4
- DividerProps,
5
- GridProps,
6
- StackProps,
7
- } from '../../types/layout';
8
- export { Box } from './adapters/inbound/Box';
9
- export { Container } from './adapters/inbound/Container';
1
+ export type { DividerProps, GridProps, ScrollViewProps, ViewProps } from '../../types/layout';
10
2
  export { Divider } from './adapters/inbound/Divider';
11
3
  export { Grid } from './adapters/inbound/Grid';
12
- export { Stack } from './adapters/inbound/Stack';
4
+ export { ScrollView } from './adapters/inbound/ScrollView';
5
+ export { View } from './adapters/inbound/View';
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import { Pressable, StyleSheet, View as ReactNativeView, type ViewStyle } from 'react-native';
3
+
4
+ import { FocusScope } from '../../../../internal/focus/FocusScope';
5
+ import { Portal } from '../../../../internal/overlay/Portal';
6
+ import { resolvePointerEvents } from '../../../../internal/resolvePointerEvents';
7
+ import { resolveOverlayAnimation } from '../../../../internal/resolvers';
8
+ import { useTheme } from '../../../../theme/ThemeContext';
9
+ import type { ModalProps } from '../../../../types/modal';
10
+ import { View } from '../../../layout/public';
11
+ import { Surface } from '../../../surface/public';
12
+
13
+ const boxNonePointerEvents = resolvePointerEvents('box-none');
14
+
15
+ /*** Renders the generic Surface modal overlay and focus boundary. */
16
+ export function Modal({
17
+ visible,
18
+ onDismiss,
19
+ children,
20
+ closeOnBackdrop = true,
21
+ interactionPolicy = 'enabled',
22
+ testID,
23
+ }: ModalProps) {
24
+ const { theme } = useTheme();
25
+ const animation = resolveOverlayAnimation('modal');
26
+ const passive = interactionPolicy === 'passive';
27
+ const backdropPress = passive || !closeOnBackdrop ? undefined : onDismiss;
28
+
29
+ if (!visible) return null;
30
+
31
+ return (
32
+ <Portal layer="modal" visible={visible}>
33
+ <ReactNativeView
34
+ {...boxNonePointerEvents.props}
35
+ style={[boxNonePointerEvents.style, styles.fill]}
36
+ >
37
+ <Pressable
38
+ onPress={backdropPress}
39
+ style={[
40
+ styles.fill,
41
+ resolveBackdropStyle(theme.semantics.neutral.text, animation.backdropOpacity),
42
+ ]}
43
+ testID={testID ? `${testID}-backdrop` : undefined}
44
+ />
45
+ <FocusScope
46
+ active={visible}
47
+ onEscape={passive ? undefined : onDismiss}
48
+ testID={testID ? `${testID}-focus` : undefined}
49
+ >
50
+ <View align="center" justify="center" p="l" style={styles.center}>
51
+ <ReactNativeView accessible accessibilityViewIsModal style={styles.content}>
52
+ <Surface p="l" style={styles.surface} testID={testID} variant="raised">
53
+ {children}
54
+ </Surface>
55
+ </ReactNativeView>
56
+ </View>
57
+ </FocusScope>
58
+ </ReactNativeView>
59
+ </Portal>
60
+ );
61
+ }
62
+
63
+ /*** Resolves the runtime backdrop color and opacity without inline JSX styles. */
64
+ function resolveBackdropStyle(backgroundColor: string, opacity: number): ViewStyle {
65
+ return { backgroundColor, opacity };
66
+ }
67
+
68
+ const styles = StyleSheet.create({
69
+ center: { flex: 1 },
70
+ content: { maxWidth: 560, width: '100%' },
71
+ fill: { bottom: 0, left: 0, position: 'absolute', right: 0, top: 0 },
72
+ surface: {
73
+ shadowOffset: { height: 8, width: 0 },
74
+ shadowOpacity: 0.14,
75
+ shadowRadius: 18,
76
+ },
77
+ });
@@ -0,0 +1,2 @@
1
+ export type { ModalProps } from '../../types/modal';
2
+ export { Modal } from './adapters/inbound/Modal';
@@ -3,10 +3,9 @@ import { Pressable } from 'react-native';
3
3
 
4
4
  import { FocusScope } from '../../../../internal/focus/FocusScope';
5
5
  import { useFocusManager } from '../../../../internal/focus/useFocusManager';
6
- import { Inline } from '../../../../layout';
7
6
  import { useTheme } from '../../../../theme/ThemeContext';
8
7
  import type { PopoverMenuAction, PopoverMenuProps } from '../../../../types/popoverMenu';
9
- import { Box, Stack } from '../../../layout/public';
8
+ import { View } from '../../../layout/public';
10
9
  import { Popover } from '../../../popover/public';
11
10
  import { Surface } from '../../../surface/public';
12
11
  import { Text } from '../../../typography/public';
@@ -103,10 +102,8 @@ function usePopoverMenuKeyboard({
103
102
  () =>
104
103
  bindKeydown((event) => {
105
104
  if (passive) return;
106
-
107
105
  const { key } = event;
108
106
  if (key === undefined) return;
109
-
110
107
  if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(key)) {
111
108
  event.preventDefault();
112
109
  setActiveIndex((current) => resolveNextMenuIndex(actions, current, key));
@@ -152,7 +149,7 @@ function PopoverMenuItem({
152
149
  onPress={passive ? undefined : () => activateAction(action)}
153
150
  testID={testID ? `${testID}-item-${action.id}` : undefined}
154
151
  >
155
- <Box
152
+ <View
156
153
  bg={selected ? theme.semantics.action.neutral.softBg : 'transparent'}
157
154
  opacity={action.disabled ? 0.56 : 1}
158
155
  px="m"
@@ -160,7 +157,7 @@ function PopoverMenuItem({
160
157
  radius="s"
161
158
  >
162
159
  <PopoverMenuItemContent action={action} active={active} />
163
- </Box>
160
+ </View>
164
161
  </Pressable>
165
162
  );
166
163
  }
@@ -177,10 +174,10 @@ function PopoverMenuItemContent({
177
174
  action.intent === 'danger' ? 'danger' : active || action.selected ? 'neutral' : undefined;
178
175
 
179
176
  return (
180
- <Inline align="center" gap="s" justify="space-between" wrap="nowrap">
181
- {action.leading ? <Box>{action.leading}</Box> : null}
182
- <Box flex={1}>
183
- <Stack gap="xxs">
177
+ <View align="center" direction="row" gap="s" justify="space-between" wrap="nowrap">
178
+ {action.leading ? <View>{action.leading}</View> : null}
179
+ <View flex={1}>
180
+ <View gap="xxs">
184
181
  <Text
185
182
  color={titleColor}
186
183
  variant="bodySmall"
@@ -193,9 +190,9 @@ function PopoverMenuItemContent({
193
190
  {action.description}
194
191
  </Text>
195
192
  ) : null}
196
- </Stack>
197
- </Box>
198
- {action.trailing ? <Box>{action.trailing}</Box> : null}
199
- </Inline>
193
+ </View>
194
+ </View>
195
+ {action.trailing ? <View>{action.trailing}</View> : null}
196
+ </View>
200
197
  );
201
198
  }
@@ -3,9 +3,9 @@ import type { ViewStyle } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../../../../theme/ThemeContext';
5
5
  import type { SurfaceProps, SurfaceVariant } from '../../../../types/surface';
6
- import { Box } from '../../../layout/public';
6
+ import { View } from '../../../layout/public';
7
7
 
8
- /*** Renders a themed container surface with semantic elevation and border variants. */
8
+ /*** Renders a themed content surface with semantic elevation and border variants. */
9
9
  export function Surface({ variant = 'default', radius = 'm', style, ...props }: SurfaceProps) {
10
10
  const { theme } = useTheme();
11
11
  const backgroundColor =
@@ -17,7 +17,7 @@ export function Surface({ variant = 'default', radius = 'm', style, ...props }:
17
17
  const borderColor = theme.semantics.border.default;
18
18
 
19
19
  return (
20
- <Box
20
+ <View
21
21
  {...props}
22
22
  radius={radius}
23
23
  style={[resolveSurfaceVariantStyles(variant, borderColor, backgroundColor), style]}
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { Pressable, type ViewStyle } from 'react-native';
3
+
4
+ import { useTheme } from '../../../../theme/ThemeContext';
5
+ import type { TabProps } from '../../../../types/tabs';
6
+ import { View } from '../../../layout/public';
7
+ import { Text } from '../../../typography/public';
8
+ import { useTabRegistration } from '../../composition/useTabRegistration';
9
+ import { useTabsContext } from '../../composition/useTabsContext';
10
+
11
+ /*** Renders one accessible selectable tab inside a Tabs context. */
12
+ export function Tab({
13
+ value,
14
+ children,
15
+ disabled = false,
16
+ interactionPolicy = 'enabled',
17
+ testID,
18
+ }: TabProps) {
19
+ const { theme } = useTheme();
20
+ const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue } = useTabsContext();
21
+ const pressableRef = useTabRegistration({ disabled, value });
22
+ const selected = activeValue === value;
23
+ const passive = interactionPolicy === 'passive';
24
+ const onPress = passive || disabled ? undefined : () => setActiveValue(value);
25
+
26
+ return (
27
+ <Pressable
28
+ accessibilityLabel={undefined}
29
+ accessibilityRole="tab"
30
+ accessibilityState={{ disabled, selected }}
31
+ aria-controls={getPanelId(value)}
32
+ disabled={disabled}
33
+ nativeID={getTabId(value)}
34
+ onBlur={() => setFocusedValue(undefined)}
35
+ onFocus={() => setFocusedValue(value)}
36
+ onPress={onPress}
37
+ ref={pressableRef}
38
+ testID={testID}
39
+ >
40
+ <View
41
+ px="m"
42
+ py="s"
43
+ style={resolveTabStyle({
44
+ borderColor: selected
45
+ ? theme.semantics.action.primary.base
46
+ : theme.semantics.border.default,
47
+ disabled,
48
+ })}
49
+ >
50
+ <Text color={selected ? 'primary' : undefined} variant="label" weight="medium">
51
+ {children}
52
+ </Text>
53
+ </View>
54
+ </Pressable>
55
+ );
56
+ }
57
+
58
+ /*** Resolves active and disabled visual state without inline JSX styles. */
59
+ function resolveTabStyle({
60
+ borderColor,
61
+ disabled,
62
+ }: {
63
+ borderColor: string;
64
+ disabled: boolean;
65
+ }): ViewStyle {
66
+ return { borderBottomColor: borderColor, borderBottomWidth: 2, opacity: disabled ? 0.64 : 1 };
67
+ }
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+
3
+ import { useFocusManager } from '../../../../internal/focus/useFocusManager';
4
+ import type { TabListProps, TabNavigationKey } from '../../../../types/tabs';
5
+ import { View } from '../../../layout/public';
6
+ import { useTabsContext } from '../../composition/useTabsContext';
7
+ import { resolveNextTabValue } from '../../utils/resolveNextTabValue';
8
+
9
+ const navigationKeys: readonly string[] = [
10
+ 'ArrowLeft',
11
+ 'ArrowRight',
12
+ 'ArrowUp',
13
+ 'ArrowDown',
14
+ 'Home',
15
+ 'End',
16
+ ];
17
+
18
+ /*** Renders the accessible tab list and owns keyboard focus navigation. */
19
+ export function TabList({ children, testID }: TabListProps) {
20
+ const { bindKeydown } = useFocusManager();
21
+ const { focusedValue, setActiveValue, tabs } = useTabsContext();
22
+
23
+ React.useEffect(() => {
24
+ if (!focusedValue) return undefined;
25
+
26
+ return bindKeydown((event) => {
27
+ if (!isTabNavigationKey(event.key)) return;
28
+ const nextValue = resolveNextTabValue(tabs, focusedValue, event.key);
29
+ if (!nextValue) return;
30
+
31
+ event.preventDefault();
32
+ tabs.find((tab) => tab.value === nextValue)?.focus();
33
+ setActiveValue(nextValue);
34
+ });
35
+ }, [bindKeydown, focusedValue, setActiveValue, tabs]);
36
+
37
+ return (
38
+ <View accessibilityRole="tablist" direction="row" testID={testID}>
39
+ {children}
40
+ </View>
41
+ );
42
+ }
43
+
44
+ /*** Narrows keyboard event keys to the tab navigation key contract. */
45
+ function isTabNavigationKey(key: string | undefined): key is TabNavigationKey {
46
+ return key !== undefined && navigationKeys.includes(key);
47
+ }
@@ -1,26 +1,22 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
 
4
- import { useTabsContext } from './context';
5
- import type { TabPanelProps } from './types';
4
+ import type { TabPanelProps } from '../../../../types/tabs';
5
+ import { useTabsContext } from '../../composition/useTabsContext';
6
6
 
7
7
  const TAB_PANEL_ROLE = 'tabpanel' as React.ComponentProps<typeof View>['accessibilityRole'];
8
8
 
9
+ /*** Renders the content panel associated with the active tab value. */
9
10
  export function TabPanel({ value, children, testID }: TabPanelProps) {
10
11
  const { activeValue, getPanelId, getTabId } = useTabsContext();
11
12
 
12
- if (activeValue !== value) {
13
- return null;
14
- }
15
-
16
- const tabId = getTabId(value);
17
- const panelId = getPanelId(value);
13
+ if (activeValue !== value) return null;
18
14
 
19
15
  return (
20
16
  <View
21
- accessibilityLabelledBy={tabId}
17
+ accessibilityLabelledBy={getTabId(value)}
22
18
  accessibilityRole={TAB_PANEL_ROLE}
23
- nativeID={panelId}
19
+ nativeID={getPanelId(value)}
24
20
  testID={testID}
25
21
  >
26
22
  {children}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ import type { TabsProps } from '../../../../types/tabs';
4
+ import { View } from '../../../layout/public';
5
+ import { TabsContext } from '../../composition/TabsContext';
6
+ import { useTabsController } from '../../composition/useTabsController';
7
+
8
+ /*** Provides accessible tab selection state to TabList, Tab, and TabPanel children. */
9
+ export function Tabs({ children, ...props }: TabsProps) {
10
+ const contextValue = useTabsController(props);
11
+
12
+ return (
13
+ <TabsContext value={contextValue}>
14
+ <View testID={props.testID}>{children}</View>
15
+ </TabsContext>
16
+ );
17
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ import type { TabsContextValue } from '../../../types/tabs';
4
+
5
+ export const TabsContext = React.createContext<TabsContextValue | null>(null);
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import type { Pressable } from 'react-native';
3
+
4
+ import { useTabsContext } from './useTabsContext';
5
+
6
+ /*** Registers one focusable tab with the owning Tabs context. */
7
+ export function useTabRegistration({ disabled, value }: { disabled: boolean; value: string }) {
8
+ const { registerTab, unregisterTab } = useTabsContext();
9
+ const pressableRef = React.useRef<React.ElementRef<typeof Pressable> | null>(null);
10
+
11
+ React.useEffect(() => {
12
+ registerTab({
13
+ disabled,
14
+ focus: () => {
15
+ const focusable = pressableRef.current as unknown as {
16
+ focus?: (() => void) | undefined;
17
+ } | null;
18
+ focusable?.focus?.();
19
+ },
20
+ value,
21
+ });
22
+
23
+ return () => unregisterTab(value);
24
+ }, [disabled, registerTab, unregisterTab, value]);
25
+
26
+ return pressableRef;
27
+ }
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ import type { TabsContextValue } from '../../../types/tabs';
4
+ import { TabsContext } from './TabsContext';
5
+
6
+ /*** Returns the active Tabs feature context. */
7
+ export function useTabsContext(): TabsContextValue {
8
+ const value = React.use(TabsContext);
9
+
10
+ if (!value) throw new Error('Tabs components must be used within <Tabs>.');
11
+
12
+ return value;
13
+ }