@wordpress/components 19.1.1 → 19.1.5

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 (79) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +0 -1
  3. package/build/card/styles.js +21 -17
  4. package/build/card/styles.js.map +1 -1
  5. package/build/color-palette/index.js +28 -8
  6. package/build/color-palette/index.js.map +1 -1
  7. package/build/color-picker/component.js +15 -5
  8. package/build/color-picker/component.js.map +1 -1
  9. package/build/custom-gradient-bar/constants.js +1 -6
  10. package/build/custom-gradient-bar/constants.js.map +1 -1
  11. package/build/custom-gradient-bar/control-points.js +52 -21
  12. package/build/custom-gradient-bar/control-points.js.map +1 -1
  13. package/build/custom-gradient-bar/index.js +5 -1
  14. package/build/custom-gradient-bar/index.js.map +1 -1
  15. package/build/custom-gradient-picker/index.js +3 -1
  16. package/build/custom-gradient-picker/index.js.map +1 -1
  17. package/build/gradient-picker/index.js +5 -3
  18. package/build/gradient-picker/index.js.map +1 -1
  19. package/build/navigation/item/index.js +3 -1
  20. package/build/navigation/item/index.js.map +1 -1
  21. package/build/palette-edit/index.js +19 -13
  22. package/build/palette-edit/index.js.map +1 -1
  23. package/build/toggle-group-control/toggle-group-control-option/styles.js +8 -8
  24. package/build/toggle-group-control/toggle-group-control-option/styles.js.map +1 -1
  25. package/build-module/card/styles.js +21 -17
  26. package/build-module/card/styles.js.map +1 -1
  27. package/build-module/color-palette/index.js +24 -8
  28. package/build-module/color-palette/index.js.map +1 -1
  29. package/build-module/color-picker/component.js +13 -5
  30. package/build-module/color-picker/component.js.map +1 -1
  31. package/build-module/custom-gradient-bar/constants.js +0 -4
  32. package/build-module/custom-gradient-bar/constants.js.map +1 -1
  33. package/build-module/custom-gradient-bar/control-points.js +54 -23
  34. package/build-module/custom-gradient-bar/control-points.js.map +1 -1
  35. package/build-module/custom-gradient-bar/index.js +5 -1
  36. package/build-module/custom-gradient-bar/index.js.map +1 -1
  37. package/build-module/custom-gradient-picker/index.js +3 -1
  38. package/build-module/custom-gradient-picker/index.js.map +1 -1
  39. package/build-module/gradient-picker/index.js +5 -3
  40. package/build-module/gradient-picker/index.js.map +1 -1
  41. package/build-module/navigation/item/index.js +3 -1
  42. package/build-module/navigation/item/index.js.map +1 -1
  43. package/build-module/palette-edit/index.js +20 -14
  44. package/build-module/palette-edit/index.js.map +1 -1
  45. package/build-module/toggle-group-control/toggle-group-control-option/styles.js +8 -8
  46. package/build-module/toggle-group-control/toggle-group-control-option/styles.js.map +1 -1
  47. package/build-style/style-rtl.css +23 -1
  48. package/build-style/style.css +23 -1
  49. package/build-types/card/card/hook.d.ts +1 -1
  50. package/build-types/card/card-header/component.d.ts +1 -1
  51. package/build-types/card/styles.d.ts +7 -4
  52. package/build-types/card/styles.d.ts.map +1 -1
  53. package/build-types/card/types.d.ts +2 -1
  54. package/build-types/card/types.d.ts.map +1 -1
  55. package/build-types/flyout/styles.d.ts +1 -1
  56. package/build-types/toggle-group-control/toggle-group-control-option/styles.d.ts.map +1 -1
  57. package/package.json +2 -2
  58. package/src/card/styles.js +8 -3
  59. package/src/card/test/__snapshots__/index.js.snap +6 -1
  60. package/src/card/test/index.js +20 -0
  61. package/src/card/types.ts +2 -1
  62. package/src/circular-option-picker/style.scss +1 -0
  63. package/src/color-palette/index.js +29 -3
  64. package/src/color-palette/style.scss +22 -1
  65. package/src/color-palette/test/__snapshots__/index.js.snap +29 -21
  66. package/src/color-picker/README.md +13 -11
  67. package/src/color-picker/component.tsx +15 -5
  68. package/src/color-picker/test/index.js +15 -0
  69. package/src/custom-gradient-bar/constants.js +0 -5
  70. package/src/custom-gradient-bar/control-points.js +40 -9
  71. package/src/custom-gradient-bar/index.js +8 -0
  72. package/src/custom-gradient-picker/index.js +8 -1
  73. package/src/gradient-picker/index.js +11 -4
  74. package/src/gradient-picker/stories/index.js +23 -0
  75. package/src/navigation/item/index.js +10 -2
  76. package/src/palette-edit/index.js +25 -20
  77. package/src/palette-edit/style.scss +5 -0
  78. package/src/toggle-group-control/toggle-group-control-option/styles.ts +3 -0
  79. package/tsconfig.tsbuildinfo +1 -1
