@wordpress/components 19.8.3 → 19.10.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 (256) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/CONTRIBUTING.md +80 -7
  3. package/build/alignment-matrix-control/styles/alignment-matrix-control-styles.js +11 -11
  4. package/build/alignment-matrix-control/styles/alignment-matrix-control-styles.js.map +1 -1
  5. package/build/angle-picker-control/angle-circle.js +5 -7
  6. package/build/angle-picker-control/angle-circle.js.map +1 -1
  7. package/build/box-control/index.js +0 -21
  8. package/build/box-control/index.js.map +1 -1
  9. package/build/box-control/utils.js +1 -8
  10. package/build/box-control/utils.js.map +1 -1
  11. package/build/button/index.js +3 -5
  12. package/build/button/index.js.map +1 -1
  13. package/build/circular-option-picker/index.js +1 -2
  14. package/build/circular-option-picker/index.js.map +1 -1
  15. package/build/disabled/index.js +4 -76
  16. package/build/disabled/index.js.map +1 -1
  17. package/build/heading/hook.js +1 -1
  18. package/build/heading/hook.js.map +1 -1
  19. package/build/input-control/index.js +27 -4
  20. package/build/input-control/index.js.map +1 -1
  21. package/build/input-control/styles/input-control-styles.js +42 -30
  22. package/build/input-control/styles/input-control-styles.js.map +1 -1
  23. package/build/mobile/bottom-sheet-select-control/index.native.js +1 -0
  24. package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  25. package/build/navigation/styles/navigation-styles.js +12 -12
  26. package/build/navigation/styles/navigation-styles.js.map +1 -1
  27. package/build/notice/index.native.js +44 -40
  28. package/build/notice/index.native.js.map +1 -1
  29. package/build/notice/list.native.js +27 -45
  30. package/build/notice/list.native.js.map +1 -1
  31. package/build/popover/index.js +6 -52
  32. package/build/popover/index.js.map +1 -1
  33. package/build/sandbox/index.js +2 -2
  34. package/build/sandbox/index.js.map +1 -1
  35. package/build/select-control/index.js +31 -4
  36. package/build/select-control/index.js.map +1 -1
  37. package/build/select-control/styles/select-control-styles.js +8 -8
  38. package/build/select-control/styles/select-control-styles.js.map +1 -1
  39. package/build/surface/styles.js +8 -8
  40. package/build/surface/styles.js.map +1 -1
  41. package/build/text/hook.js +5 -5
  42. package/build/text/hook.js.map +1 -1
  43. package/build/text/styles/text-mixins.native.js +1 -1
  44. package/build/text/styles/text-mixins.native.js.map +1 -1
  45. package/build/text/styles.js +7 -7
  46. package/build/text/styles.js.map +1 -1
  47. package/build/text-control/index.js +35 -28
  48. package/build/text-control/index.js.map +1 -1
  49. package/build/text-control/types.js +6 -0
  50. package/build/text-control/types.js.map +1 -0
  51. package/build/toggle-group-control/toggle-group-control-option-icon/component.js +6 -4
  52. package/build/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
  53. package/build/tools-panel/tools-panel-header/component.js +52 -36
  54. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  55. package/build/ui/spinner/component.js +1 -1
  56. package/build/ui/spinner/component.js.map +1 -1
  57. package/build/unit-control/index.js +3 -3
  58. package/build/unit-control/index.js.map +1 -1
  59. package/build/unit-control/styles/unit-control-styles.js +11 -20
  60. package/build/unit-control/styles/unit-control-styles.js.map +1 -1
  61. package/build/unit-control/utils.js.map +1 -1
  62. package/build/utils/colors-values.js +9 -24
  63. package/build/utils/colors-values.js.map +1 -1
  64. package/build-module/alignment-matrix-control/styles/alignment-matrix-control-styles.js +11 -11
  65. package/build-module/alignment-matrix-control/styles/alignment-matrix-control-styles.js.map +1 -1
  66. package/build-module/angle-picker-control/angle-circle.js +5 -7
  67. package/build-module/angle-picker-control/angle-circle.js.map +1 -1
  68. package/build-module/box-control/index.js +1 -20
  69. package/build-module/box-control/index.js.map +1 -1
  70. package/build-module/box-control/utils.js +0 -6
  71. package/build-module/box-control/utils.js.map +1 -1
  72. package/build-module/button/index.js +3 -4
  73. package/build-module/button/index.js.map +1 -1
  74. package/build-module/circular-option-picker/index.js +1 -2
  75. package/build-module/circular-option-picker/index.js.map +1 -1
  76. package/build-module/disabled/index.js +5 -76
  77. package/build-module/disabled/index.js.map +1 -1
  78. package/build-module/heading/hook.js +1 -1
  79. package/build-module/heading/hook.js.map +1 -1
  80. package/build-module/input-control/index.js +24 -3
  81. package/build-module/input-control/index.js.map +1 -1
  82. package/build-module/input-control/styles/input-control-styles.js +42 -30
  83. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  84. package/build-module/mobile/bottom-sheet-select-control/index.native.js +1 -0
  85. package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  86. package/build-module/navigation/styles/navigation-styles.js +13 -13
  87. package/build-module/navigation/styles/navigation-styles.js.map +1 -1
  88. package/build-module/notice/index.native.js +45 -41
  89. package/build-module/notice/index.native.js.map +1 -1
  90. package/build-module/notice/list.native.js +28 -46
  91. package/build-module/notice/list.native.js.map +1 -1
  92. package/build-module/popover/index.js +6 -52
  93. package/build-module/popover/index.js.map +1 -1
  94. package/build-module/sandbox/index.js +2 -2
  95. package/build-module/sandbox/index.js.map +1 -1
  96. package/build-module/select-control/index.js +29 -3
  97. package/build-module/select-control/index.js.map +1 -1
  98. package/build-module/select-control/styles/select-control-styles.js +8 -8
  99. package/build-module/select-control/styles/select-control-styles.js.map +1 -1
  100. package/build-module/surface/styles.js +8 -8
  101. package/build-module/surface/styles.js.map +1 -1
  102. package/build-module/text/hook.js +5 -5
  103. package/build-module/text/hook.js.map +1 -1
  104. package/build-module/text/styles/text-mixins.native.js +2 -2
  105. package/build-module/text/styles/text-mixins.native.js.map +1 -1
  106. package/build-module/text/styles.js +7 -7
  107. package/build-module/text/styles.js.map +1 -1
  108. package/build-module/text-control/index.js +35 -27
  109. package/build-module/text-control/index.js.map +1 -1
  110. package/build-module/text-control/types.js +2 -0
  111. package/build-module/text-control/types.js.map +1 -0
  112. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js +1 -5
  113. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
  114. package/build-module/tools-panel/tools-panel-header/component.js +51 -36
  115. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  116. package/build-module/ui/spinner/component.js +1 -1
  117. package/build-module/ui/spinner/component.js.map +1 -1
  118. package/build-module/unit-control/index.js +3 -3
  119. package/build-module/unit-control/index.js.map +1 -1
  120. package/build-module/unit-control/styles/unit-control-styles.js +11 -20
  121. package/build-module/unit-control/styles/unit-control-styles.js.map +1 -1
  122. package/build-module/unit-control/utils.js.map +1 -1
  123. package/build-module/utils/colors-values.js +19 -23
  124. package/build-module/utils/colors-values.js.map +1 -1
  125. package/build-style/style-rtl.css +24 -0
  126. package/build-style/style.css +24 -0
  127. package/build-types/button/index.d.ts.map +1 -1
  128. package/build-types/circular-option-picker/index.d.ts.map +1 -1
  129. package/build-types/color-picker/styles.d.ts +3 -3
  130. package/build-types/disabled/index.d.ts.map +1 -1
  131. package/build-types/input-control/index.d.ts +23 -3
  132. package/build-types/input-control/index.d.ts.map +1 -1
  133. package/build-types/input-control/input-field.d.ts +1 -1
  134. package/build-types/input-control/input-field.d.ts.map +1 -1
  135. package/build-types/input-control/stories/index.d.ts +5 -5
  136. package/build-types/input-control/styles/input-control-styles.d.ts +1 -0
  137. package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
  138. package/build-types/input-control/types.d.ts +79 -3
  139. package/build-types/input-control/types.d.ts.map +1 -1
  140. package/build-types/number-control/styles/number-control-styles.d.ts +1 -1
  141. package/build-types/popover/index.d.ts +0 -1
  142. package/build-types/popover/index.d.ts.map +1 -1
  143. package/build-types/select-control/index.d.ts +30 -26
  144. package/build-types/select-control/index.d.ts.map +1 -1
  145. package/build-types/select-control/stories/index.d.ts +23 -0
  146. package/build-types/select-control/stories/index.d.ts.map +1 -0
  147. package/build-types/select-control/styles/select-control-styles.d.ts +3 -4
  148. package/build-types/select-control/styles/select-control-styles.d.ts.map +1 -1
  149. package/build-types/select-control/test/select-control.d.ts +2 -0
  150. package/build-types/select-control/test/select-control.d.ts.map +1 -0
  151. package/build-types/select-control/types.d.ts +52 -1
  152. package/build-types/select-control/types.d.ts.map +1 -1
  153. package/build-types/text-control/index.d.ts +32 -0
  154. package/build-types/text-control/index.d.ts.map +1 -0
  155. package/build-types/text-control/stories/index.d.ts +13 -0
  156. package/build-types/text-control/stories/index.d.ts.map +1 -0
  157. package/build-types/text-control/types.d.ts +25 -0
  158. package/build-types/text-control/types.d.ts.map +1 -0
  159. package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts.map +1 -1
  160. package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
  161. package/build-types/tools-panel/types.d.ts +0 -1
  162. package/build-types/tools-panel/types.d.ts.map +1 -1
  163. package/build-types/unit-control/index.d.ts +2 -2
  164. package/build-types/unit-control/index.d.ts.map +1 -1
  165. package/build-types/unit-control/styles/unit-control-styles.d.ts.map +1 -1
  166. package/build-types/unit-control/test/index.d.ts +2 -0
  167. package/build-types/unit-control/test/index.d.ts.map +1 -0
  168. package/build-types/unit-control/test/utils.d.ts +2 -0
  169. package/build-types/unit-control/test/utils.d.ts.map +1 -0
  170. package/build-types/unit-control/types.d.ts +1 -1
  171. package/build-types/unit-control/types.d.ts.map +1 -1
  172. package/build-types/unit-control/utils.d.ts +3 -3
  173. package/build-types/unit-control/utils.d.ts.map +1 -1
  174. package/build-types/utils/colors-values.d.ts +6 -146
  175. package/build-types/utils/colors-values.d.ts.map +1 -1
  176. package/package.json +17 -17
  177. package/src/alignment-matrix-control/styles/alignment-matrix-control-styles.js +5 -3
  178. package/src/angle-picker-control/angle-circle.js +3 -3
  179. package/src/box-control/README.md +0 -74
  180. package/src/box-control/index.js +0 -15
  181. package/src/box-control/stories/index.js +0 -29
  182. package/src/box-control/utils.js +0 -7
  183. package/src/button/index.js +2 -4
  184. package/src/button/test/index.js +16 -1
  185. package/src/circular-option-picker/index.js +1 -2
  186. package/src/color-palette/README.md +0 -1
  187. package/src/color-palette/test/__snapshots__/index.js.snap +2 -3
  188. package/src/confirm-dialog/stories/index.js +87 -99
  189. package/src/date-time/stories/index.js +19 -0
  190. package/src/date-time/test/date.js +107 -78
  191. package/src/dimension-control/test/__snapshots__/index.test.js.snap +4 -4
  192. package/src/disabled/index.js +5 -90
  193. package/src/form-file-upload/test/index.js +15 -12
  194. package/src/heading/hook.ts +1 -1
  195. package/src/heading/test/__snapshots__/index.js.snap +3 -3
  196. package/src/input-control/README.md +3 -3
  197. package/src/input-control/index.tsx +23 -3
  198. package/src/input-control/stories/index.tsx +63 -0
  199. package/src/input-control/styles/input-control-styles.tsx +20 -7
  200. package/src/input-control/types.ts +79 -2
  201. package/src/menu-item/style.scss +10 -0
  202. package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +8 -1
  203. package/src/mobile/bottom-sheet-select-control/index.native.js +1 -0
  204. package/src/mobile/html-text-input/style.android.scss +1 -0
  205. package/src/mobile/html-text-input/style.ios.scss +1 -0
  206. package/src/mobile/link-settings/test/link-settings-navigation.native.js +9 -1
  207. package/src/navigation/styles/navigation-styles.js +5 -5
  208. package/src/notice/index.native.js +44 -54
  209. package/src/notice/list.native.js +27 -51
  210. package/src/notice/style.native.scss +1 -0
  211. package/src/popover/index.js +5 -51
  212. package/src/query-controls/README.md +2 -2
  213. package/src/sandbox/index.js +2 -2
  214. package/src/select-control/README.md +2 -2
  215. package/src/select-control/index.tsx +30 -29
  216. package/src/select-control/stories/index.tsx +90 -0
  217. package/src/select-control/styles/select-control-styles.ts +10 -9
  218. package/src/select-control/test/{select-control.js → select-control.tsx} +2 -2
  219. package/src/select-control/types.ts +66 -1
  220. package/src/surface/styles.js +1 -1
  221. package/src/text/hook.js +1 -1
  222. package/src/text/styles/text-mixins.native.js +2 -2
  223. package/src/text/styles.js +1 -1
  224. package/src/text/test/__snapshots__/{index.js.snap → index.tsx.snap} +16 -0
  225. package/src/text/test/{index.js → index.tsx} +12 -6
  226. package/src/text-control/index.tsx +84 -0
  227. package/src/text-control/stories/index.tsx +66 -0
  228. package/src/text-control/types.ts +29 -0
  229. package/src/toggle-group-control/toggle-group-control-option-icon/component.tsx +1 -5
  230. package/src/toolbar-group/style.scss +20 -0
  231. package/src/tools-panel/test/__snapshots__/index.js.snap +2 -2
  232. package/src/tools-panel/test/index.js +71 -18
  233. package/src/tools-panel/tools-panel-header/component.tsx +75 -33
  234. package/src/tools-panel/types.ts +0 -1
  235. package/src/tooltip/test/index.js +6 -0
  236. package/src/ui/spinner/component.js +1 -1
  237. package/src/ui/spinner/test/__snapshots__/index.js.snap +3 -3
  238. package/src/unit-control/index.tsx +2 -5
  239. package/src/unit-control/styles/unit-control-styles.ts +3 -13
  240. package/src/unit-control/test/__snapshots__/index.tsx.snap +33 -0
  241. package/src/unit-control/test/{index.js → index.tsx} +214 -165
  242. package/src/unit-control/test/{utils.js → utils.ts} +38 -19
  243. package/src/unit-control/types.ts +4 -1
  244. package/src/unit-control/utils.ts +5 -3
  245. package/src/utils/colors-values.js +18 -22
  246. package/tsconfig.json +9 -2
  247. package/tsconfig.tsbuildinfo +1 -1
  248. package/build/box-control/visualizer.js +0 -165
  249. package/build/box-control/visualizer.js.map +0 -1
  250. package/build-module/box-control/visualizer.js +0 -154
  251. package/build-module/box-control/visualizer.js.map +0 -1
  252. package/src/box-control/visualizer.js +0 -116
  253. package/src/input-control/stories/index.js +0 -71
  254. package/src/select-control/stories/index.js +0 -104
  255. package/src/text-control/index.js +0 -72
  256. package/src/text-control/stories/index.js +0 -46
