@wordpress/components 28.1.0 → 28.2.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 (58) hide show
  1. package/CHANGELOG.md +131 -120
  2. package/build/custom-select-control-v2/custom-select.js +1 -3
  3. package/build/custom-select-control-v2/custom-select.js.map +1 -1
  4. package/build/custom-select-control-v2/legacy-component/index.js +16 -10
  5. package/build/custom-select-control-v2/legacy-component/index.js.map +1 -1
  6. package/build/custom-select-control-v2/styles.js +34 -19
  7. package/build/custom-select-control-v2/styles.js.map +1 -1
  8. package/build/custom-select-control-v2/types.js.map +1 -1
  9. package/build/drop-zone/index.js +16 -79
  10. package/build/drop-zone/index.js.map +1 -1
  11. package/build/lock-unlock.js +1 -1
  12. package/build/lock-unlock.js.map +1 -1
  13. package/build/palette-edit/index.js +30 -38
  14. package/build/palette-edit/index.js.map +1 -1
  15. package/build/palette-edit/types.js.map +1 -1
  16. package/build-module/custom-select-control-v2/custom-select.js +1 -3
  17. package/build-module/custom-select-control-v2/custom-select.js.map +1 -1
  18. package/build-module/custom-select-control-v2/legacy-component/index.js +16 -11
  19. package/build-module/custom-select-control-v2/legacy-component/index.js.map +1 -1
  20. package/build-module/custom-select-control-v2/styles.js +33 -18
  21. package/build-module/custom-select-control-v2/styles.js.map +1 -1
  22. package/build-module/custom-select-control-v2/types.js.map +1 -1
  23. package/build-module/drop-zone/index.js +17 -80
  24. package/build-module/drop-zone/index.js.map +1 -1
  25. package/build-module/lock-unlock.js +1 -1
  26. package/build-module/lock-unlock.js.map +1 -1
  27. package/build-module/palette-edit/index.js +31 -39
  28. package/build-module/palette-edit/index.js.map +1 -1
  29. package/build-module/palette-edit/types.js.map +1 -1
  30. package/build-style/style-rtl.css +28 -6
  31. package/build-style/style.css +28 -6
  32. package/build-types/custom-select-control/stories/index.story.d.ts +15 -0
  33. package/build-types/custom-select-control/stories/index.story.d.ts.map +1 -1
  34. package/build-types/custom-select-control-v2/legacy-component/index.d.ts.map +1 -1
  35. package/build-types/custom-select-control-v2/styles.d.ts +4 -0
  36. package/build-types/custom-select-control-v2/styles.d.ts.map +1 -1
  37. package/build-types/custom-select-control-v2/types.d.ts +1 -0
  38. package/build-types/custom-select-control-v2/types.d.ts.map +1 -1
  39. package/build-types/drop-zone/index.d.ts +3 -0
  40. package/build-types/drop-zone/index.d.ts.map +1 -1
  41. package/build-types/palette-edit/index.d.ts.map +1 -1
  42. package/build-types/palette-edit/types.d.ts +1 -3
  43. package/build-types/palette-edit/types.d.ts.map +1 -1
  44. package/package.json +19 -19
  45. package/src/custom-select-control/stories/index.story.tsx +32 -3
  46. package/src/custom-select-control/test/index.js +205 -22
  47. package/src/custom-select-control-v2/custom-select.tsx +1 -1
  48. package/src/custom-select-control-v2/legacy-component/index.tsx +18 -10
  49. package/src/custom-select-control-v2/legacy-component/test/index.tsx +220 -38
  50. package/src/custom-select-control-v2/styles.ts +22 -10
  51. package/src/custom-select-control-v2/types.ts +1 -0
  52. package/src/drop-zone/index.tsx +17 -76
  53. package/src/drop-zone/style.scss +51 -16
  54. package/src/lock-unlock.js +1 -1
  55. package/src/palette-edit/index.tsx +33 -45
  56. package/src/palette-edit/test/index.tsx +2 -4
  57. package/src/palette-edit/types.ts +1 -3
  58. package/tsconfig.tsbuildinfo +1 -1