@@ -5,6 +5,7 @@ import { map } from 'lodash';
5
5
  import { colord, extend } from 'colord';
6
6
  import namesPlugin from 'colord/plugins/names';
7
7
  import a11yPlugin from 'colord/plugins/a11y';
8
+ import classnames from 'classnames';
8
9
 
9
10
  /**
10
11
  * WordPress dependencies
@@ -34,6 +35,7 @@ function SinglePalette( {
34
35
  const colorOptions = useMemo( () => {
35
36
  return map( colors, ( { color, name } ) => {
36
37
  const colordColor = colord( color );
38
+
37
39
  return (
38
40
  <CircularOptionPicker.Option
39
41
  key={ color }
@@ -108,6 +110,20 @@ function MultiplePalettes( {
108
110
  );
109
111
  }
110
112
 
113
+ export function CustomColorPickerDropdown( { isRenderedInSidebar, ...props } ) {
114
+ return (
115
+ <Dropdown
116
+ contentClassName={ classnames(
117
+ 'components-color-palette__custom-color-dropdown-content',
118
+ {
119
+ 'is-rendered-in-sidebar': isRenderedInSidebar,
120
+ }
121
+ ) }
122
+ { ...props }
123
+ />
124
+ );
125
+ }
126
+
111
127
  export default function ColorPalette( {
112
128
  clearable = true,
113
129
  className,
@@ -117,6 +133,7 @@ export default function ColorPalette( {
117
133
  onChange,
118
134
  value,
119
135
  __experimentalHasMultipleOrigins = false,
136
+ __experimentalIsRenderedInSidebar = false,
120
137
  } ) {
121
138
  const clearColor = useCallback( () => onChange( undefined ), [ onChange ] );
122
139
  const Component = __experimentalHasMultipleOrigins
@@ -131,11 +148,13 @@ export default function ColorPalette( {
131
148
  />
132
149
  );
133
150
 
151
+ const colordColor = colord( value );
152
+
134
153
  return (
135
154
  <VStack spacing={ 3 } className={ className }>
136
155
  { ! disableCustomColors && (
137
- <Dropdown
138
- contentClassName="components-color-palette__custom-color-dropdown-content"
156
+ <CustomColorPickerDropdown
157
+ isRenderedInSidebar={ __experimentalIsRenderedInSidebar }
139
158
  renderContent={ renderCustomColorPicker }
140
159
  renderToggle={ ( { isOpen, onToggle } ) => (
141
160
  <button
@@ -144,7 +163,14 @@ export default function ColorPalette( {
144
163
  aria-haspopup="true"
145
164
  onClick={ onToggle }
146
165
  aria-label={ __( 'Custom color picker' ) }
147
- style={ { background: value } }
166
+ style={ {
167
+ background: value,
168
+ color:
169
+ colordColor.contrast() >
170
+ colordColor.contrast( '#000' )
171
+ ? '#fff'
172
+ : '#000',
173
+ } }
148
174
  >
149
175
  { value }
150
176
  </button>
@@ -1,7 +1,7 @@
1
1
  .components-color-palette__custom-color {
2
+ position: relative;
2
3
  border: none;
3
4
  background: none;
4
- outline: 0;
5
5
  display: block;
6
6
  border-radius: $radius-block-ui;
7
7
  height: $grid-unit-60;
@@ -15,13 +15,34 @@
15
15
  box-sizing: border-box;
16
16
  color: $white;
17
17
  cursor: pointer;
18
+ box-shadow: inset 0 0 0 $border-width rgba(0, 0, 0, 0.2);
19
+ // Show a thin outline in Windows high contrast mode.
20
+ outline: 1px solid transparent;
21
+
22
+ &:focus {
23
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
24
+ // Show a outline in Windows high contrast mode.
25
+ outline-width: 2px;
26
+ }
18
27
  }
19
28
 
20
29
  .components-dropdown__content.components-color-palette__custom-color-dropdown-content .components-popover__content {
21
30
  overflow: visible;
22
31
  box-shadow: 0 4px 4px rgba(0, 0, 0, 0.05);
23
32
  border: none;
33
+ border-radius: $radius-block-ui;
24
34
  & > div {
25
35
  padding: 0;
26
36
  }
37
+ .react-colorful__saturation {
38
+ border-top-right-radius: $radius-block-ui;
39
+ border-top-left-radius: $radius-block-ui;
40
+ }
41
+ }
42
+
43
+ @include break-medium() {
44
+ .components-dropdown__content.components-color-palette__custom-color-dropdown-content.is-rendered-in-sidebar.is-from-top .components-popover__content {
45
+ margin-right: #{ math.div($sidebar-width, 2) + $grid-unit-20 };
46
+ margin-top: #{ -($grid-unit-60 + $grid-unit-15) };
47
+ }
27
48
  }
@@ -17,6 +17,7 @@ exports[`ColorPalette Dropdown .renderToggle should render dropdown content 1`]
17
17
  style={
18
18
  Object {
19
19
  "background": "#f00",
20
+ "color": "#000",
20
21
  }
21
22
  }
22
23
  >
@@ -27,7 +28,6 @@ exports[`ColorPalette Dropdown .renderToggle should render dropdown content 1`]
27
28
  exports[`ColorPalette Dropdown should render it correctly 1`] = `
28
29
  <Dropdown
29
30
  contentClassName="components-color-palette__custom-color-dropdown-content"
30
- key=".0"
31
31
  renderContent={[Function]}
32
32
  renderToggle={[Function]}
33
33
  >
@@ -44,6 +44,7 @@ exports[`ColorPalette Dropdown should render it correctly 1`] = `
44
44
  style={
45
45
  Object {
46
46
  "background": "#f00",
47
+ "color": "#000",
47
48
  }
48
49
  }
49
50
  >
@@ -177,32 +178,39 @@ exports[`ColorPalette should render a dynamic toolbar of colors 1`] = `
177
178
  data-wp-c16t={true}
178
179
  data-wp-component="VStack"
179
180
  >
180
- <Dropdown
181
- contentClassName="components-color-palette__custom-color-dropdown-content"
181
+ <CustomColorPickerDropdown
182
+ isRenderedInSidebar={false}
182
183
  key=".0"
183
184
  renderContent={[Function]}
184
185
  renderToggle={[Function]}
185
186
  >
186
- <div
187
- className="components-dropdown"
188
- tabIndex="-1"
187
+ <Dropdown
188
+ contentClassName="components-color-palette__custom-color-dropdown-content"
189
+ renderContent={[Function]}
190
+ renderToggle={[Function]}
189
191
  >
190
- <button
191
- aria-expanded={false}
192
- aria-haspopup="true"
193
- aria-label="Custom color picker"
194
- className="components-color-palette__custom-color"
195
- onClick={[Function]}
196
- style={
197
- Object {
198
- "background": "#f00",
199
- }
200
- }
192
+ <div
193
+ className="components-dropdown"
194
+ tabIndex="-1"
201
195
  >
202
- #f00
203
- </button>
204
- </div>
205
- </Dropdown>
196
+ <button
197
+ aria-expanded={false}
198
+ aria-haspopup="true"
199
+ aria-label="Custom color picker"
200
+ className="components-color-palette__custom-color"
201
+ onClick={[Function]}
202
+ style={
203
+ Object {
204
+ "background": "#f00",
205
+ "color": "#000",
206
+ }
207
+ }
208
+ >
209
+ #f00
210
+ </button>
211
+ </div>
212
+ </Dropdown>
213
+ </CustomColorPickerDropdown>
206
214
  <SinglePalette
207
215
  actions={
208
216
  <ButtonAction
@@ -22,32 +22,34 @@ function Example() {
22
22
 
23
23
  ## Props
24
24
 
25
- ### `color`
26
-
27
- **Type**: `string`
25
+ ### `color`: `string`
28
26
 
29
27
  The current color value to display in the picker. Must be a hex or hex8 string.
30
28
 
31
- ### `onChange`
29
+ - Required: No
32
30
 
33
- **Type**: `(hex8Color: string) => void`
31
+ ### `onChange`: `(hex8Color: string) => void`
34
32
 
35
33
  Fired when the color changes. Always passes a hex8 color string.
36
34
 
37
- ### `enableAlpha`
35
+ - Required: No
38
36
 
39
- **Type**: `boolean`
37
+ ### `enableAlpha`: `boolean`
40
38
 
41
39
  Defaults to `false`. When `true` the color picker will display the alpha channel both in the bottom inputs as well as in the color picker itself.
42
40
 
43
- ### `defaultValue`
41
+ - Required: No
42
+ - Default: `false`
44
43
 
45
- **Type**: `string | undefined`
44
+ ### `defaultValue`: `string | undefined`
46
45
 
47
46
  An optional default value to use for the color picker.
48
47
 
49
- ### `copyFormat`
48
+ - Required: No
49
+ - Default: `'#fff'`
50
50
 
51
- **Type**: `'hex' | 'hsl' | 'rgb' | undefined`
51
+ ### `copyFormat`: `'hex' | 'hsl' | 'rgb' | undefined`
52
52
 
53
53
  The format to copy when clicking the displayed color format.
54
+
55
+ - Required: No
@@ -11,6 +11,7 @@ import namesPlugin from 'colord/plugins/names';
11
11
  */