@@ -164,7 +164,7 @@ describe( 'Button', () => {
164
164
  expect( buttonDescription ).toBe( 'Description text' );
165
165
  } );
166
166
 
167
- it( 'should populate tooltip with describedBy content', () => {
167
+ it( 'should populate tooltip with label content for buttons without visible labels (no children)', () => {
168
168
  const buttonTooltip = shallow(
169
169
  <Button
170
170
  describedBy="Description text"
@@ -173,6 +173,21 @@ describe( 'Button', () => {
173
173
  />
174
174
  ).find( 'Tooltip' );
175
175
 
176
+ expect( buttonTooltip.prop( 'text' ) ).toBe( 'Label' );
177
+ } );
178
+
179
+ it( 'should populate tooltip with description content for buttons with visible labels (buttons with children)', () => {
180
+ const buttonTooltip = shallow(
181
+ <Button
182
+ label="Label"
183
+ describedBy="Description text"
184
+ icon={ plusCircle }
185
+ showTooltip
186
+ >
187
+ Children
188
+ </Button>
189
+ ).find( 'Tooltip' );
190
+
176
191
  expect( buttonTooltip.prop( 'text' ) ).toBe( 'Description text' );
177
192
  } );
178
193
 
@@ -87,8 +87,7 @@ function ButtonAction( { className, children, ...additionalProps } ) {
87
87
  'components-circular-option-picker__clear',
88
88
  className
89
89
  ) }
90
- isSmall
91
- variant="secondary"
90
+ variant="tertiary"
92
91
  { ...additionalProps }
93
92
  >
94
93
  { children }
@@ -41,7 +41,6 @@ classes to be applied to the container.
41
41
 
42
42
  - Type: `String`
43
43
  - Required: No
44
- - Default: `Select or Upload Media`
45
44
 
46
45
  ### clearable
47
46
 
@@ -1186,13 +1186,12 @@ exports[`ColorPalette should render a dynamic toolbar of colors 1`] = `
1186
1186
  >
1187
1187
  <ForwardRef(Button)
1188
1188
  className="components-circular-option-picker__clear"
1189
- isSmall={true}
1190
1189
  onClick={[Function]}
1191
- variant="secondary"
1190
+ variant="tertiary"
1192
1191
  >
1193
1192
  <button
1194
1193
  aria-describedby={null}
1195
- className="components-button components-circular-option-picker__clear is-secondary is-small"
1194
+ className="components-button components-circular-option-picker__clear is-tertiary"
1196
1195
  onClick={[Function]}
1197
1196
  type="button"
1198
1197
  >
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { text } from '@storybook/addon-knobs';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -15,102 +10,42 @@ import Button from '../../button';
15
10
  import { Heading } from '../../heading';
16
11
  import { ConfirmDialog } from '..';
17
12
 
18
- export default {
13
+ const meta = {
19
14
  component: ConfirmDialog,
20
15
  title: 'Components (Experimental)/ConfirmDialog',
16
+ argTypes: {
17
+ children: {
18
+ control: { type: 'text' },
19
+ },
20
+ confirmButtonText: {
21
+ control: { type: 'text' },
22
+ },
23
+ cancelButtonText: {
24
+ control: { type: 'text' },
25
+ },
26
+ isOpen: {
27
+ control: { type: null },
28
+ },
29
+ onConfirm: {
30
+ control: { type: null },
31
+ },
32
+ onCancel: {
33
+ control: { type: null },
34
+ },
35
+ },
36
+ args: {
37
+ children: 'Would you like to privately publish the post now?',
38
+ },
21
39
  parameters: {
22
- knobs: { disable: false },
40
+ docs: { source: { state: 'open' } },
23
41
  },
24
42
  };
25
43
 
26
- const daText = () =>
27
- text( 'message', 'Would you like to privately publish the post now?' );
28
- const daCancelText = () => text( 'cancel button', 'No thanks' );
29
- const daConfirmText = () => text( 'confirm button', 'Yes please!' );
30
-
31
- // Simplest usage: just declare the component with the required `onConfirm` prop.
32
- export const _default = () => {
33
- const [ confirmVal, setConfirmVal ] = useState( "Hasn't confirmed yet" );
34
-
35
- return (
36
- <>
37
- <ConfirmDialog onConfirm={ () => setConfirmVal( 'Confirmed!' ) }>
38
- { daText() }
39
- </ConfirmDialog>
40
- <Heading level={ 1 }>{ confirmVal }</Heading>
41
- </>
42
- );
43
- };
44
-
45
- export const WithCustomButtonLabels = () => {
46
- const [ confirmVal, setConfirmVal ] = useState( "Hasn't confirmed yet" );
47
-
48
- return (
49
- <>
50
- <ConfirmDialog
51
- onConfirm={ () => setConfirmVal( 'Confirmed!' ) }
52
- cancelButtonText={ daCancelText() }
53
- confirmButtonText={ daConfirmText() }
54
- >
55
- { daText() }
56
- </ConfirmDialog>
57
- <Heading level={ 1 }>{ confirmVal }</Heading>
58
- </>
59
- );
60
- };
61
-
62
- export const WithJSXMessage = () => {
63
- const [ confirmVal, setConfirmVal ] = useState( "Hasn't confirmed yet" );
64
-
65
- return (
66
- <>
67
- <ConfirmDialog onConfirm={ () => setConfirmVal( 'Confirmed!' ) }>
68
- <Heading level={ 2 }>{ daText() }</Heading>
69
- </ConfirmDialog>
70
- <Heading level={ 1 }>{ confirmVal }</Heading>
71
- </>
72
- );
73
- };
74
-
75
- export const VeeeryLongMessage = () => {
76
- const [ confirmVal, setConfirmVal ] = useState( "Hasn't confirmed yet" );
44
+ export default meta;
77
45
 
78
- return (
79
- <>
80
- <ConfirmDialog onConfirm={ () => setConfirmVal( 'Confirmed!' ) }>
81
- { daText().repeat( 20 ) }
82
- </ConfirmDialog>
83
- <Heading level={ 1 }>{ confirmVal }</Heading>
84
- </>
85
- );
86
- };
87
-
88
- export const UncontrolledAndWithExplicitOnCancel = () => {
89
- const [ confirmVal, setConfirmVal ] = useState(
90
- "Hasn't confirmed or cancelled yet"
91
- );
92
-
93
- return (
94
- <>
95
- <ConfirmDialog
96
- onConfirm={ () => setConfirmVal( 'Confirmed!' ) }
97
- onCancel={ () => setConfirmVal( 'Cancelled' ) }
98
- >
99
- { daText() }
100
- </ConfirmDialog>
101
- <Heading level={ 1 }>{ confirmVal }</Heading>
102
- </>
103
- );
104
- };
105
-
106
- // Controlled `ConfirmDialog`s require both `onConfirm` *and* `onCancel to be passed
107
- // It's expected that the user will then use it to hide the dialog, too (see the
108
- // `setIsOpen` calls below).
109
- export const Controlled = () => {
46
+ const Template = ( args ) => {
110
47
  const [ isOpen, setIsOpen ] = useState( false );
111
- const [ confirmVal, setConfirmVal ] = useState(
112
- "Hasn't confirmed or cancelled yet"
113
- );
48
+ const [ confirmVal, setConfirmVal ] = useState( '' );
114
49
 
115
50
  const handleConfirm = () => {
116
51
  setConfirmVal( 'Confirmed!' );
@@ -121,22 +56,75 @@ export const Controlled = () => {
121
56
  setConfirmVal( 'Cancelled' );
122
57
  setIsOpen( false );
123
58
  };
124
-
125
59
  return (
126
60
  <>
61
+ <Button variant="primary" onClick={ () => setIsOpen( true ) }>
62
+ Open ConfirmDialog
63
+ </Button>
64
+
127
65
  <ConfirmDialog
66
+ { ...args }
128
67
  isOpen={ isOpen }
129
68
  onConfirm={ handleConfirm }
130
69
  onCancel={ handleCancel }
131
70
  >
132
- { daText() }
71
+ { args.children }
133
72
  </ConfirmDialog>
134
73
 
135
74
  <Heading level={ 1 }>{ confirmVal }</Heading>
136
-
137
- <Button variant="primary" onClick={ () => setIsOpen( true ) }>
138
- Open ConfirmDialog
139
- </Button>
140
75
  </>
141
76
  );
142
77
  };
78
+
79
+ // Simplest usage: just declare the component with the required `onConfirm` prop. Note: the `onCancel` prop is optional here, unless you'd like to render the component in Controlled mode (see below)
80
+ export const _default = Template.bind( {} );
81
+ const _defaultSnippet = `() => {
82
+ const [ isOpen, setIsOpen ] = useState( false );
83
+ const [ confirmVal, setConfirmVal ] = useState('');
84
+
85
+ const handleConfirm = () => {
86
+ setConfirmVal( 'Confirmed!' );
87
+ setIsOpen( false );
88
+ };
89
+
90
+ const handleCancel = () => {
91
+ setConfirmVal( 'Cancelled' );
92
+ setIsOpen( false );
93
+ };
94
+
95
+ return (
96
+ <>
97
+ <ConfirmDialog
98
+ isOpen={ isOpen }
99
+ onConfirm={ handleConfirm }
100
+ onCancel={ handleCancel }
101
+ >
102
+ Would you like to privately publish the post now?
103
+ </ConfirmDialog>
104
+
105
+ <Heading level={ 1 }>{ confirmVal }</Heading>
106
+
107
+ <Button variant="primary" onClick={ () => setIsOpen( true ) }>
108
+ Open ConfirmDialog
109
+ </Button>
110
+ </>
111
+ );
112
+ };`;
113
+ _default.args = {};
114
+ _default.parameters = {
115
+ docs: {
116
+ source: {
117
+ code: _defaultSnippet,
118
+ language: 'jsx',
119
+ type: 'auto',
120
+ format: 'true',
121
+ },
122
+ },
123
+ };
124
+
125
+ // To customize button text, pass the `cancelButtonText` and/or `confirmButtonText` props.
126
+ export const withCustomButtonLabels = Template.bind( {} );
127
+ withCustomButtonLabels.args = {
128
+ cancelButtonText: 'No thanks',
129
+ confirmButtonText: 'Yes please!',
130
+ };
@@ -70,3 +70,22 @@ export const WithDaysHighlighted = () => {
70
70
  />
71
71
  );
72
72
  };
73
+
74
+ /**
75
+ * You can mark particular dates as invalid using the `isInvalidDate` prop. This
76
+ * prevents the user from being able to select it.
77
+ */
78
+ export const WithInvalidDates = () => {
79
+ const [ currentDate, setCurrentDate ] = useState( now );
80
+
81
+ return (
82
+ <DateTimePicker
83
+ currentDate={ currentDate }
84
+ onChange={ setCurrentDate }
85
+ isInvalidDate={ ( date ) =>
86
+ // Mark Saturdays and Sundays as invalid.
87
+ date.getDay() === 0 || date.getDay() === 6
88
+ }
89
+ />
90
+ );
91
+ };
@@ -1,97 +1,126 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { shallow } from 'enzyme';
5
4
  import moment from 'moment';
5
+ import { render, screen } from '@testing-library/react';
6
+ import userEvent from '@testing-library/user-event';
7
+ import 'react-dates/initialize';
6
8
 
7
9
  /**
8
10
  * Internal dependencies
9
11
  */
10
12
  import DatePicker from '../date';
11
13
 
12
- const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss';
13
-
14
14
  describe( 'DatePicker', () => {
15
- it( 'should pass down a moment object for currentDate', () => {
16
- const currentDate = '1986-10-18T23:00:00';
17
- const wrapper = shallow( <DatePicker currentDate={ currentDate } /> );
18
- const date = wrapper.children().props().date;
19
- expect( moment.isMoment( date ) ).toBe( true );
20
- expect( date.isSame( moment( currentDate ) ) ).toBe( true );
15
+ it( 'should highlight the current date', () => {
16
+ render( <DatePicker currentDate="2022-05-02T11:00:00" /> );
17
+
18
+ expect(
19
+ screen.getByRole( 'button', { name: 'Monday, May 2, 2022' } )
20
+ ).toHaveClass( 'CalendarDay__selected' );
21
+
22
+ // Expect React deprecation warning due to outdated 'react-dates' package.
23
+ // TODO: Update 'react-dates'.
24
+ expect( console ).toHaveWarned();
21
25
  } );
22
26
 
23
- it( 'should pass down a null date when currentDate is set to null', () => {
24
- const wrapper = shallow( <DatePicker currentDate={ null } /> );
25
- expect( wrapper.children().props().date ).toBeNull();
27
+ it( "should highlight today's date when not provided a currentDate", () => {
28
+ render( <DatePicker /> );
29
+
30
+ const todayDescription = moment().format( 'dddd, MMM D, YYYY' );
31
+ expect(
32
+ screen.getByRole( 'button', { name: todayDescription } )
33
+ ).toHaveClass( 'CalendarDay__selected' );
26
34
  } );
27
35
 
28
- it( 'should pass down a moment object for now when currentDate is undefined', () => {
29
- const wrapper = shallow( <DatePicker /> );
30
- const date = wrapper.children().props().date;
31
- expect( moment.isMoment( date ) ).toBe( true );
36
+ it( 'should call onChange when a day is selected', async () => {
37
+ const user = userEvent.setup( { delay: null } );
38
+
39
+ const onChange = jest.fn();
40
+
41
+ render(
42
+ <DatePicker
43
+ currentDate="2022-05-02T11:00:00"
44
+ onChange={ onChange }
45
+ />
46
+ );
47
+
48
+ await user.click(
49
+ screen.getByRole( 'button', { name: 'Friday, May 20, 2022' } )
50
+ );
51
+
52
+ expect( onChange ).toHaveBeenCalledWith( '2022-05-20T11:00:00' );
32
53
  } );
33
54
 
34
- describe( 'onChangeMoment', () => {
35
- it( 'should call onChange with a formated date of the input', () => {
36
- const onChangeSpy = jest.fn();
37
- const currentDate = '1986-10-18T11:00:00';
38
- const wrapper = shallow(
39
- <DatePicker
40
- currentDate={ currentDate }
41
- onChange={ onChangeSpy }
42
- />
43
- );
44
- const newDate = moment();
45
-
46
- wrapper.childAt( 0 ).props().onDateChange( newDate );
47
-
48
- expect( onChangeSpy ).toHaveBeenCalledWith(
49
- newDate.format( TIMEZONELESS_FORMAT )
50
- );
51
- } );
52
-
53
- it( 'should call onChange with hours, minutes, seconds of the current time when currentDate is undefined', () => {
54
- let onChangeSpyArgument;
55
- const onChangeSpy = ( arg ) => ( onChangeSpyArgument = arg );
56
- const wrapper = shallow( <DatePicker onChange={ onChangeSpy } /> );
57
- const newDate = moment( '1986-10-18T11:00:00' );
58
- const current = moment();
59
- const newDateWithCurrentTime = newDate.clone().set( {
60
- hours: current.hours(),
61
- minutes: current.minutes(),
62
- seconds: current.seconds(),
63
- } );
64
- wrapper.childAt( 0 ).props().onDateChange( newDate );
65
-
66
- expect(
67
- moment( onChangeSpyArgument ).isSame(
68
- newDateWithCurrentTime,
69
- 'minute'
70
- )
71
- ).toBe( true );
72
- } );
73
-
74
- it( 'should call onChange with hours, minutes, seconds of the current time when currentDate is null', () => {
75
- let onChangeSpyArgument;
76
- const onChangeSpy = ( arg ) => ( onChangeSpyArgument = arg );
77
- const wrapper = shallow(
78
- <DatePicker currentDate={ null } onChange={ onChangeSpy } />
79
- );
80
- const newDate = moment( '1986-10-18T11:00:00' );
81
- const current = moment();
82
- const newDateWithCurrentTime = newDate.clone().set( {
83
- hours: current.hours(),
84
- minutes: current.minutes(),
85
- seconds: current.seconds(),
86
- } );
87
- wrapper.childAt( 0 ).props().onDateChange( newDate );
88
-
89
- expect(
90
- moment( onChangeSpyArgument ).isSame(
91
- newDateWithCurrentTime,
92
- 'minute'
93
- )
94
- ).toBe( true );
95
- } );
55
+ it( 'should call onMonthPreviewed and onChange when a day in a different month is selected', async () => {
56
+ const user = userEvent.setup( { delay: null } );
57
+
58
+ const onMonthPreviewed = jest.fn();
59
+ const onChange = jest.fn();
60
+
61
+ render(
62
+ <DatePicker
63
+ currentDate="2022-05-02T11:00:00"
64
+ onMonthPreviewed={ onMonthPreviewed }
65
+ onChange={ onChange }
66
+ />
67
+ );
68
+
69
+ await user.click(
70
+ screen.getByRole( 'button', {
71
+ name: 'Move forward to switch to the next month.',
72
+ } )
73
+ );
74
+
75
+ expect( onMonthPreviewed ).toHaveBeenCalledWith(
76
+ expect.stringMatching( /^2022-06/ )
77
+ );
78
+
79
+ await user.click(
80
+ screen.getByRole( 'button', { name: 'Monday, June 20, 2022' } )
81
+ );
82
+
83
+ expect( onChange ).toHaveBeenCalledWith( '2022-06-20T11:00:00' );
84
+ } );
85
+
86
+ it( 'should highlight events on the calendar', () => {
87
+ render(
88
+ <DatePicker
89
+ currentDate="2022-05-02T11:00:00"
90
+ events={ [
91
+ { date: new Date( '2022-05-04T00:00:00' ) },
92
+ { date: new Date( '2022-05-19T00:00:00' ) },
93
+ ] }
94
+ />
95
+ );
96
+
97
+ expect(
98
+ screen
99
+ .getAllByLabelText( 'There is 1 event.', { exact: false } )
100
+ .map( ( day ) => day.getAttribute( 'aria-label' ) )
101
+ ).toEqual( [
102
+ 'Wednesday, May 4, 2022. There is 1 event.',
103
+ 'Thursday, May 19, 2022. There is 1 event.',
104
+ ] );
105
+ } );
106
+
107
+ it( 'should not allow invalid date to be selected', async () => {
108
+ const user = userEvent.setup( { delay: null } );
109
+
110
+ const onChange = jest.fn();
111
+
112
+ render(
113
+ <DatePicker
114
+ currentDate="2022-05-02T11:00:00"
115
+ onChange={ onChange }
116
+ isInvalidDate={ ( date ) => date.getDate() === 20 }
117
+ />
118
+ );
119
+
120
+ await user.click(
121
+ screen.getByRole( 'button', { name: 'Friday, May 20, 2022' } )
122
+ );
123
+
124
+ expect( onChange ).not.toHaveBeenCalledWith( '2022-05-20T11:00:00' );
96
125
  } );
97
126
  } );
@@ -1,7 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`DimensionControl rendering renders with custom sizes 1`] = `
4
- <ForwardRef(SelectControl)
4
+ <ForwardRef(UnforwardedSelectControl)
5
5
  className="block-editor-dimension-control"
6
6
  hideLabelFromVision={false}
7
7
  label={
@@ -34,7 +34,7 @@ exports[`DimensionControl rendering renders with custom sizes 1`] = `
34
34
  `;
35
35
 
36
36
  exports[`DimensionControl rendering renders with defaults 1`] = `
37
- <ForwardRef(SelectControl)
37
+ <ForwardRef(UnforwardedSelectControl)
38
38
  className="block-editor-dimension-control"
39
39
  hideLabelFromVision={false}
40
40
  label={
@@ -75,7 +75,7 @@ exports[`DimensionControl rendering renders with defaults 1`] = `
75
75
  `;
76
76
 
77
77
  exports[`DimensionControl rendering renders with icon and custom icon label 1`] = `
78
- <ForwardRef(SelectControl)
78
+ <ForwardRef(UnforwardedSelectControl)
79
79
  className="block-editor-dimension-control"
80
80
  hideLabelFromVision={false}
81
81
  label={
@@ -128,7 +128,7 @@ exports[`DimensionControl rendering renders with icon and custom icon label 1`]
128
128
  `;
129
129
 
130
130
  exports[`DimensionControl rendering renders with icon and default icon label 1`] = `
131
- <ForwardRef(SelectControl)
131
+ <ForwardRef(UnforwardedSelectControl)
132
132
  className="block-editor-dimension-control"
133
133
  hideLabelFromVision={false}
134
134
  label={
@@ -1,19 +1,13 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { includes, debounce } from 'lodash';
5
4
  import classnames from 'classnames';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
9
8
  */
10
- import {
11
- createContext,
12
- useCallback,
13
- useLayoutEffect,
14
- useRef,
15
- } from '@wordpress/element';
16
- import { focus } from '@wordpress/dom';
9
+ import { __experimentalUseDisabled as useDisabled } from '@wordpress/compose';
10
+ import { createContext } from '@wordpress/element';
17
11
 
18
12
  /**
19
13
  * Internal dependencies
@@ -23,25 +17,6 @@ import { StyledWrapper } from './styles/disabled-styles';
23
17
  const Context = createContext( false );
24
18
  const { Consumer, Provider } = Context;
25
19
 
26
- /**
27
- * Names of control nodes which qualify for disabled behavior.
28
- *
29
- * See WHATWG HTML Standard: 4.10.18.5: "Enabling and disabling form controls: the disabled attribute".
30
- *
31
- * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
32
- *
33
- * @type {string[]}
34
- */
35
- const DISABLED_ELIGIBLE_NODE_NAMES = [
36
- 'BUTTON',
37
- 'FIELDSET',
38
- 'INPUT',
39
- 'OPTGROUP',
40
- 'OPTION',
41
- 'SELECT',
42
- 'TEXTAREA',
43
- ];
44
-
45
20
  /**
46
21
  * @typedef OwnProps
47
22
  * @property {string} [className] Classname for the disabled element.
@@ -54,68 +29,8 @@ const DISABLED_ELIGIBLE_NODE_NAMES = [
54
29
  * @return {JSX.Element} Element wrapping the children to disable them when isDisabled is true.
55
30
  */
56
31
  function Disabled( { className, children, isDisabled = true, ...props } ) {
57
- /** @type {import('react').RefObject<HTMLDivElement>} */
58
- const node = useRef( null );
59
-
60
- const disable = () => {
61
- if ( ! node.current ) {
62
- return;
63
- }
64
-
65
- focus.focusable.find( node.current ).forEach( ( focusable ) => {
66
- if (
67
- includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
68
- ) {
69
- focusable.setAttribute( 'disabled', '' );
70
- }
71
-
72
- if ( focusable.nodeName === 'A' ) {
73
- focusable.setAttribute( 'tabindex', '-1' );
74
- }
75
-
76
- const tabIndex = focusable.getAttribute( 'tabindex' );
77
- if ( tabIndex !== null && tabIndex !== '-1' ) {
78
- focusable.removeAttribute( 'tabindex' );
79
- }
80
-
81
- if ( focusable.hasAttribute( 'contenteditable' ) ) {
82
- focusable.setAttribute( 'contenteditable', 'false' );
83
- }
84
- } );
85
- };
86
-
87
- // Debounce re-disable since disabling process itself will incur
88
- // additional mutations which should be ignored.
89
- const debouncedDisable = useCallback(
90
- debounce( disable, undefined, { leading: true } ),
91
- []
92
- );
93
-
94
- useLayoutEffect( () => {
95
- if ( ! isDisabled ) {
96
- return;
97
- }
98
-
99
- disable();
100
-
101
- /** @type {MutationObserver | undefined} */
102
- let observer;
103
- if ( node.current ) {
104
- observer = new window.MutationObserver( debouncedDisable );
105
- observer.observe( node.current, {
106
- childList: true,
107
- attributes: true,
108
- subtree: true,
109
- } );
110
- }
111
-
112
- return () => {
113
- if ( observer ) {
114
- observer.disconnect();
115
- }
116
- debouncedDisable.cancel();
117
- };
118
- }, [] );
32
+ /** @type {import('react').RefCallback<HTMLDivElement>} */
33
+ const ref = useDisabled();
119
34
 
120
35
  if ( ! isDisabled ) {
121
36
  return <Provider value={ false }>{ children }</Provider>;
@@ -124,7 +39,7 @@ function Disabled( { className, children, isDisabled = true, ...props } ) {
124
39
  return (
125
40
  <Provider value={ true }>
126
41
  <StyledWrapper
127
- ref={ node }
42
+ ref={ ref }
128
43
  className={ classnames( className, 'components-disabled' ) }
129
44
  { ...props }
130
45
  >