@@ -13,23 +13,58 @@
13
13
  opacity: 1;
14
14
  visibility: visible;
15
15
  }
16
- }
17
16
 
18
- .components-drop-zone__content {
19
- position: absolute;
20
- top: 0;
21
- bottom: 0;
22
- left: 0;
23
- right: 0;
24
- height: 100%;
25
- width: 100%;
26
- display: flex;
27
- background-color: $components-color-accent;
28
- align-items: center;
29
- justify-content: center;
30
- z-index: z-index(".components-drop-zone__content");
31
- text-align: center;
32
- color: $white;
17
+ .components-drop-zone__content {
18
+ position: absolute;
19
+ top: 0;
20
+ bottom: 0;
21
+ left: 0;
22
+ right: 0;
23
+ height: 100%;
24
+ width: 100%;
25
+ display: flex;
26
+ background-color: $components-color-accent;
27
+ align-items: center;
28
+ justify-content: center;
29
+ z-index: z-index(".components-drop-zone__content");
30
+ text-align: center;
31
+ color: $white;
32
+ opacity: 0;
33
+
34
+ // Without this, when this div is shown,
35
+ // Safari calls a onDropZoneLeave causing a loop because of this bug
36
+ // https://bugs.webkit.org/show_bug.cgi?id=66547
37
+ pointer-events: none;
38
+ }
39
+
40
+ .components-drop-zone__content-inner {
41
+ opacity: 0;
42
+ transform: scale(0.9);
43
+ }
44
+
45
+ &.is-active:not(.has-dragged-out) {
46
+ .components-drop-zone__content {
47
+ opacity: 1;
48
+
49
+ transition: opacity 0.2s ease-in-out;
50
+ @media (prefers-reduced-motion) {
51
+ transition: none;
52
+ }
53
+ }
54
+
55
+ .components-drop-zone__content-inner {
56
+ opacity: 1;
57
+ transform: scale(1);
58
+
59
+ transition:
60
+ opacity 0.1s ease-in-out 0.1s,
61
+ transform 0.1s ease-in-out 0.1s;
62
+
63
+ @media (prefers-reduced-motion) {
64
+ transition: none;
65
+ }
66
+ }
67
+ }
33
68
  }
34
69
 
35
70
  .components-drop-zone__content-icon,
@@ -5,6 +5,6 @@ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/pri
5
5
 
6
6
  export const { lock, unlock } =
7
7
  __dangerousOptInToUnstableAPIsOnlyForCoreModules(
8
- 'I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.',
8
+ 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
9
9
  '@wordpress/components'
10
10
  );
@@ -15,10 +15,7 @@ import {
15
15
  } from '@wordpress/element';
16
16
  import { __, sprintf } from '@wordpress/i18n';
17
17
  import { lineSolid, moreVertical, plus } from '@wordpress/icons';
18
- import {
19
- __experimentalUseFocusOutside as useFocusOutside,
20
- useDebounce,
21
- } from '@wordpress/compose';
18
+ import { useDebounce } from '@wordpress/compose';
22
19
 
