@planningcenter/tapestry-react 1.4.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 (319) hide show
  1. package/dist/cjs/ActionsDropdown/ActionsDropdown.js +3 -3
  2. package/dist/cjs/Badge/Badge.js +41 -26
  3. package/dist/cjs/Badge/Status.js +2 -2
  4. package/dist/cjs/Calendar/Calendar.js +5 -3
  5. package/dist/cjs/Card/Card.js +2 -0
  6. package/dist/cjs/Checkbox/Checkbox.js +3 -3
  7. package/dist/cjs/ChurchCenterStatus/ChurchCenterStatus.js +4 -4
  8. package/dist/cjs/ColumnView/ColumnView.js +5 -2
  9. package/dist/cjs/Combobox/ComboboxPopover.js +2 -2
  10. package/dist/cjs/DataTable/components/CheckboxCell.js +4 -4
  11. package/dist/cjs/DataTable/components/ColumnPicker.js +6 -5
  12. package/dist/cjs/DataTable/hooks/useCollapsibleRows.js +1 -1
  13. package/dist/cjs/DataTable/hooks/useColumnSort.js +1 -1
  14. package/dist/cjs/DataTable/utils/getParsedColumns.js +4 -4
  15. package/dist/cjs/DateField/DateField.js +1 -1
  16. package/dist/cjs/Drawer/Drawer.js +4 -1
  17. package/dist/cjs/Dropdown/Dropdown.js +1 -1
  18. package/dist/cjs/Dropdown/Dropdown.test.js +194 -19
  19. package/dist/cjs/Dropdown/Link.js +3 -1
  20. package/dist/cjs/EditActions/EditActions.js +9 -3
  21. package/dist/cjs/FieldSet/FieldSet.js +24 -10
  22. package/dist/cjs/FilterLayout/FilterLayout.js +2 -1
  23. package/dist/cjs/Form/Form.js +1 -1
  24. package/dist/cjs/GridView/GridView.js +6 -4
  25. package/dist/cjs/Group/Group.js +10 -3
  26. package/dist/cjs/HeadingUppercase/HeadingUppercase.js +2 -2
  27. package/dist/cjs/HelperDrawer/HelperDrawer.js +1 -1
  28. package/dist/cjs/Highlight/Highlight.js +11 -5
  29. package/dist/cjs/Icon/Status.js +4 -4
  30. package/dist/cjs/Input/InputBox.js +1 -1
  31. package/dist/cjs/List/ListItem.js +1 -1
  32. package/dist/cjs/Menu/Heading.js +1 -0
  33. package/dist/cjs/Modal/Modal.test.js +156 -0
  34. package/dist/cjs/Pagination/Pagination.js +4 -2
  35. package/dist/cjs/Popover/Popover.js +4 -0
  36. package/dist/cjs/Popover/Popover.test.js +65 -0
  37. package/dist/cjs/Popover/rewireTabOrder.js +13 -30
  38. package/dist/cjs/Progress/Progress.js +12 -6
  39. package/dist/cjs/Radio/Radio.js +2 -2
  40. package/dist/cjs/RangeSlider/RangeSlider.js +10 -4
  41. package/dist/cjs/Scrim/Scrim.js +2 -2
  42. package/dist/cjs/Section/Section.js +14 -6
  43. package/dist/cjs/Select/Option.js +1 -1
  44. package/dist/cjs/Select/Select.js +10 -1
  45. package/dist/cjs/Sidebar/Sidebar.js +4 -3
  46. package/dist/cjs/Sortable/SortableItem.js +1 -1
  47. package/dist/cjs/StackView/StackView.js +5 -5
  48. package/dist/cjs/StepperField/StepperField.js +9 -6
  49. package/dist/cjs/StepperProgress/StepperProgress.js +9 -5
  50. package/dist/cjs/Table/ColumnPicker.js +1 -1
  51. package/dist/cjs/Table/DragHandle.js +1 -1
  52. package/dist/cjs/Table/NavigationArrow.js +1 -1
  53. package/dist/cjs/Table/SubRowToggleCell.js +1 -1
  54. package/dist/cjs/Table/Table.js +4 -6
  55. package/dist/cjs/Tabs/Tab.js +1 -0
  56. package/dist/cjs/ThemeProvider/ThemeProvider.js +5 -5
  57. package/dist/cjs/TileView/TileView.js +1 -1
  58. package/dist/cjs/TokenInput/DefaultToken.js +1 -1
  59. package/dist/cjs/Wizard/Wizard.js +2 -1
  60. package/dist/cjs/WrapView/WrapView.js +2 -27
  61. package/dist/cjs/hooks/use-accessibility-violation.js +1 -1
  62. package/dist/cjs/hooks/useConstant.js +23 -0
  63. package/dist/cjs/system/default-theme.js +8 -3
  64. package/dist/cjs/system/utils.js +2 -2
  65. package/dist/cjs/utils.js +3 -3
  66. package/dist/esm/ActionsDropdown/ActionsDropdown.js +3 -3
  67. package/dist/esm/Badge/Badge.js +42 -27
  68. package/dist/esm/Badge/Status.js +2 -2
  69. package/dist/esm/Calendar/Calendar.js +5 -3
  70. package/dist/esm/Card/Card.js +2 -3
  71. package/dist/esm/Checkbox/Checkbox.js +3 -3
  72. package/dist/esm/ChurchCenterStatus/ChurchCenterStatus.js +4 -4
  73. package/dist/esm/ColumnView/ColumnView.js +4 -2
  74. package/dist/esm/Combobox/ComboboxPopover.js +2 -2
  75. package/dist/esm/DataTable/components/CheckboxCell.js +4 -4
  76. package/dist/esm/DataTable/components/ColumnPicker.js +6 -5
  77. package/dist/esm/DataTable/hooks/useCollapsibleRows.js +1 -1
  78. package/dist/esm/DataTable/hooks/useColumnSort.js +1 -1
  79. package/dist/esm/DataTable/utils/getParsedColumns.js +4 -4
  80. package/dist/esm/DateField/DateField.js +1 -1
  81. package/dist/esm/Drawer/Drawer.js +3 -1
  82. package/dist/esm/Dropdown/Dropdown.js +1 -1
  83. package/dist/esm/Dropdown/Dropdown.test.js +158 -17
  84. package/dist/esm/Dropdown/Link.js +3 -1
  85. package/dist/esm/EditActions/EditActions.js +8 -3
  86. package/dist/esm/FieldSet/FieldSet.js +22 -10
  87. package/dist/esm/FilterLayout/FilterLayout.js +2 -1
  88. package/dist/esm/Form/Form.js +1 -1
  89. package/dist/esm/GridView/GridView.js +5 -4
  90. package/dist/esm/Group/Group.js +10 -3
  91. package/dist/esm/HeadingUppercase/HeadingUppercase.js +3 -3
  92. package/dist/esm/HelperDrawer/HelperDrawer.js +1 -1
  93. package/dist/esm/Highlight/Highlight.js +9 -5
  94. package/dist/esm/Icon/Status.js +4 -4
  95. package/dist/esm/Input/InputBox.js +1 -1
  96. package/dist/esm/List/ListItem.js +1 -1
  97. package/dist/esm/Menu/Heading.js +1 -0
  98. package/dist/esm/Modal/Modal.test.js +122 -0
  99. package/dist/esm/Pagination/Pagination.js +4 -2
  100. package/dist/esm/Popover/Popover.js +4 -0
  101. package/dist/esm/Popover/Popover.test.js +51 -0
  102. package/dist/esm/Popover/rewireTabOrder.js +13 -33
  103. package/dist/esm/Progress/Progress.js +10 -6
  104. package/dist/esm/Radio/Radio.js +2 -2
  105. package/dist/esm/RangeSlider/RangeSlider.js +8 -4
  106. package/dist/esm/Scrim/Scrim.js +2 -2
  107. package/dist/esm/Section/Section.js +12 -6
  108. package/dist/esm/Select/Option.js +1 -1
  109. package/dist/esm/Select/Select.js +10 -1
  110. package/dist/esm/Sidebar/Sidebar.js +4 -2
  111. package/dist/esm/Sortable/SortableItem.js +1 -1
  112. package/dist/esm/StackView/StackView.js +4 -5
  113. package/dist/esm/StepperField/StepperField.js +10 -7
  114. package/dist/esm/StepperProgress/StepperProgress.js +8 -5
  115. package/dist/esm/Table/ColumnPicker.js +1 -1
  116. package/dist/esm/Table/DragHandle.js +1 -1
  117. package/dist/esm/Table/NavigationArrow.js +1 -1
  118. package/dist/esm/Table/SubRowToggleCell.js +1 -1
  119. package/dist/esm/Table/Table.js +2 -3
  120. package/dist/esm/Tabs/Tab.js +1 -0
  121. package/dist/esm/ThemeProvider/ThemeProvider.js +1 -1
  122. package/dist/esm/TileView/TileView.js +1 -1
  123. package/dist/esm/TokenInput/DefaultToken.js +1 -1
  124. package/dist/esm/Wizard/Wizard.js +2 -1
  125. package/dist/esm/WrapView/WrapView.js +2 -28
  126. package/dist/esm/hooks/use-accessibility-violation.js +1 -1
  127. package/dist/esm/hooks/useConstant.js +15 -0
  128. package/dist/esm/system/default-theme.js +6 -2
  129. package/dist/esm/system/utils.js +1 -1
  130. package/dist/esm/utils.js +3 -3
  131. package/dist/types/Alert/Alert.d.ts +3 -0
  132. package/dist/types/Box/Box.d.ts +11 -2
  133. package/dist/types/Button/Button.d.ts +9 -1
  134. package/dist/types/Button/Input.d.ts +1 -1
  135. package/dist/types/Card/Card.d.ts +8 -1
  136. package/dist/types/Dropdown/Dropdown.test.d.ts +1 -1
  137. package/dist/types/GridView/GridView.d.ts +16 -4
  138. package/dist/types/Group/Group.d.ts +5 -1
  139. package/dist/types/Modal/Modal.test.d.ts +1 -0
  140. package/dist/types/Popover/Popover.test.d.ts +1 -0
  141. package/dist/types/Scrim/Scrim.d.ts +6 -1
  142. package/dist/types/StackView/StackView.d.ts +11 -0
  143. package/dist/types/Text/Text.d.ts +12 -0
  144. package/dist/types/TileView/TileView.d.ts +15 -7
  145. package/dist/types/WrapView/WrapView.d.ts +2 -1
  146. package/dist/types/hooks/useConstant.d.ts +1 -0
  147. package/package.json +16 -24
  148. package/src/ActionsDropdown/ActionsDropdown.tsx +3 -3
  149. package/src/Alert/Alert.mdx +1 -0
  150. package/src/Alert/Alert.tsx +5 -0
  151. package/src/Avatar/Avatar.mdx +1 -0
  152. package/src/Badge/Badge.js +66 -25
  153. package/src/Badge/Badge.mdx +2 -1
  154. package/src/Badge/Status.js +2 -2
  155. package/src/Badge/Status.mdx +1 -0
  156. package/src/Box/Box.mdx +2 -1
  157. package/src/Box/Box.tsx +13 -2
  158. package/src/Button/Button.mdx +4 -3
  159. package/src/Button/Button.tsx +11 -0
  160. package/src/Button/Input.mdx +2 -2
  161. package/src/Calendar/Calendar.js +8 -3
  162. package/src/Calendar/Calendar.mdx +1 -0
  163. package/src/Card/Card.mdx +1 -0
  164. package/src/Card/Card.tsx +7 -1
  165. package/src/Checkbox/Checkbox.js +8 -3
  166. package/src/Checkbox/Checkbox.mdx +1 -0
  167. package/src/CheckboxCard/CheckboxCard.js +26 -1
  168. package/src/CheckboxCard/CheckboxCard.mdx +1 -0
  169. package/src/CheckboxGroup/CheckboxGroup.js +6 -0
  170. package/src/CheckboxGroup/CheckboxGroup.mdx +1 -0
  171. package/src/ChurchCenterStatus/ChurchCenterStatus.mdx +1 -0
  172. package/src/ChurchCenterStatus/ChurchCenterStatus.tsx +4 -4
  173. package/src/Collapse/Collapse.js +2 -0
  174. package/src/ColumnView/ColumnView.js +7 -3
  175. package/src/ColumnView/ColumnView.mdx +1 -0
  176. package/src/Combobox/Combobox.js +11 -1
  177. package/src/Combobox/Combobox.mdx +2 -1
  178. package/src/Combobox/ComboboxPopover.js +2 -2
  179. package/src/DataTable/DataTable.js +48 -0
  180. package/src/DataTable/DataTable.mdx +2 -2
  181. package/src/DataTable/components/CheckboxCell.js +5 -4
  182. package/src/DataTable/components/ColumnPicker.js +4 -4
  183. package/src/DataTable/hooks/useCollapsibleRows.js +1 -1
  184. package/src/DataTable/hooks/useColumnSort.js +1 -1
  185. package/src/DataTable/utils/getParsedColumns.js +4 -4
  186. package/src/DateField/DateField.js +11 -1
  187. package/src/DateField/DateField.mdx +1 -0
  188. package/src/Divider/Divider.mdx +1 -0
  189. package/src/DragDrop/DragDrop.mdx +23 -9
  190. package/src/Drawer/Drawer.js +3 -0
  191. package/src/Drawer/Drawer.mdx +2 -1
  192. package/src/Dropdown/Dropdown.js +49 -3
  193. package/src/Dropdown/Dropdown.mdx +3 -2
  194. package/src/Dropdown/Dropdown.test.tsx +128 -17
  195. package/src/Dropdown/Link.js +3 -1
  196. package/src/EditActions/EditActions.js +18 -3
  197. package/src/EditActions/EditActions.mdx +1 -0
  198. package/src/Field/Field.js +15 -0
  199. package/src/Field/Field.mdx +1 -0
  200. package/src/FieldSet/FieldSet.js +35 -11
  201. package/src/FieldSet/FieldSet.mdx +1 -0
  202. package/src/FilterLayout/FilterLayout.mdx +1 -0
  203. package/src/FilterLayout/FilterLayout.tsx +4 -1
  204. package/src/Form/Form.js +1 -1
  205. package/src/Form/Form.mdx +26 -24
  206. package/src/GridView/GridView.mdx +2 -1
  207. package/src/GridView/GridView.tsx +27 -8
  208. package/src/Group/Group.mdx +8 -7
  209. package/src/Group/Group.tsx +12 -1
  210. package/src/Heading/Heading.js +6 -2
  211. package/src/Heading/Heading.mdx +1 -0
  212. package/src/HeadingUppercase/HeadingUppercase.js +9 -5
  213. package/src/HeadingUppercase/HeadingUppercase.mdx +1 -0
  214. package/src/HelperDrawer/HelperDrawer.js +10 -2
  215. package/src/HelperDrawer/HelperDrawer.mdx +1 -0
  216. package/src/Highlight/Highlight.js +6 -2
  217. package/src/Highlight/Highlight.mdx +1 -0
  218. package/src/Icon/Icon.js +6 -0
  219. package/src/Icon/Icon.mdx +42 -37
  220. package/src/Icon/Status.js +4 -4
  221. package/src/Input/Inline.js +11 -1
  222. package/src/Input/Inline.mdx +2 -1
  223. package/src/Input/Input.js +119 -1
  224. package/src/Input/Input.mdx +1 -6
  225. package/src/Input/InputBox.js +41 -1
  226. package/src/Input/InputBox.mdx +1 -0
  227. package/src/Input/InputField.js +32 -0
  228. package/src/Input/InputField.mdx +1 -0
  229. package/src/Input/InputLabel.mdx +1 -0
  230. package/src/Link/Link.js +10 -0
  231. package/src/Link/Link.mdx +2 -1
  232. package/src/LinkList/LinkList.js +7 -1
  233. package/src/LinkList/LinkList.mdx +1 -0
  234. package/src/List/List.js +25 -1
  235. package/src/List/List.mdx +1 -0
  236. package/src/List/ListItem.js +1 -1
  237. package/src/Logo/Logo.js +10 -1
  238. package/src/Logo/Logo.mdx +1 -0
  239. package/src/Menu/Heading.js +1 -0
  240. package/src/Menu/Menu.js +7 -1
  241. package/src/Menu/Menu.mdx +2 -1
  242. package/src/Modal/Modal.js +1 -0
  243. package/src/Modal/Modal.mdx +1 -0
  244. package/src/Modal/Modal.test.tsx +113 -0
  245. package/src/NumberField/NumberField.js +19 -0
  246. package/src/Page/Page.mdx +1 -1
  247. package/src/PagerView/PagerView.js +1 -0
  248. package/src/PagerView/PagerView.mdx +9 -8
  249. package/src/Pagination/Pagination.js +2 -2
  250. package/src/Pagination/Pagination.mdx +1 -0
  251. package/src/Popover/Popover.test.tsx +62 -0
  252. package/src/Popover/Popover.tsx +3 -0
  253. package/src/Popover/rewireTabOrder.ts +24 -42
  254. package/src/Progress/Progress.js +8 -3
  255. package/src/Progress/Progress.mdx +1 -0
  256. package/src/Radio/Radio.js +4 -2
  257. package/src/Radio/Radio.mdx +1 -0
  258. package/src/RangeSlider/RangeSlider.js +11 -2
  259. package/src/RangeSlider/RangeSlider.mdx +13 -10
  260. package/src/ScreenReader/ScreenReader.js +6 -1
  261. package/src/ScreenReader/ScreenReader.mdx +1 -0
  262. package/src/Scrim/Scrim.mdx +1 -0
  263. package/src/Scrim/Scrim.tsx +8 -2
  264. package/src/Section/Section.js +15 -3
  265. package/src/Section/Section.mdx +1 -0
  266. package/src/SegmentedControl/SegmentedControl.mdx +3 -2
  267. package/src/SegmentedTabs/SegmentedTabs.js +2 -0
  268. package/src/SegmentedTabs/SegmentedTabs.mdx +1 -0
  269. package/src/Select/Option.js +1 -1
  270. package/src/Select/Select.js +69 -2
  271. package/src/Select/Select.mdx +1 -0
  272. package/src/Sidebar/Sidebar.js +14 -6
  273. package/src/Sidebar/Sidebar.mdx +1 -0
  274. package/src/Sortable/SortableItem.js +1 -1
  275. package/src/Spinner/Spinner.mdx +1 -0
  276. package/src/StackView/StackView.mdx +17 -1
  277. package/src/StackView/StackView.tsx +23 -8
  278. package/src/StepperField/StepperField.js +35 -6
  279. package/src/StepperField/StepperField.mdx +2 -2
  280. package/src/StepperProgress/StepperProgress.js +9 -10
  281. package/src/StepperProgress/StepperProgress.mdx +1 -0
  282. package/src/Summary/Summary.mdx +1 -0
  283. package/src/Tab/Tab.mdx +1 -0
  284. package/src/Table/ColumnPicker.js +1 -1
  285. package/src/Table/DragHandle.js +1 -1
  286. package/src/Table/NavigationArrow.js +1 -1
  287. package/src/Table/SubRowToggleCell.js +1 -1
  288. package/src/Table/Table.js +2 -3
  289. package/src/Table/Table.mdx +2 -2
  290. package/src/Tabs/Tab.js +1 -0
  291. package/src/Tabs/Tabs.js +5 -0
  292. package/src/Tabs/Tabs.mdx +1 -0
  293. package/src/Text/Text.mdx +1 -0
  294. package/src/Text/Text.tsx +12 -0
  295. package/src/TextArea/TextArea.js +7 -1
  296. package/src/TextArea/TextArea.mdx +1 -0
  297. package/src/ThemeProvider/ThemeProvider.tsx +1 -1
  298. package/src/TileView/TileView.mdx +1 -0
  299. package/src/TileView/TileView.tsx +17 -3
  300. package/src/TimeField/TimeField.mdx +1 -0
  301. package/src/TokenInput/DefaultToken.js +1 -1
  302. package/src/TokenInput/TokenInput.js +12 -6
  303. package/src/TokenInput/TokenInput.mdx +1 -0
  304. package/src/Toolbar/Toolbar.mdx +1 -0
  305. package/src/Tooltip/Tooltip.js +39 -0
  306. package/src/Tooltip/Tooltip.mdx +4 -3
  307. package/src/Wizard/Wizard.js +1 -1
  308. package/src/Wizard/Wizard.mdx +7 -2
  309. package/src/WrapView/WrapView.mdx +1 -0
  310. package/src/WrapView/WrapView.tsx +6 -28
  311. package/src/hooks/use-accessibility-violation.tsx +1 -1
  312. package/src/hooks/useConstant.ts +17 -0
  313. package/src/system/default-theme.ts +7 -2
  314. package/src/system/utils.js +1 -1
  315. package/src/utils.js +3 -3
  316. package/src/utils.test.js +29 -0
  317. package/dist/cjs/icons.js +0 -126
  318. package/dist/esm/icons.js +0 -121
  319. package/src/icons.js +0 -121