12
12
  import { useState, useMemo } from '@wordpress/element';
13
13
  import { settings } from '@wordpress/icons';
14
+ import { useDebounce } from '@wordpress/compose';
14
15
  import { __ } from '@wordpress/i18n';
15
16
 
16
17
  /**
@@ -32,6 +33,7 @@ import {
32
33
  import { ColorDisplay } from './color-display';
33
34
  import { ColorInput } from './color-input';
34
35
  import { Picker } from './picker';
36
+ import { useControlledValue } from '../utils/hooks';
35
37
 
36
38
  import type { ColorType } from './types';
37
39
 
@@ -57,7 +59,7 @@ const ColorPicker = (
57
59
  ) => {
58
60
  const {
59
61
  enableAlpha = false,
60
- color,
62
+ color: colorProp,
61
63
  onChange,
62
64
  defaultValue = '#fff',
63
65
  copyFormat,
@@ -65,15 +67,23 @@ const ColorPicker = (
65
67
  } = useContextSystem( props, 'ColorPicker' );
66
68
 
67
69
  // Use a safe default value for the color and remove the possibility of `undefined`.
70
+ const [ color, setColor ] = useControlledValue( {
71
+ onChange,
72
+ value: colorProp,
73
+ defaultValue,
74
+ } );
75
+
68
76
  const safeColordColor = useMemo( () => {
69
- return color ? colord( color ) : colord( defaultValue );
70
- }, [ color, defaultValue ] );
77
+ return colord( color );
78
+ }, [ color ] );
79
+
80
+ const debouncedSetColor = useDebounce( setColor );
71
81
 
72
82
  const handleChange = useCallback(
73
83
  ( nextValue: Colord ) => {
74
- onChange( nextValue.toHex() );
84
+ debouncedSetColor( nextValue.toHex() );
75
85
  },
76
- [ onChange ]
86
+ [ debouncedSetColor ]
77
87
  );
78
88
 
79
89
  const [ showInputs, setShowInputs ] = useState< boolean >( false );
@@ -41,6 +41,12 @@ function moveReactColorfulSlider( sliderElement, from, to ) {
41
41
  fireEvent( sliderElement, new FakeMouseEvent( 'mousemove', to ) );
42
42
  }
43
43
 
44
+ const sleep = ( ms ) => {
45
+ const promise = new Promise( ( resolve ) => setTimeout( resolve, ms ) );
46
+ jest.advanceTimersByTime( ms + 1 );
47
+ return promise;
48
+ };
49
+
44
50
  const hslaMatcher = expect.objectContaining( {
45
51
  h: expect.any( Number ),
46
52
  s: expect.any( Number ),
@@ -87,6 +93,9 @@ describe( 'ColorPicker', () => {
87
93
  { pageX: 10, pageY: 10 }
88
94
  );
89
95
 
96
+ // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
97
+ await sleep( 1 );
98
+
90
99
  expect( onChangeComplete ).toHaveBeenCalledWith(
91
100
  legacyColorMatcher
92
101
  );
@@ -108,6 +117,9 @@ describe( 'ColorPicker', () => {
108
117
  { pageX: 10, pageY: 10 }
109
118
  );
110
119
 
120
+ // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
121
+ await sleep( 1 );
122
+
111
123
  expect( onChange ).toHaveBeenCalledWith(
112
124
  expect.stringMatching( /^#([a-fA-F0-9]{8})$/ )
113
125
  );
@@ -138,6 +150,9 @@ describe( 'ColorPicker', () => {
138
150
  { pageX: 10, pageY: 10 }
139
151
  );
140
152
 
153
+ // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
154
+ await sleep( 1 );
155
+
141
156
  expect( onChange ).toHaveBeenCalledWith(
142
157
  expect.stringMatching( /^#([a-fA-F0-9]{6})$/ )
143
158
  );
@@ -1,8 +1,3 @@
1
- export const COLOR_POPOVER_PROPS = {
2
- className: 'components-custom-gradient-picker__color-picker-popover',
3
- position: 'top',
4
- };
5
-
6
1
  export const GRADIENT_MARKERS_WIDTH = 16;
7
2
  export const INSERT_POINT_WIDTH = 16;
8
3
  export const MINIMUM_ABSOLUTE_LEFT_POSITION = 5;
@@ -8,8 +8,8 @@ import { colord } from 'colord';
8
8
  * WordPress dependencies
9
9
  */