23
20
  /**
24
21
  * Internal dependencies
@@ -174,16 +171,13 @@ function Option< T extends Color | Gradient >( {
174
171
  canOnlyChangeValues,
175
172
  element,
176
173
  onChange,
177
- isEditing,
178
- onStartEditing,
179
174
  onRemove,
180
- onStopEditing,
181
175
  popoverProps: receivedPopoverProps,
182
176
  slugPrefix,
183
177
  isGradient,
184
178
  }: OptionProps< T > ) {
185
- const focusOutsideProps = useFocusOutside( onStopEditing );
186
179
  const value = isGradient ? element.gradient : element.color;
180
+ const [ isEditingColor, setIsEditingColor ] = useState( false );
187
181
 
188
182
  // Use internal state instead of a ref to make sure that the component
189
183
  // re-renders when the popover's anchor updates.
@@ -198,26 +192,23 @@ function Option< T extends Color | Gradient >( {
198
192
  );
199
193
 
200
194
  return (
201
- <PaletteItem
202
- className={ isEditing ? 'is-selected' : undefined }
203
- as={ isEditing ? 'div' : 'button' }
204
- onClick={ onStartEditing }
205
- aria-label={
206
- isEditing
207
- ? undefined
208
- : sprintf(
209
- // translators: %s is a color or gradient name, e.g. "Red".
210
- __( 'Edit: %s' ),
211
- element.name.trim().length ? element.name : value
212
- )
213
- }
214
- ref={ setPopoverAnchor }
215
- { ...( isEditing ? { ...focusOutsideProps } : {} ) }
216
- >
195
+ <PaletteItem ref={ setPopoverAnchor } as="div">
217
196
  <HStack justify="flex-start">
218
- <IndicatorStyled colorValue={ value } />
197
+ <Button
198
+ onClick={ () => {
199
+ setIsEditingColor( true );
200
+ } }
201
+ aria-label={ sprintf(
202
+ // translators: %s is a color or gradient name, e.g. "Red".
203
+ __( 'Edit: %s' ),
204
+ element.name.trim().length ? element.name : value
205
+ ) }
206
+ style={ { padding: 0 } }
207
+ >
208
+ <IndicatorStyled colorValue={ value } />
209
+ </Button>
219
210
  <FlexItem>
220
- { isEditing && ! canOnlyChangeValues ? (
211
+ { ! canOnlyChangeValues ? (
221
212
  <NameInput
222
213
  label={
223
214
  isGradient
@@ -244,23 +235,30 @@ function Option< T extends Color | Gradient >( {
244
235
  </NameContainer>
245
236
  ) }
246
237
  </FlexItem>
247
- { isEditing && ! canOnlyChangeValues && (
238
+ { ! canOnlyChangeValues && (
248
239
  <FlexItem>
249
240
  <RemoveButton
250
241
  size="small"
251
242
  icon={ lineSolid }
252
- label={ __( 'Remove color' ) }
243
+ label={ sprintf(
244
+ // translators: %s is a color or gradient name, e.g. "Red".
245
+ __( 'Remove color: %s' ),
246
+ element.name.trim().length
247
+ ? element.name
248
+ : value
249
+ ) }
253
250
  onClick={ onRemove }
254
251
  />
255
252
  </FlexItem>
256
253
  ) }
257
254
  </HStack>
258
- { isEditing && (
255
+ { isEditingColor && (
259
256
  <ColorPickerPopover
260
257
  isGradient={ isGradient }
261
258
  onChange={ onChange }
262
259
  element={ element }
263
260
  popoverProps={ popoverProps }
261
+ onClose={ () => setIsEditingColor( false ) }
264
262
  />
265
263
  ) }
266
264
  </PaletteItem>
@@ -270,12 +268,11 @@ function Option< T extends Color | Gradient >( {
270
268
  function PaletteEditListView< T extends Color | Gradient >( {
271
269
  elements,
272
270
  onChange,
273
- editingElement,
274
- setEditingElement,
275
271
  canOnlyChangeValues,
276
272
  slugPrefix,
277
273
  isGradient,
278
274
  popoverProps,
275
+ addColorRef,
279
276
  }: PaletteEditListViewProps< T > ) {
280
277
  // When unmounting the component if there are empty elements (the user did not complete the insertion) clean them.
281
278
  const elementsReference = useRef< typeof elements >();
@@ -294,11 +291,6 @@ function PaletteEditListView< T extends Color | Gradient >( {
294
291
  canOnlyChangeValues={ canOnlyChangeValues }
295
292
  key={ index }
296
293
  element={ element }
297
- onStartEditing={ () => {
298
- if ( editingElement !== index ) {
299
- setEditingElement( index );
300
- }
301
- } }
302
294
  onChange={ ( newElement ) => {
303
295
  debounceOnChange(
304
296
  elements.map(
@@ -312,7 +304,6 @@ function PaletteEditListView< T extends Color | Gradient >( {
312
304
  );
313
305
  } }
314
306
  onRemove={ () => {
315
- setEditingElement( null );
316
307
  const newElements = elements.filter(
317
308
  ( _currentElement, currentIndex ) => {
318
309
  if ( currentIndex === index ) {
@@ -324,12 +315,7 @@ function PaletteEditListView< T extends Color | Gradient >( {
324
315
  onChange(
325
316
  newElements.length ? newElements : undefined
326
317
  );
327
- } }
328
- isEditing={ index === editingElement }
329
- onStopEditing={ () => {
330
- if ( index === editingElement ) {
331
- setEditingElement( null );
332
- }
318
+ addColorRef.current?.focus();
333
319
  } }
334
320
  slugPrefix={ slugPrefix }
335
321
  popoverProps={ popoverProps }
@@ -408,6 +394,8 @@ export function PaletteEdit( {
408
394
  [ isGradient, elements ]
409
395
  );
410
396
 
397
+ const addColorRef = useRef< HTMLButtonElement | null >( null );
398
+
411
399
  return (
412
400
  <PaletteEditStyles>
413
401
  <HStack>
@@ -428,6 +416,7 @@ export function PaletteEdit( {
428
416
  ) }
429
417
  { ! canOnlyChangeValues && (
430
418
  <Button
419
+ ref={ addColorRef }
431
420
  size="small"
432
421
  isPressed={ isAdding }
433
422
  icon={ plus }
@@ -551,11 +540,10 @@ export function PaletteEdit( {
551
540
  elements={ elements }
552
541
  // @ts-expect-error TODO: Don't know how to resolve
553
542
  onChange={ onChange }
554
- editingElement={ editingElement }
555
- setEditingElement={ setEditingElement }
556
543
  slugPrefix={ slugPrefix }
557
544
  isGradient={ isGradient }
558
545
  popoverProps={ popoverProps }
546
+ addColorRef={ addColorRef }
559
547
  />
560
548
  ) }
561
549
  { ! isEditing && editingElement !== null && (
@@ -306,7 +306,7 @@ describe( 'PaletteEdit', () => {
306
306
  await click( screen.getByRole( 'button', { name: 'Edit: Primary' } ) );
307
307
  await click(
308
308
  screen.getByRole( 'button', {
309
- name: 'Remove color',
309
+ name: 'Remove color: Primary',
310
310
  } )
311
311
  );
312
312
 
@@ -337,9 +337,7 @@ describe( 'PaletteEdit', () => {
337
337
  } )
338
338
  );
339
339
  await click( screen.getByRole( 'button', { name: 'Edit: Primary' } ) );
340
- const nameInput = screen.getByRole( 'textbox', {
341
- name: 'Color name',
342
- } );
340
+ const nameInput = screen.getByDisplayValue( 'Primary' );
343
341
 
344
342
  await clearInput( nameInput as HTMLInputElement );
345
343
 
@@ -116,11 +116,8 @@ export type OptionProps< T extends Color | Gradient > = {
116
116
  onChange: ( newElement: T ) => void;
117
117
  isGradient: T extends Gradient ? true : false;
118
118
  canOnlyChangeValues: PaletteEditProps[ 'canOnlyChangeValues' ];
119
- isEditing: boolean;
120
119
  key: Key;
121
120
  onRemove: MouseEventHandler< HTMLButtonElement >;
122
- onStartEditing: () => void;
123
- onStopEditing: () => void;
124
121
  popoverProps?: PaletteEditProps[ 'popoverProps' ];
125
122
  slugPrefix: string;
126
123
  };
@@ -130,6 +127,7 @@ export type PaletteEditListViewProps< T extends Color | Gradient > = {
130
127
  onChange: ( newElements?: T[] ) => void;
131
128
  isGradient: T extends Gradient ? true : false;
132
129
  canOnlyChangeValues: PaletteEditProps[ 'canOnlyChangeValues' ];
130
+ addColorRef: React.RefObject< HTMLButtonElement >;
133
131
  editingElement?: EditingElement;
134
132
  popoverProps?: PaletteEditProps[ 'popoverProps' ];
135
133
  setEditingElement: ( newEditingElement?: EditingElement ) => void;