@@ -1,22 +1,133 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
  import { fireEvent, render, screen } from '@testing-library/react'
3
+ import userEvent from '@testing-library/user-event'
4
+ import '@testing-library/jest-dom/extend-expect'
5
+ import { noop } from 'lodash'
6
+ import { Box, Button, Text, ThemeProvider } from '..'
3
7
  import Dropdown from './Dropdown'
4
- import ThemeProvider from '../ThemeProvider'
5
8
 
6
- it(`should render title`, () => {
7
- render(<Dropdown title="A menu"></Dropdown>)
8
- screen.getByText('A menu')
9
- })
9
+ describe('Dropdown', () => {
10
+ describe('Text search', () => {
11
+ it(`should render title`, () => {
12
+ render(<Dropdown title="A menu"></Dropdown>)
13
+ screen.getByText('A menu')
14
+ })
15
+
16
+ it(`calls passed onSearch function when receiving keyboard input`, () => {
17
+ const customTextSearch = jest.fn()
18
+ render(
19
+ <ThemeProvider>
20
+ <Dropdown title="A menu" onSearch={customTextSearch}></Dropdown>
21
+ </ThemeProvider>
22
+ )
23
+ const dropdown = screen.getByText('A menu')
24
+
25
+ fireEvent.keyDown(dropdown, { key: 'A', code: 'KeyA' })
26
+ expect(customTextSearch).toHaveBeenCalled()
27
+ })
28
+ })
29
+
30
+ describe('Keyboard navigation', () => {
31
+ const StatefulDropdown = () => {
32
+ const [count, setCount] = useState(0)
33
+ return (
34
+ <ThemeProvider>
35
+ <Box>
36
+ <Dropdown>
37
+ <Dropdown.Item>
38
+ <Button title="One" onClick={() => noop()} />
39
+ </Dropdown.Item>
40
+ <Dropdown.Item>
41
+ <Button title="Two" onClick={() => setCount((c) => c + 1)} />
42
+ <Text data-testid="count-text">{count}</Text>
43
+ </Dropdown.Item>
44
+ <Dropdown.Item>
45
+ <Button title="Three" onClick={() => noop()} />
46
+ </Dropdown.Item>
47
+ </Dropdown>
48
+ </Box>
49
+ </ThemeProvider>
50
+ )
51
+ }
52
+
53
+ it('should trap focus, tab forward through all elements', () => {
54
+ render(<StatefulDropdown />)
55
+ userEvent.tab()
56
+ userEvent.keyboard('{enter}')
57
+ const [
58
+ openPopover,
59
+ buttonOne,
60
+ buttonTwo,
61
+ buttonThree,
62
+ ] = screen.getAllByRole('button')
63
+
64
+ expect(openPopover).toHaveFocus()
65
+ userEvent.tab()
66
+ expect(buttonOne).toHaveFocus()
67
+ userEvent.tab()
68
+ expect(buttonTwo).toHaveFocus()
69
+ userEvent.tab()
70
+ expect(buttonThree).toHaveFocus()
71
+ userEvent.tab()
72
+ expect(buttonOne).toHaveFocus()
73
+ })
74
+
75
+ it('should trap focus, tab backwards from first element to last', () => {
76
+ render(<StatefulDropdown />)
77
+ userEvent.tab()
78
+ userEvent.keyboard('{enter}')
79
+ const [
80
+ openPopover,
81
+ buttonOne,
82
+ _buttonTwo,
83
+ buttonThree,
84
+ ] = screen.getAllByRole('button')
85
+
86
+ expect(openPopover).toHaveFocus()
87
+ userEvent.tab()
88
+ expect(buttonOne).toHaveFocus()
89
+ userEvent.tab({ shift: true })
90
+ expect(buttonThree).toHaveFocus()
91
+ })
92
+
93
+ it('should retain tab order after rerender', () => {
94
+ render(<StatefulDropdown />)
95
+ userEvent.tab()
96
+ userEvent.keyboard('{enter}')
97
+ const [, buttonOne, buttonTwo, buttonThree] = screen.getAllByRole(
98
+ 'button'
99
+ )
100
+
101
+ userEvent.tab()
102
+ userEvent.tab()
103
+ expect(screen.getByTestId('count-text')).toHaveTextContent('0')
104
+ userEvent.keyboard('{enter}')
105
+ expect(screen.getByTestId('count-text')).toHaveTextContent('1')
106
+ expect(buttonTwo).toHaveFocus()
107
+ userEvent.tab()
108
+ expect(buttonThree).toHaveFocus()
109
+ userEvent.tab({ shift: true })
110
+ userEvent.tab({ shift: true })
111
+ expect(buttonOne).toHaveFocus()
112
+ userEvent.tab()
113
+ userEvent.tab()
114
+ userEvent.tab()
115
+ expect(buttonOne).toHaveFocus()
116
+ userEvent.tab({ shift: true })
117
+ userEvent.tab({ shift: true })
118
+ userEvent.tab({ shift: true })
119
+ expect(buttonOne).toHaveFocus()
120
+ })
10
121
 
11
- it(`calls passed onSearch function when receiving keyboard input`, () => {
12
- const customTextSearch = jest.fn()
13
- render(
14
- <ThemeProvider>
15
- <Dropdown title="A menu" onSearch={customTextSearch}></Dropdown>
16
- </ThemeProvider>
17
- )
18
- const dropdown = screen.getByText('A menu')
19
-
20
- fireEvent.keyDown(dropdown, { key: 'A', code: 'KeyA' })
21
- expect(customTextSearch).toHaveBeenCalled()
122
+ it('should focus dropdown toggle when a user presses escape key', () => {
123
+ render(<StatefulDropdown />)
124
+ userEvent.tab()
125
+ userEvent.keyboard('{enter}')
126
+ const [openPopover, buttonOne] = screen.getAllByRole('button')
127
+ userEvent.tab()
128
+ expect(buttonOne).toHaveFocus()
129
+ userEvent.keyboard(`{esc}`)
130
+ expect(openPopover).toHaveFocus()
131
+ })
132
+ })
22
133
  })
@@ -7,7 +7,9 @@ export const LINK_DISPLAY_NAME = 'Dropdown.Link'
7
7
  export const LINK_DATA = 'link'
8
8
 
9
9
  class Link extends Component {
10
- static displayName = LINK_DISPLAY_NAME
10
+ // Graphql wasn't picking up the correct displayName when this was
11
+ // assigned to LINK_DISPLAY_NAME, but using a string works
12
+ static displayName = 'Dropdown.Link'
11
13
 
12
14
  render() {
13
15
  const { disabled, external, index, text, to, ...restProps } = this.props
@@ -1,15 +1,29 @@
1
+ // @flow
1
2
  import React, { Children, useEffect, useState } from 'react'
2
3
 
3
4
  import Button from '../Button'
4
5
  import StackView from '../StackView'
5
6
  import { useDocumentEvent, useFocus, useHover } from '../hooks'
7
+ import { useThemeProps } from '../system'
6
8
 
7
- function EditActions({ display, edit, loading, ...restProps }) {
9
+ type Props = {
10
+ /** Renders any custom component or HTML element when not in the edit state. */
11
+ display?: React.ReactNode,
12
+
13
+ /** Renders any custom component or HTML element, usually form elments to capture user values. */
14
+ edit?: React.ReactNode,
15
+
16
+ /** Shows a spinner if true and then optimistically shows a checkmark when false again. */
17
+ loading?: boolean,
18
+ }
19
+
20
+ function EditActions({ display, edit, loading, ...restProps }: Props) {
8
21
  const { focus, focusProps } = useFocus()
9
22
  const { hover, hoverProps } = useHover()
10
23
  const [on, setOn] = useState(false)
11
24
  const [showCheck, setShowCheck] = useState(false)
12
25
  const toggle = () => setOn((bool) => !bool)
26
+ const { buttonProps, ...themeProps } = useThemeProps('editActions', restProps)
13
27
 
14
28
  useEffect(() => {
15
29
  if (loading === false) {
@@ -35,14 +49,14 @@ function EditActions({ display, edit, loading, ...restProps }) {
35
49
  onClick={on ? undefined : () => setOn(true)}
36
50
  {...focusProps}
37
51
  {...hoverProps}
38
- {...restProps}
52
+ {...themeProps}
39
53
  >
40
54
  {Children.toArray(on ? edit : display)}
41
55
  <Button
42
56
  grow={0}
43
57
  title={on ? 'Close' : 'Edit'}
44
58
  icon={{
45
- name: showCheck ? 'checkmark' : on ? 'close' : 'pencil',
59
+ name: showCheck ? 'general.check' : on ? 'general.x' : 'general.pencil',
46
60
  color: showCheck ? 'green' : undefined,
47
61
  }}
48
62
  tooltip={{
@@ -53,6 +67,7 @@ function EditActions({ display, edit, loading, ...restProps }) {
53
67
  onClick={focus || on ? toggle : () => setOn(true)}
54
68
  opacity={focus || hover || on ? 1 : 0}
55
69
  spinner={on && loading ? { color: 'primary' } : undefined}
70
+ {...buttonProps}
56
71
  />
57
72
  </StackView>
58
73
  )
@@ -2,6 +2,7 @@
2
2
  title: EditActions
3
3
  category: General
4
4
  summary: Helper component that manages switching between initial and editing states of inline forms. It uses an optimisitic save that will render a checkmark after the loading prop has been set to `false`.
5
+ propsSummary: Accepts [StackView](/stackview) props.
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -9,6 +9,12 @@ import StackView from '../StackView'
9
9
  import { cloneChildren, generateId } from '../utils'
10
10
 
11
11
  type Props = {
12
+ /** Usually accepts form fields, such as `input` or `select`. */
13
+ children?: any,
14
+
15
+ /** Gain access to the internal ref. */
16
+ innerRef?: any,
17
+
12
18
  /** Label that describes field[s]. */
13
19
  label?: string | React.ReactNode,
14
20
 
@@ -24,6 +30,9 @@ type Props = {
24
30
  /** Renders label and field[s] inline. */
25
31
  inline?: boolean,
26
32
 
33
+ /** Renders label and field[s] smaller. */
34
+ compact?: boolean,
35
+
27
36
  /** Renders content into a [HelperDrawer](/helperdrawer) next to label. */
28
37
  helpContent?: string | React.ReactNode,
29
38
 
@@ -33,8 +42,14 @@ type Props = {
33
42
  /** Controls spacing between fields. */
34
43
  spacing?: number,
35
44
 
45
+ /** Controls distribution between fields, by [passing this prop to StackView](/stackview#distribution). (Defaults to "fill".) */
46
+ distribution?: number,
47
+
36
48
  /** State of field[s]. */
37
49
  state?: 'success' | 'error',
50
+
51
+ /** Places an icon to the left of the label. */
52
+ icon?: any,
38
53
  }
39
54
 
40
55
  class Field extends Component<Props> {
@@ -2,6 +2,7 @@
2
2
  title: Field
3
3
  category: Forms
4
4
  summary: Composes [InputLabel](/inputlabel) and passes an `id` to the first child to pair labels and controls automatically.
5
+ propsSummary: Accepts [Box](/box) props.
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -5,8 +5,16 @@ import Heading from '../Heading'
5
5
  import StackView from '../StackView'
6
6
  import TileView from '../TileView'
7
7
  import Toolbar from '../Toolbar'
8
+ import { useThemeProps } from '../system'
8
9
 
9
10
  type Props = {
11
+ children?: any,
12
+
13
+ /**
14
+ * Accepts any valid [Heading](/heading) props.
15
+ */
16
+ headingProps?: object,
17
+
10
18
  /**
11
19
  * Maps to internal `Toolbar` prop.
12
20
  */
@@ -26,28 +34,44 @@ type Props = {
26
34
  * Maps to internal `TileView` prop.
27
35
  */
28
36
  spacing: number,
37
+
38
+ /**
39
+ * Accepts any valid [TileView](/tileview) props.
40
+ */
41
+ tileViewProps?: object,
29
42
  }
30
43
 
31
- function FieldSet({
32
- children,
33
- minCellWidth = 16,
34
- spacing = 1,
35
- helpContent,
36
- legend,
37
- ...restProps
38
- }: Props) {
44
+ function FieldSet({ children, helpContent, legend, ...restProps }: Props) {
45
+ const {
46
+ headingProps,
47
+ tileViewProps,
48
+ spacing = 1,
49
+ minCellWidth = 16,
50
+ ...themeProps
51
+ } = useThemeProps('fieldset', { ...restProps })
52
+
39
53
  return (
40
- <StackView as="fieldset" padding={0} margin={2} {...restProps}>
54
+ <StackView
55
+ as="fieldset"
56
+ padding={0}
57
+ margin={2}
58
+ {...themeProps}
59
+ {...restProps}
60
+ >
41
61
  <Toolbar
42
62
  title={
43
- <Heading as="legend" level={4}>
63
+ <Heading as="legend" level={4} {...headingProps}>
44
64
  {legend}
45
65
  </Heading>
46
66
  }
47
67
  helpContent={helpContent}
48
68
  marginBottom={1}
49
69
  />
50
- <TileView minCellWidth={minCellWidth} spacing={spacing}>
70
+ <TileView
71
+ minCellWidth={minCellWidth}
72
+ spacing={spacing}
73
+ {...tileViewProps}
74
+ >
51
75
  {children}
52
76
  </TileView>
53
77
  </StackView>
@@ -2,6 +2,7 @@
2
2
  title: FieldSet
3
3
  category: Forms
4
4
  summary: Used to group several controls as well as labels within a web form.
5
+ propsSummary: Accepts [StackView](/stackview) props.
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -2,6 +2,7 @@
2
2
  title: FilterLayout
3
3
  category: General
4
4
  summary: Used to display a filterable content area. Use with [DataTable](/datatable).
5
+ propsSummary: Accepts [Card](/card) props.
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -59,7 +59,10 @@ export function FilterLayout(props: Props) {
59
59
  radius={0}
60
60
  title="Filter"
61
61
  aria-label={sidebarOpen ? 'close filter' : 'open filter'}
62
- iconRight={{ name: sidebarOpen ? 'caret-left' : 'filter' }}
62
+ iconRight={{
63
+ name: sidebarOpen ? 'general.leftChevron' : 'general.threeReducingHorizontalBars',
64
+ size: sidebarOpen ? 'xs' : 'md'
65
+ }}
63
66
  onClick={toggleSidebar}
64
67
  />
65
68
  <Box visible={!(sidebarOpen && fill)} grow={1} shrink={1}>
package/src/Form/Form.js CHANGED
@@ -130,7 +130,7 @@ class Form extends React.Component<Props> {
130
130
  ...this.state,
131
131
  editButtonProps: {
132
132
  disabled: isSubmitting,
133
- icon: isEditing ? undefined : { name: 'pencil' },
133
+ icon: isEditing ? undefined : { name: 'general.pencil' },
134
134
  onClick: () => {
135
135
  // bail out if we've already triggered a submit in onBlur
136
136
  if (this.submitTimeoutId === null) {
package/src/Form/Form.mdx CHANGED
@@ -7,31 +7,33 @@ category: Forms
7
7
  render(() => {
8
8
  const [value, setValue] = React.useState({ name: "Dave's Band Tag Team" })
9
9
  return (
10
- <Form
11
- initialPayload={value}
12
- onSubmit={(payload, complete) => {
13
- setTimeout(() => {
14
- setValue(payload)
15
- complete()
16
- }, 1600)
17
- }}
18
- >
19
- {({ editButtonProps, getFieldProps }) => (
20
- <StackView
21
- minWidth={64}
22
- padding={2}
23
- spacing={1}
24
- backgroundColor="primary-light"
25
- >
26
- <StackView axis="horizontal" alignment="center" spacing={1}>
27
- <Input.Inline fontSize={0} light {...getFieldProps('name')} />
28
- <Button size="xs" theme="light" {...editButtonProps} />
29
- <Icon name="split" size="md" color="light-6" />
30
- <Icon name="tag" size="md" color="light-6" />
10
+ <ThemeProvider theme={{ icons }}>
11
+ <Form
12
+ initialPayload={value}
13
+ onSubmit={(payload, complete) => {
14
+ setTimeout(() => {
15
+ setValue(payload)
16
+ complete()
17
+ }, 1600)
18
+ }}
19
+ >
20
+ {({ editButtonProps, getFieldProps }) => (
21
+ <StackView
22
+ minWidth={64}
23
+ padding={2}
24
+ spacing={1}
25
+ backgroundColor="primary-light"
26
+ >
27
+ <StackView axis="horizontal" alignment="center" spacing={1}>
28
+ <Input.Inline fontSize={0} light {...getFieldProps('name')} />
29
+ <Button size="xs" theme="light" {...editButtonProps} />
30
+ <Icon name="services.split" size="md" color="light-6" />
31
+ <Icon name="services.tag" size="md" color="light-6" />
32
+ </StackView>
31
33
  </StackView>
32
- </StackView>
33
- )}
34
- </Form>
34
+ )}
35
+ </Form>
36
+ </ThemeProvider>
35
37
  )
36
38
  })
37
39
  ```
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  title: GridView
3
3
  category: Layout
4
- summary: Lay out children in columns and rows. Wraps CSS grid styles in a simple API. Any direct children can use the `column|Start|End` or `row|Start|End` [shorthand properties](/system-props#css-grid) to place themselves on the grid. To learn more about how you can use CSS grid visit [learncssgrid.com](https://learncssgrid.com/).
4
+ summary: Lay out children in columns and rows. Wraps CSS grid styles in a simple API. To learn more about how you can use CSS grid visit [learncssgrid.com](https://learncssgrid.com/).
5
+ propsSummary: Accepts all valid HTML attributes.
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -5,6 +5,7 @@ import * as React from 'react'
5
5
 
6
6
  import { BoxProps } from '../Box'
7
7
  import splitStyles from '../system/split-styles'
8
+ import { spacingValue } from '../system'
8
9
  import { MediaQueries, Variants } from '../index'
9
10
  import { useVariant } from '../VariantProvider'
10
11
 
@@ -64,19 +65,25 @@ const gridViewPlugin = {
64
65
  styles.justifyItems = distribution
65
66
  }
66
67
  if (columnSpacing !== undefined && styles.gridColumnGap === undefined) {
67
- styles.gridColumnGap = columnSpacing * 8
68
+ styles.gridColumnGap = spacingValue(columnSpacing)
68
69
  }
69
70
  if (rowSpacing !== undefined && styles.gridRowGap === undefined) {
70
- styles.gridRowGap = rowSpacing * 8
71
+ styles.gridRowGap = spacingValue(rowSpacing)
71
72
  }
72
- if (spacing !== undefined && styles.gridGap === undefined) {
73
- styles.gridGap = spacing * 8
73
+ if (spacing !== undefined && styles.gap === undefined) {
74
+ styles.gap = spacingValue(spacing)
74
75
  }
75
76
  return styles
76
77
  },
77
78
  }
78
79
 
79
80
  export type GridViewProps = {
81
+ /** Any direct children can use the `column|Start|End` or `row|Start|End` [shorthand properties](/style-props#grid) to place themselves on the grid. */
82
+ children?: any
83
+
84
+ /** Render custom component or HTML element tag. (Defaults to a `<div>` element). */
85
+ as?: any
86
+
80
87
  /** The algorithm used to implicitly place grid items. Maps to CSS [gridAutoFlow](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow) property. */
81
88
  autoFlow?: 'column' | 'row' | 'dense'
82
89
 
@@ -89,20 +96,32 @@ export type GridViewProps = {
89
96
  /** The columns of the grid. Maps to CSS [gridTemplateColumns](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns) property. */
90
97
  columns?: Array<any> | string
91
98
 
99
+ /** If true, sets `display: inline-grid`, otherwise it defaults to `display: grid` */
100
+ inline?: boolean
101
+
102
+ /** Gain access to the internal ref */
103
+ innerRef?: any
104
+
92
105
  /** The rows of the grid. Maps to CSS [gridTemplateRows](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows) property. */
93
106
  rows?: Array<any> | string
94
107
 
95
108
  /** Aligns content in a grid item along the column axis. Maps to CSS [alignItems](https://developer.mozilla.org/en-US/docs/Web/CSS/align-items) property. */
96
109
  alignment?: 'start' | 'end' | 'center' | 'stretch'
97
110
 
98
- /** The amount of space between children. Maps to CSS [gridGap](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-gap) property. */
99
- spacing?: number
111
+ /** The amount of space between children. Maps to CSS [gap](https://developer.mozilla.org/en-US/docs/Web/CSS/gap) property. */
112
+ spacing?: number | string
100
113
 
101
114
  /** The amount of space between columns. Maps to CSS [gridColumnGap](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column-gap) property. */
102
- columnSpacing?: number
115
+ columnSpacing?: number | string
103
116
 
104
117
  /** The amount of space between rows. Maps to CSS [gridRowGap](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row-gap) property. */
105
- rowSpacing?: number
118
+ rowSpacing?: number | string
119
+
120
+ /** Describes styles at various points in time. [Read about variants](/variants).*/
121
+ variants?: object
122
+
123
+ /** Describes props at different breakpoints. [Read about mediaQueries](/responsive). */
124
+ mediaQueries?: object
106
125
  } & BoxProps
107
126
 
108
127
  type Props = React.RefAttributes<any> &
@@ -2,24 +2,25 @@
2
2
  title: Group
3
3
  category: General
4
4
  summary: Used to lay out groups of elements like cards, buttons, and/or inputs.
5
+ propsSummary: Accepts [StackView](/stackview) props.
5
6
  ---
6
7
 
7
8
  ```jsx live
8
9
  render(
9
10
  <Group>
10
11
  <Button
11
- icon={{ name: 'email' }}
12
+ icon={{ name: 'general.envelope' }}
12
13
  tooltip={{ title: 'Email' }}
13
14
  variant="outline"
14
15
  />
15
16
  <Button
16
- icon={{ name: 'print' }}
17
+ icon={{ name: 'general.printer' }}
17
18
  tooltip={{ title: 'Print' }}
18
19
  variant="outline"
19
20
  />
20
21
  <Button
21
- icon={{ name: 'csv-export' }}
22
- tooltip={{ title: 'CSV Export' }}
22
+ icon={{ name: 'general.thickToBottomArrow' }}
23
+ tooltip={{ title: 'Download' }}
23
24
  variant="outline"
24
25
  />
25
26
  </Group>
@@ -40,7 +41,7 @@ render(
40
41
  color="grey-8"
41
42
  subdued
42
43
  >
43
- <Icon name="info" size="sm" color="grey-6" marginRight={2} />
44
+ <Icon name="general.outlinedInfoCircle" size="sm" color="grey-6" marginRight={2} />
44
45
  <Text>
45
46
  David is an <Link to="#">Organization Administrator</Link> with full
46
47
  Administrator permission everywhere.
@@ -60,7 +61,7 @@ render(
60
61
  <Group size="md">
61
62
  <Button title="Email" variant="outline" />
62
63
  <Button
63
- icon={{ name: 'print', color: 'foregroundSecondary' }}
64
+ icon={{ name: 'general.printer', color: 'foregroundSecondary' }}
64
65
  tooltip={{ title: 'Print' }}
65
66
  />
66
67
  </Group>
@@ -72,7 +73,7 @@ render(
72
73
  render(
73
74
  <Group radius={0} size="lg">
74
75
  <Input placeholder="Search things..." />
75
- <Button icon={{ name: 'search' }} tooltip={{ title: 'Search' }} />
76
+ <Button icon={{ name: 'general.search' }} tooltip={{ title: 'Search' }} />
76
77
  </Group>
77
78
  )
78
79
  ```
@@ -24,6 +24,11 @@ export type GroupProps = {
24
24
  * The size of the radius.
25
25
  */
26
26
  radius?: number | string
27
+
28
+ /**
29
+ * The amount of space or element that is inserted between each child.
30
+ */
31
+ spacing?: number | string | React.ReactNode
27
32
  }
28
33
 
29
34
  export function Group({
@@ -31,6 +36,7 @@ export function Group({
31
36
  childProps,
32
37
  children,
33
38
  radius,
39
+ spacing,
34
40
  ...restProps
35
41
  }: GroupProps) {
36
42
  const themeRadius = useThemeValue('group.radius')
@@ -40,12 +46,17 @@ export function Group({
40
46
  const startRadius = isHorizontalLayout ? 'radiusLeft' : 'radiusTop'
41
47
  const endRadius = isHorizontalLayout ? 'radiusRight' : 'radiusBottom'
42
48
 
49
+ const marginBottom = isHorizontalLayout ? 0 : '-1px'
50
+ const marginRight = isHorizontalLayout ? '-1px' : 0
51
+
43
52
  return (
44
- <StackView axis={axis} spacing={-0.125} {...restProps}>
53
+ <StackView {...{ axis, spacing }} {...restProps}>
45
54
  {cloneChildren(children, (child, { firstChild, lastChild }) => ({
46
55
  ...childProps,
47
56
  [startRadius]: firstChild ? radiusValue : 0,
48
57
  [endRadius]: lastChild ? radiusValue : 0,
58
+ ...(!spacing && !lastChild && { marginBottom }),
59
+ ...(!spacing && !lastChild && { marginRight }),
49
60
  }))}
50
61
  </StackView>
51
62
  )
@@ -5,8 +5,12 @@ import Text from '../Text'
5
5
  import { useThemeValue } from '../system'
6
6
 
7
7
  type Props = {
8
- /** Sets the heading tag (1-6) and the respective font size corresponding to the index position (level - 1) in theme `fontSizes` */
9
- level?: 1 | 2 | 3 | 4 | 5 | 6,
8
+ children?: any,
9
+
10
+ /** Sets the heading tag (1-6) and the respective font size corresponding to the index position (level - 1) in theme `fontSizes`
11
+ * `1 | 2 | 3 | 4 | 5 | 6`
12
+ */
13
+ level?: number,
10
14
  }
11
15
 
12
16
  function Heading({ level = 1, ...restProps }: Props) {
@@ -2,6 +2,7 @@
2
2
  title: Heading
3
3
  category: General
4
4
  summary: Headings communicate the hierarchy of content to users and assistive technologies.
5
+ propsSummary: Accepts [Text](/text) props.
5
6
  ---
6
7
 
7
8
  ```jsx live