10
10
  import { useInstanceId } from '@wordpress/compose';
11
- import { useEffect, useRef, useState } from '@wordpress/element';
12
- import { __, sprintf } from '@wordpress/i18n';
11
+ import { useEffect, useRef, useState, useMemo } from '@wordpress/element';
12
+ import { __, sprintf, isRTL } from '@wordpress/i18n';
13
13
  import { plus } from '@wordpress/icons';
14
14
  import { LEFT, RIGHT } from '@wordpress/keycodes';
15
15
 
@@ -18,8 +18,8 @@ import { LEFT, RIGHT } from '@wordpress/keycodes';
18
18
  */
19
19
  import Button from '../button';
20
20
  import { ColorPicker } from '../color-picker';
21
- import Dropdown from '../dropdown';
22
21
  import { VisuallyHidden } from '../visually-hidden';
22
+ import { CustomColorPickerDropdown } from '../color-palette';
23
23
 
24
24
  import {
25
25
  addControlPoint,
@@ -31,7 +31,6 @@ import {
31
31
  getHorizontalRelativeGradientPosition,
32
32
  } from './utils';
33
33
  import {
34
- COLOR_POPOVER_PROPS,
35
34
  GRADIENT_MARKERS_WIDTH,
36
35
  MINIMUM_SIGNIFICANT_MOVE,
37
36
  KEYBOARD_CONTROL_POINT_VARIATION,
@@ -74,6 +73,33 @@ function ControlPointButton( { isOpen, position, color, ...additionalProps } ) {
74
73
  );
75
74
  }
76
75
 
76
+ function GradientColorPickerDropdown( {
77
+ isRenderedInSidebar,
78
+ gradientPickerDomRef,
79
+ ...props
80
+ } ) {
81
+ const popoverProps = useMemo( () => {
82
+ const result = {
83
+ className:
84
+ 'components-custom-gradient-picker__color-picker-popover',
85
+ position: 'top',
86
+ };
87
+ if ( isRenderedInSidebar ) {
88
+ result.anchorRef = gradientPickerDomRef.current;
89
+ result.position = isRTL() ? 'bottom right' : 'bottom left';
90
+ result.__unstableForcePosition = true;
91
+ }
92
+ return result;
93
+ }, [ gradientPickerDomRef.current, isRenderedInSidebar ] );
94
+ return (
95
+ <CustomColorPickerDropdown
96
+ isRenderedInSidebar={ isRenderedInSidebar }
97
+ popoverProps={ popoverProps }
98
+ { ...props }
99
+ />
100
+ );
101
+ }
102
+
77
103
  function ControlPoints( {
78
104
  disableRemove,
79
105
  disableAlpha,
@@ -83,6 +109,7 @@ function ControlPoints( {
83
109
  onChange,
84
110
  onStartControlPointChange,
85
111
  onStopControlPointChange,
112
+ __experimentalIsRenderedInSidebar,
86
113
  } ) {
87
114
  const controlPointMoveState = useRef();
88
115
 
@@ -134,7 +161,9 @@ function ControlPoints( {
134
161
  const initialPosition = point?.position;
135
162
  return (
136
163
  ignoreMarkerPosition !== initialPosition && (
137
- <Dropdown
164
+ <GradientColorPickerDropdown
165
+ gradientPickerDomRef={ gradientPickerDomRef }
166
+ isRenderedInSidebar={ __experimentalIsRenderedInSidebar }
138
167
  key={ index }
139
168
  onClose={ onStopControlPointChange }
140
169
  renderToggle={ ( { isOpen, onToggle } ) => (
@@ -225,7 +254,7 @@ function ControlPoints( {
225
254
  );
226
255
  } }
227
256
  />
228
- { ! disableRemove && (
257
+ { ! disableRemove && controlPoints.length > 2 && (
229
258
  <Button
230
259
  className="components-custom-gradient-picker__remove-control-point"
231
260
  onClick={ () => {
@@ -244,7 +273,6 @@ function ControlPoints( {
244
273
  ) }
245
274
  </>
246
275
  ) }
247
- popoverProps={ COLOR_POPOVER_PROPS }
248
276
  />
249
277
  )
250
278
  );
@@ -258,10 +286,14 @@ function InsertPoint( {
258
286
  onCloseInserter,
259
287
  insertPosition,
260
288
  disableAlpha,
289
+ __experimentalIsRenderedInSidebar,
290
+ gradientPickerDomRef,
261
291
  } ) {
262
292
  const [ alreadyInsertedPoint, setAlreadyInsertedPoint ] = useState( false );
263
293
  return (
264
- <Dropdown
294
+ <GradientColorPickerDropdown
295
+ gradientPickerDomRef={ gradientPickerDomRef }
296
+ isRenderedInSidebar={ __experimentalIsRenderedInSidebar }
265
297
  className="components-custom-gradient-picker__inserter"
266
298
  onClose={ () => {
267
299
  onCloseInserter();
@@ -314,7 +346,6 @@ function InsertPoint( {
314
346
  } }
315
347
  />
316
348
  ) }
317
- popoverProps={ COLOR_POPOVER_PROPS }
318
349
  />
319
350
  );
320
351
  }
@@ -78,6 +78,7 @@ export default function CustomGradientBar( {
78
78
  onChange,
79
79
  disableInserter = false,
80
80
  disableAlpha = false,
81
+ __experimentalIsRenderedInSidebar,
81
82
  } ) {
82
83
  const gradientPickerDomRef = useRef();
83
84
 
@@ -134,6 +135,10 @@ export default function CustomGradientBar( {
134
135
  { ! disableInserter &&
135
136
  ( isMovingInserter || isInsertingControlPoint ) && (
136
137
  <ControlPoints.InsertPoint
138
+ __experimentalIsRenderedInSidebar={
139
+ __experimentalIsRenderedInSidebar
140
+ }
141
+ gradientPickerDomRef={ gradientPickerDomRef }
137
142
  disableAlpha={ disableAlpha }
138
143
  insertPosition={ gradientBarState.insertPosition }
139
144
  value={ controlPoints }
@@ -151,6 +156,9 @@ export default function CustomGradientBar( {
151
156
  />
152
157
  ) }
153
158
  <ControlPoints
159
+ __experimentalIsRenderedInSidebar={
160
+ __experimentalIsRenderedInSidebar
161
+ }
154
162
  disableAlpha={ disableAlpha }
155
163
  disableRemove={ disableInserter }
156
164
  gradientPickerDomRef={ gradientPickerDomRef }
@@ -103,7 +103,11 @@ const GradientTypePicker = ( { gradientAST, hasGradient, onChange } ) => {
103
103
  );
104
104
  };
105
105
 
106
- export default function CustomGradientPicker( { value, onChange } ) {
106
+ export default function CustomGradientPicker( {
107
+ value,
108
+ onChange,
109
+ __experimentalIsRenderedInSidebar,
110
+ } ) {
107
111
  const gradientAST = getGradientAstWithDefault( value );
108
112
  // On radial gradients the bar should display a linear gradient.
109
113
  // On radial gradients the bar represents a slice of the gradient from the center until the outside.
@@ -120,6 +124,9 @@ export default function CustomGradientPicker( { value, onChange } ) {
120
124
  return (
121
125
  <div className="components-custom-gradient-picker">
122
126
  <CustomGradientBar
127
+ __experimentalIsRenderedInSidebar={
128
+ __experimentalIsRenderedInSidebar
129
+ }
123
130
  background={ background }
124
131
  hasGradient={ hasGradient }
125
132
  value={ controlPoints }
@@ -106,13 +106,16 @@ export default function GradientPicker( {
106
106
  clearable = true,
107
107
  disableCustomGradients = false,
108
108
  __experimentalHasMultipleOrigins,
109
+ __experimentalIsRenderedInSidebar,
109
110
  } ) {
110
111
  const clearGradient = useCallback( () => onChange( undefined ), [
111
112
  onChange,
112
113
  ] );
113
- const Component = __experimentalHasMultipleOrigins
114
- ? MultipleOrigin
115
- : SingleOrigin;
114
+ const Component =
115
+ __experimentalHasMultipleOrigins && gradients?.length
116
+ ? MultipleOrigin
117
+ : SingleOrigin;
118
+
116
119
  return (
117
120
  <Component
118
121
  className={ className }
@@ -122,7 +125,8 @@ export default function GradientPicker( {
122
125
  onChange={ onChange }
123
126
  value={ value }
124
127
  actions={
125
- clearable && (
128
+ clearable &&
129
+ ( gradients?.length || ! disableCustomGradients ) && (
126
130
  <CircularOptionPicker.ButtonAction
127
131
  onClick={ clearGradient }
128
132
  >
@@ -133,6 +137,9 @@ export default function GradientPicker( {
133
137
  content={
134
138
  ! disableCustomGradients && (
135
139
  <CustomGradientPicker
140
+ __experimentalIsRenderedInSidebar={
141
+ __experimentalIsRenderedInSidebar
142
+ }
136
143
  value={ value }
137
144
  onChange={ onChange }
138
145
  />
@@ -84,3 +84,26 @@ export const _default = () => {
84
84
  />
85
85
  );
86
86
  };
87
+
88
+ export const WithNoExistingGradients = () => {
89
+ const disableCustomGradients = boolean( 'Disable Custom Gradients', false );
90
+ const __experimentalHasMultipleOrigins = boolean(
91
+ 'Experimental Has Multiple Origins',
92
+ true
93
+ );
94
+ const clearable = boolean( 'Clearable', true );
95
+ const className = text( 'Class Name', '' );
96
+ const gradients = object( 'Gradients', [] );
97
+
98
+ return (
99
+ <GradientPickerWithState
100
+ __experimentalHasMultipleOrigins={
101
+ __experimentalHasMultipleOrigins
102
+ }
103
+ disableCustomGradients={ disableCustomGradients }
104
+ gradients={ gradients }
105
+ clearable={ clearable }
106
+ className={ className }
107
+ />
108
+ );
109
+ };
@@ -52,8 +52,10 @@ export default function NavigationItem( props ) {
52
52
  return null;
53
53
  }
54
54
 
55
+ const isActive = item && activeItem === item;
56
+
55
57
  const classes = classnames( className, {
56
- 'is-active': item && activeItem === item,
58
+ 'is-active': isActive,
57
59
  } );
58
60
 
59
61
  const onItemClick = ( event ) => {
@@ -67,7 +69,13 @@ export default function NavigationItem( props ) {
67
69
  const baseProps = children ? props : { ...props, onClick: undefined };
68
70
  const itemProps = isText
69
71
  ? restProps
70
- : { as: Button, href, onClick: onItemClick, ...restProps };
72
+ : {
73
+ as: Button,
74
+ href,
75
+ onClick: onItemClick,
76
+ 'aria-current': isActive ? 'page' : undefined,
77
+ ...restProps,
78
+ };
71
79
 
72
80
  return (
73
81
  <NavigationItemBase { ...baseProps } className={ classes }>