@wordpress/components 19.9.0 → 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 (185) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/CONTRIBUTING.md +80 -7
  3. package/build/angle-picker-control/angle-circle.js +5 -7
  4. package/build/angle-picker-control/angle-circle.js.map +1 -1
  5. package/build/box-control/index.js +0 -21
  6. package/build/box-control/index.js.map +1 -1
  7. package/build/box-control/utils.js +1 -8
  8. package/build/box-control/utils.js.map +1 -1
  9. package/build/button/index.js +3 -5
  10. package/build/button/index.js.map +1 -1
  11. package/build/circular-option-picker/index.js +1 -2
  12. package/build/circular-option-picker/index.js.map +1 -1
  13. package/build/disabled/index.js +4 -76
  14. package/build/disabled/index.js.map +1 -1
  15. package/build/input-control/index.js +3 -2
  16. package/build/input-control/index.js.map +1 -1
  17. package/build/input-control/styles/input-control-styles.js +42 -30
  18. package/build/input-control/styles/input-control-styles.js.map +1 -1
  19. package/build/mobile/bottom-sheet-select-control/index.native.js +1 -0
  20. package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  21. package/build/popover/index.js +6 -52
  22. package/build/popover/index.js.map +1 -1
  23. package/build/select-control/index.js +31 -4
  24. package/build/select-control/index.js.map +1 -1
  25. package/build/select-control/styles/select-control-styles.js +8 -8
  26. package/build/select-control/styles/select-control-styles.js.map +1 -1
  27. package/build/text-control/index.js +35 -28
  28. package/build/text-control/index.js.map +1 -1
  29. package/build/text-control/types.js +6 -0
  30. package/build/text-control/types.js.map +1 -0
  31. package/build/toggle-group-control/toggle-group-control-option-icon/component.js +6 -4
  32. package/build/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
  33. package/build/tools-panel/tools-panel-header/component.js +52 -36
  34. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  35. package/build/unit-control/index.js +3 -3
  36. package/build/unit-control/index.js.map +1 -1
  37. package/build/unit-control/styles/unit-control-styles.js +11 -20
  38. package/build/unit-control/styles/unit-control-styles.js.map +1 -1
  39. package/build/unit-control/utils.js.map +1 -1
  40. package/build-module/angle-picker-control/angle-circle.js +5 -7
  41. package/build-module/angle-picker-control/angle-circle.js.map +1 -1
  42. package/build-module/box-control/index.js +1 -20
  43. package/build-module/box-control/index.js.map +1 -1
  44. package/build-module/box-control/utils.js +0 -6
  45. package/build-module/box-control/utils.js.map +1 -1
  46. package/build-module/button/index.js +3 -4
  47. package/build-module/button/index.js.map +1 -1
  48. package/build-module/circular-option-picker/index.js +1 -2
  49. package/build-module/circular-option-picker/index.js.map +1 -1
  50. package/build-module/disabled/index.js +5 -76
  51. package/build-module/disabled/index.js.map +1 -1
  52. package/build-module/input-control/index.js +3 -2
  53. package/build-module/input-control/index.js.map +1 -1
  54. package/build-module/input-control/styles/input-control-styles.js +42 -30
  55. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  56. package/build-module/mobile/bottom-sheet-select-control/index.native.js +1 -0
  57. package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  58. package/build-module/popover/index.js +6 -52
  59. package/build-module/popover/index.js.map +1 -1
  60. package/build-module/select-control/index.js +29 -3
  61. package/build-module/select-control/index.js.map +1 -1
  62. package/build-module/select-control/styles/select-control-styles.js +8 -8
  63. package/build-module/select-control/styles/select-control-styles.js.map +1 -1
  64. package/build-module/text-control/index.js +35 -27
  65. package/build-module/text-control/index.js.map +1 -1
  66. package/build-module/text-control/types.js +2 -0
  67. package/build-module/text-control/types.js.map +1 -0
  68. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js +1 -5
  69. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
  70. package/build-module/tools-panel/tools-panel-header/component.js +51 -36
  71. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  72. package/build-module/unit-control/index.js +3 -3
  73. package/build-module/unit-control/index.js.map +1 -1
  74. package/build-module/unit-control/styles/unit-control-styles.js +11 -20
  75. package/build-module/unit-control/styles/unit-control-styles.js.map +1 -1
  76. package/build-module/unit-control/utils.js.map +1 -1
  77. package/build-style/style-rtl.css +7 -0
  78. package/build-style/style.css +7 -0
  79. package/build-types/button/index.d.ts.map +1 -1
  80. package/build-types/circular-option-picker/index.d.ts.map +1 -1
  81. package/build-types/color-picker/styles.d.ts +3 -3
  82. package/build-types/disabled/index.d.ts.map +1 -1
  83. package/build-types/input-control/index.d.ts +4 -3
  84. package/build-types/input-control/index.d.ts.map +1 -1
  85. package/build-types/input-control/stories/index.d.ts +5 -5
  86. package/build-types/input-control/stories/index.d.ts.map +1 -1
  87. package/build-types/input-control/styles/input-control-styles.d.ts +1 -0
  88. package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
  89. package/build-types/input-control/types.d.ts +6 -0
  90. package/build-types/input-control/types.d.ts.map +1 -1
  91. package/build-types/number-control/styles/number-control-styles.d.ts +1 -1
  92. package/build-types/popover/index.d.ts +0 -1
  93. package/build-types/popover/index.d.ts.map +1 -1
  94. package/build-types/select-control/index.d.ts +30 -26
  95. package/build-types/select-control/index.d.ts.map +1 -1
  96. package/build-types/select-control/stories/index.d.ts +23 -0
  97. package/build-types/select-control/stories/index.d.ts.map +1 -0
  98. package/build-types/select-control/styles/select-control-styles.d.ts +3 -4
  99. package/build-types/select-control/styles/select-control-styles.d.ts.map +1 -1
  100. package/build-types/select-control/test/select-control.d.ts +2 -0
  101. package/build-types/select-control/test/select-control.d.ts.map +1 -0
  102. package/build-types/select-control/types.d.ts +52 -1
  103. package/build-types/select-control/types.d.ts.map +1 -1
  104. package/build-types/text-control/index.d.ts +32 -0
  105. package/build-types/text-control/index.d.ts.map +1 -0
  106. package/build-types/text-control/stories/index.d.ts +13 -0
  107. package/build-types/text-control/stories/index.d.ts.map +1 -0
  108. package/build-types/text-control/types.d.ts +25 -0
  109. package/build-types/text-control/types.d.ts.map +1 -0
  110. package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts.map +1 -1
  111. package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
  112. package/build-types/tools-panel/types.d.ts +0 -1
  113. package/build-types/tools-panel/types.d.ts.map +1 -1
  114. package/build-types/unit-control/index.d.ts +2 -2
  115. package/build-types/unit-control/index.d.ts.map +1 -1
  116. package/build-types/unit-control/styles/unit-control-styles.d.ts.map +1 -1
  117. package/build-types/unit-control/test/index.d.ts +2 -0
  118. package/build-types/unit-control/test/index.d.ts.map +1 -0
  119. package/build-types/unit-control/test/utils.d.ts +2 -0
  120. package/build-types/unit-control/test/utils.d.ts.map +1 -0
  121. package/build-types/unit-control/types.d.ts +1 -1
  122. package/build-types/unit-control/types.d.ts.map +1 -1
  123. package/build-types/unit-control/utils.d.ts +3 -3
  124. package/build-types/unit-control/utils.d.ts.map +1 -1
  125. package/package.json +17 -17
  126. package/src/angle-picker-control/angle-circle.js +3 -3
  127. package/src/box-control/README.md +0 -74
  128. package/src/box-control/index.js +0 -15
  129. package/src/box-control/stories/index.js +0 -29
  130. package/src/box-control/utils.js +0 -7
  131. package/src/button/index.js +2 -4
  132. package/src/button/test/index.js +16 -1
  133. package/src/circular-option-picker/index.js +1 -2
  134. package/src/color-palette/README.md +0 -1
  135. package/src/color-palette/test/__snapshots__/index.js.snap +2 -3
  136. package/src/confirm-dialog/stories/index.js +87 -99
  137. package/src/date-time/stories/index.js +19 -0
  138. package/src/date-time/test/date.js +107 -78
  139. package/src/dimension-control/test/__snapshots__/index.test.js.snap +4 -4
  140. package/src/disabled/index.js +5 -90
  141. package/src/form-file-upload/test/index.js +15 -12
  142. package/src/input-control/README.md +1 -1
  143. package/src/input-control/index.tsx +3 -2
  144. package/src/input-control/stories/index.tsx +1 -1
  145. package/src/input-control/styles/input-control-styles.tsx +19 -5
  146. package/src/input-control/types.ts +6 -0
  147. package/src/menu-item/style.scss +10 -0
  148. package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +8 -1
  149. package/src/mobile/bottom-sheet-select-control/index.native.js +1 -0
  150. package/src/mobile/html-text-input/style.android.scss +1 -0
  151. package/src/mobile/html-text-input/style.ios.scss +1 -0
  152. package/src/mobile/link-settings/test/link-settings-navigation.native.js +9 -1
  153. package/src/popover/index.js +5 -51
  154. package/src/select-control/README.md +2 -2
  155. package/src/select-control/index.tsx +30 -29
  156. package/src/select-control/stories/index.tsx +90 -0
  157. package/src/select-control/styles/select-control-styles.ts +9 -8
  158. package/src/select-control/test/{select-control.js → select-control.tsx} +2 -2
  159. package/src/select-control/types.ts +66 -1
  160. package/src/text-control/index.tsx +84 -0
  161. package/src/text-control/stories/index.tsx +66 -0
  162. package/src/text-control/types.ts +29 -0
  163. package/src/toggle-group-control/toggle-group-control-option-icon/component.tsx +1 -5
  164. package/src/tools-panel/test/__snapshots__/index.js.snap +1 -1
  165. package/src/tools-panel/test/index.js +71 -18
  166. package/src/tools-panel/tools-panel-header/component.tsx +75 -33
  167. package/src/tools-panel/types.ts +0 -1
  168. package/src/tooltip/test/index.js +6 -0
  169. package/src/unit-control/index.tsx +2 -5
  170. package/src/unit-control/styles/unit-control-styles.ts +3 -13
  171. package/src/unit-control/test/__snapshots__/index.tsx.snap +33 -0
  172. package/src/unit-control/test/{index.js → index.tsx} +214 -165
  173. package/src/unit-control/test/{utils.js → utils.ts} +38 -19
  174. package/src/unit-control/types.ts +4 -1
  175. package/src/unit-control/utils.ts +5 -3
  176. package/tsconfig.json +2 -1
  177. package/tsconfig.tsbuildinfo +1 -1
  178. package/build/box-control/visualizer.js +0 -165
  179. package/build/box-control/visualizer.js.map +0 -1
  180. package/build-module/box-control/visualizer.js +0 -154
  181. package/build-module/box-control/visualizer.js.map +0 -1
  182. package/src/box-control/visualizer.js +0 -116
  183. package/src/select-control/stories/index.js +0 -104
  184. package/src/text-control/index.js +0 -72
  185. package/src/text-control/stories/index.js +0 -46
@@ -3,7 +3,6 @@
3
3
  * External dependencies
4
4
  */
5
5
  import classnames from 'classnames';
6
- import { isArray } from 'lodash';
7
6
 
8
7
  /**
9
8
  * WordPress dependencies
@@ -140,8 +139,7 @@ export function Button( props, ref ) {
140
139
  // There's a label and...
141
140
  ( !! label &&
142
141
  // The children are empty and...
143
- ( ! children ||
144
- ( isArray( children ) && ! children.length ) ) &&
142
+ ! children?.length &&
145
143
  // The tooltip is not explicitly disabled.
146
144
  false !== showTooltip ) );
147
145
 
@@ -186,7 +184,7 @@ export function Button( props, ref ) {
186
184
  return (
187
185
  <>
188
186
  <Tooltip
189
- text={ describedBy ? describedBy : label }
187
+ text={ children?.length && describedBy ? describedBy : label }
190
188
  shortcut={ shortcut }
191
189
  position={ tooltipPosition }
192
190
  >
@@ -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={