@wordpress/components 19.0.5 → 19.1.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 (103) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/build/circular-option-picker/index.js +2 -2
  3. package/build/circular-option-picker/index.js.map +1 -1
  4. package/build/date-time/time.js +17 -3
  5. package/build/date-time/time.js.map +1 -1
  6. package/build/font-size-picker/index.js +2 -1
  7. package/build/font-size-picker/index.js.map +1 -1
  8. package/build/index.js +7 -7
  9. package/build/index.js.map +1 -1
  10. package/build/mobile/global-styles-context/utils.native.js +2 -2
  11. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  12. package/build/navigation/item/index.js +6 -3
  13. package/build/navigation/item/index.js.map +1 -1
  14. package/build/navigation/styles/navigation-styles.js +37 -30
  15. package/build/navigation/styles/navigation-styles.js.map +1 -1
  16. package/build/palette-edit/index.js +303 -0
  17. package/build/palette-edit/index.js.map +1 -0
  18. package/build/palette-edit/styles.js +112 -0
  19. package/build/palette-edit/styles.js.map +1 -0
  20. package/build/popover/index.js +1 -1
  21. package/build/popover/index.js.map +1 -1
  22. package/build/toggle-group-control/toggle-group-control-option/component.js +30 -4
  23. package/build/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
  24. package/build/tooltip/index.js +4 -4
  25. package/build/tooltip/index.js.map +1 -1
  26. package/build-module/circular-option-picker/index.js +2 -2
  27. package/build-module/circular-option-picker/index.js.map +1 -1
  28. package/build-module/date-time/time.js +17 -3
  29. package/build-module/date-time/time.js.map +1 -1
  30. package/build-module/font-size-picker/index.js +2 -1
  31. package/build-module/font-size-picker/index.js.map +1 -1
  32. package/build-module/index.js +1 -1
  33. package/build-module/index.js.map +1 -1
  34. package/build-module/mobile/global-styles-context/utils.native.js +2 -2
  35. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  36. package/build-module/navigation/item/index.js +7 -4
  37. package/build-module/navigation/item/index.js.map +1 -1
  38. package/build-module/navigation/styles/navigation-styles.js +34 -28
  39. package/build-module/navigation/styles/navigation-styles.js.map +1 -1
  40. package/build-module/palette-edit/index.js +276 -0
  41. package/build-module/palette-edit/index.js.map +1 -0
  42. package/build-module/palette-edit/styles.js +90 -0
  43. package/build-module/palette-edit/styles.js.map +1 -0
  44. package/build-module/popover/index.js +1 -1
  45. package/build-module/popover/index.js.map +1 -1
  46. package/build-module/toggle-group-control/toggle-group-control-option/component.js +26 -5
  47. package/build-module/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
  48. package/build-module/tooltip/index.js +4 -4
  49. package/build-module/tooltip/index.js.map +1 -1
  50. package/build-style/style-rtl.css +12 -1
  51. package/build-style/style.css +12 -1
  52. package/build-types/confirm-dialog/component.d.ts +34 -0
  53. package/build-types/confirm-dialog/component.d.ts.map +1 -0
  54. package/build-types/confirm-dialog/index.d.ts +6 -0
  55. package/build-types/confirm-dialog/index.d.ts.map +1 -0
  56. package/build-types/confirm-dialog/types.d.ts +20 -0
  57. package/build-types/confirm-dialog/types.d.ts.map +1 -0
  58. package/build-types/higher-order/with-focus-outside/index.d.ts +3 -0
  59. package/build-types/higher-order/with-focus-outside/index.d.ts.map +1 -0
  60. package/build-types/modal/aria-helper.d.ts +27 -0
  61. package/build-types/modal/aria-helper.d.ts.map +1 -0
  62. package/build-types/modal/index.d.ts +3 -0
  63. package/build-types/modal/index.d.ts.map +1 -0
  64. package/build-types/popover/index.d.ts.map +1 -1
  65. package/build-types/style-provider/index.d.ts +5 -0
  66. package/build-types/style-provider/index.d.ts.map +1 -0
  67. package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts.map +1 -1
  68. package/build-types/toggle-group-control/types.d.ts +23 -0
  69. package/build-types/toggle-group-control/types.d.ts.map +1 -1
  70. package/build-types/tooltip/index.d.ts +1 -7
  71. package/build-types/tooltip/index.d.ts.map +1 -1
  72. package/package.json +2 -2
  73. package/src/circular-option-picker/index.js +7 -5
  74. package/src/date-time/test/time.js +32 -2
  75. package/src/date-time/time.js +14 -6
  76. package/src/font-size-picker/index.js +1 -0
  77. package/src/index.js +1 -1
  78. package/src/mobile/global-styles-context/utils.native.js +2 -2
  79. package/src/navigation/item/index.js +10 -3
  80. package/src/navigation/stories/more-examples.js +2 -1
  81. package/src/navigation/styles/navigation-styles.js +5 -0
  82. package/src/palette-edit/index.js +392 -0
  83. package/src/palette-edit/style.scss +19 -0
  84. package/src/{color-edit → palette-edit}/styles.js +15 -18
  85. package/src/popover/index.js +5 -1
  86. package/src/style.scss +1 -1
  87. package/src/toggle-group-control/stories/index.js +15 -0
  88. package/src/toggle-group-control/test/index.js +57 -0
  89. package/src/toggle-group-control/toggle-group-control-option/README.md +8 -1
  90. package/src/toggle-group-control/toggle-group-control-option/component.tsx +40 -17
  91. package/src/toggle-group-control/types.ts +24 -0
  92. package/src/tooltip/index.js +2 -7
  93. package/tsconfig.tsbuildinfo +1 -1
  94. package/build/color-edit/index.js +0 -271
  95. package/build/color-edit/index.js.map +0 -1
  96. package/build/color-edit/styles.js +0 -112
  97. package/build/color-edit/styles.js.map +0 -1
  98. package/build-module/color-edit/index.js +0 -247
  99. package/build-module/color-edit/index.js.map +0 -1
  100. package/build-module/color-edit/styles.js +0 -90
  101. package/build-module/color-edit/styles.js.map +0 -1
  102. package/src/color-edit/index.js +0 -329
  103. package/src/color-edit/style.scss +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/components",
3
- "version": "19.0.5",
3
+ "version": "19.1.0",
4
4
  "description": "UI components for WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -74,5 +74,5 @@
74
74
  "publishConfig": {
75
75
  "access": "public"
76
76
  },
77
- "gitHead": "518e7a279a0f596612232c55c83a351460f8816d"
77
+ "gitHead": "6d3bd917064b4b194677233ee426f5988fa441b9"
78
78
  }
@@ -25,15 +25,17 @@ function Option( {
25
25
  const optionButton = (
26
26
  <Button
27
27
  isPressed={ isSelected }
28
- className={ classnames(
29
- className,
30
- 'components-circular-option-picker__option'
31
- ) }
28
+ className="components-circular-option-picker__option"
32
29
  { ...additionalProps }
33
30
  />
34
31
  );
35
32
  return (
36
- <div className="components-circular-option-picker__option-wrapper">
33
+ <div
34
+ className={ classnames(
35
+ className,
36
+ 'components-circular-option-picker__option-wrapper'
37
+ ) }
38
+ >
37
39
  { tooltipText ? (
38
40
  <Tooltip text={ tooltipText }>{ optionButton }</Tooltip>
39
41
  ) : (
@@ -47,13 +47,13 @@ describe( 'TimePicker', () => {
47
47
  fireEvent.change( hoursInput, { target: { value: '12' } } );
48
48
  fireEvent.blur( hoursInput );
49
49
 
50
- expect( onChangeSpy ).toHaveBeenCalledWith( '2018-12-22T12:00:00' );
50
+ expect( onChangeSpy ).toHaveBeenCalledWith( '2018-12-22T00:00:00' );
51
51
  onChangeSpy.mockClear();
52
52
 
53
53
  fireEvent.change( minutesInput, { target: { value: '35' } } );
54
54
  fireEvent.blur( minutesInput );
55
55
 
56
- expect( onChangeSpy ).toHaveBeenCalledWith( '2018-12-22T12:35:00' );
56
+ expect( onChangeSpy ).toHaveBeenCalledWith( '2018-12-22T00:35:00' );
57
57
  onChangeSpy.mockClear();
58
58
  } );
59
59
 
@@ -169,6 +169,36 @@ describe( 'TimePicker', () => {
169
169
  expect( onChangeSpy ).toHaveBeenCalledWith( '1986-10-18T11:00:00' );
170
170
  } );
171
171
 
172
+ it( 'should allow to set the time correctly when the PM period is selected', () => {
173
+ const onChangeSpy = jest.fn();
174
+
175
+ render(
176
+ <TimePicker
177
+ currentTime="1986-10-18T11:00:00"
178
+ onChange={ onChangeSpy }
179
+ is12Hour
180
+ />
181
+ );
182
+
183
+ const pmButton = screen.getByText( 'PM' );
184
+ fireEvent.click( pmButton );
185
+
186
+ const hoursInput = screen.getByLabelText( 'Hours' );
187
+ fireEvent.change( hoursInput, { target: { value: '6' } } );
188
+ fireEvent.blur( hoursInput );
189
+
190
+ // When clicking on 'PM', we expect the time to be 11pm
191
+ expect( onChangeSpy ).toHaveBeenNthCalledWith(
192
+ 1,
193
+ '1986-10-18T23:00:00'
194
+ );
195
+ // When changing the hours to '6', we expect the time to be 6pm
196
+ expect( onChangeSpy ).toHaveBeenNthCalledWith(
197
+ 2,
198
+ '1986-10-18T18:00:00'
199
+ );
200
+ } );
201
+
172
202
  it( 'should truncate at the minutes on change', () => {
173
203
  const onChangeSpy = jest.fn();
174
204
 
@@ -28,6 +28,10 @@ import TimeZone from './timezone';
28
28
  */
29
29
  const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss';
30
30
 
31
+ function from12hTo24h( hours, isPm ) {
32
+ return isPm ? ( ( hours % 12 ) + 12 ) % 24 : hours % 12;
33
+ }
34
+
31
35
  /**
32
36
  * <UpdateOnBlurAsIntegerField>
33
37
  * A shared component to parse, validate, and handle remounting of the underlying form field element like <input> and <select>.
@@ -117,8 +121,16 @@ export function TimePicker( { is12Hour, currentTime, onChange } ) {
117
121
  }
118
122
 
119
123
  function update( name, value ) {
124
+ // If the 12-hour format is being used and the 'PM' period is selected, then
125
+ // the incoming value (which ranges 1-12) should be increased by 12 to match
126
+ // the expected 24-hour format.
127
+ let adjustedValue = value;
128
+ if ( name === 'hours' && is12Hour ) {
129
+ adjustedValue = from12hTo24h( value, am === 'PM' );
130
+ }
131
+
120
132
  // Clone the date and call the specific setter function according to `name`.
121
- const newDate = date.clone()[ name ]( value );
133
+ const newDate = date.clone()[ name ]( adjustedValue );
122
134
  changeDate( newDate );
123
135
  }
124
136
 
@@ -132,11 +144,7 @@ export function TimePicker( { is12Hour, currentTime, onChange } ) {
132
144
 
133
145
  const newDate = date
134
146
  .clone()
135
- .hours(
136
- value === 'PM'
137
- ? ( ( parsedHours % 12 ) + 12 ) % 24
138
- : parsedHours % 12
139
- );
147
+ .hours( from12hTo24h( parsedHours, value === 'PM' ) );
140
148
 
141
149
  changeDate( newDate );
142
150
  };
@@ -186,6 +186,7 @@ function FontSizePicker(
186
186
  value={ option.value }
187
187
  label={ option.label }
188
188
  aria-label={ option.name }
189
+ showTooltip={ true }
189
190
  />
190
191
  ) ) }
191
192
  </ToggleGroupControl>
package/src/index.js CHANGED
@@ -36,7 +36,7 @@ export {
36
36
  } from './card';
37
37
  export { default as CheckboxControl } from './checkbox-control';
38
38
  export { default as ClipboardButton } from './clipboard-button';
39
- export { default as __experimentalColorEdit } from './color-edit';
39
+ export { default as __experimentalPaletteEdit } from './palette-edit';
40
40
  export { default as ColorIndicator } from './color-indicator';
41
41
  export { default as ColorPalette } from './color-palette';
42
42
  export { ColorPicker } from './color-picker';
@@ -233,10 +233,10 @@ export function parseStylesVariables( styles, mappedValues, customValues ) {
233
233
 
234
234
  export function getMappedValues( features, palette ) {
235
235
  const typography = features?.typography;
236
- const colors = { ...palette?.theme, ...palette?.user };
236
+ const colors = { ...palette?.theme, ...palette?.custom };
237
237
  const fontSizes = {
238
238
  ...typography?.fontSizes?.theme,
239
- ...typography?.fontSizes?.user,
239
+ ...typography?.fontSizes?.custom,
240
240
  };
241
241
  const mappedValues = {
242
242
  color: {
@@ -15,7 +15,7 @@ import { isRTL } from '@wordpress/i18n';
15
15
  */
16
16
  import Button from '../../button';
17
17
  import { useNavigationContext } from '../context';
18
- import { ItemUI } from '../styles/navigation-styles';
18
+ import { ItemUI, ItemIconUI } from '../styles/navigation-styles';
19
19
  import NavigationItemBaseContent from './base-content';
20
20
  import NavigationItemBase from './base';
21
21
 
@@ -29,6 +29,7 @@ export default function NavigationItem( props ) {
29
29
  navigateToMenu,
30
30
  onClick = noop,
31
31
  title,
32
+ icon,
32
33
  hideIfTargetMenuEmpty,
33
34
  isText,
34
35
  ...restProps
@@ -62,7 +63,7 @@ export default function NavigationItem( props ) {
62
63
 
63
64
  onClick( event );
64
65
  };
65
- const icon = isRTL() ? chevronLeft : chevronRight;
66
+ const navigationIcon = isRTL() ? chevronLeft : chevronRight;
66
67
  const baseProps = children ? props : { ...props, onClick: undefined };
67
68
  const itemProps = isText
68
69
  ? restProps
@@ -72,12 +73,18 @@ export default function NavigationItem( props ) {
72
73
  <NavigationItemBase { ...baseProps } className={ classes }>
73
74
  { children || (
74
75
  <ItemUI { ...itemProps }>
76
+ { icon && (
77
+ <ItemIconUI>
78
+ <Icon icon={ icon } />
79
+ </ItemIconUI>
80
+ ) }
81
+
75
82
  <NavigationItemBaseContent
76
83
  title={ title }
77
84
  badge={ badge }
78
85
  />
79
86
 
80
- { navigateToMenu && <Icon icon={ icon } /> }
87
+ { navigateToMenu && <Icon icon={ navigationIcon } /> }
81
88
  </ItemUI>
82
89
  ) }
83
90
  </NavigationItemBase>
@@ -2,7 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useEffect, useState } from '@wordpress/element';
5
- import { Icon, wordpress } from '@wordpress/icons';
5
+ import { Icon, wordpress, home } from '@wordpress/icons';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
@@ -33,6 +33,7 @@ export function MoreExamplesStory() {
33
33
  </NavigationGroup>
34
34
  <NavigationGroup title="Items with Unusual Features">
35
35
  <NavigationItem
36
+ icon={ home }
36
37
  item="item-sub-menu"
37
38
  navigateToMenu="sub-menu"
38
39
  title="Sub-Menu with Custom Back Label"
@@ -184,6 +184,11 @@ export const ItemUI = styled.div`
184
184
  opacity: 0.7;
185
185
  `;
186
186
 
187
+ export const ItemIconUI = styled.span`
188
+ display: flex;
189
+ margin-right: ${ space( 2 ) };
190
+ `;
191
+
187
192
  export const ItemBadgeUI = styled.span`
188
193
  margin-left: ${ () => ( isRTL() ? '0' : space( 2 ) ) };
189
194
  margin-right: ${ () => ( isRTL() ? space( 2 ) : '0' ) };
@@ -0,0 +1,392 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { kebabCase } from 'lodash';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useState, useRef, useEffect } from '@wordpress/element';
10
+ import { __ } from '@wordpress/i18n';
11
+ import { lineSolid, moreVertical, plus } from '@wordpress/icons';
12
+ import { __experimentalUseFocusOutside as useFocusOutside } from '@wordpress/compose';
13
+
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+ import Button from '../button';
18
+ import { ColorPicker } from '../color-picker';
19
+ import { FlexItem } from '../flex';
20
+ import { HStack } from '../h-stack';
21
+ import { ItemGroup } from '../item-group';
22
+ import { VStack } from '../v-stack';
23
+ import GradientPicker from '../gradient-picker';
24
+ import ColorPalette from '../color-palette';
25
+ import DropdownMenu from '../dropdown-menu';
26
+ import Popover from '../popover';
27
+ import {
28
+ PaletteActionsContainer,
29
+ PaletteEditStyles,
30
+ PaletteHeading,
31
+ PaletteHStackHeader,
32
+ IndicatorStyled,
33
+ PaletteItem,
34
+ NameContainer,
35
+ NameInputControl,
36
+ DoneButton,
37
+ RemoveButton,
38
+ } from './styles';
39
+ import { NavigableMenu } from '../navigable-container';
40
+ import { DEFAULT_GRADIENT } from '../custom-gradient-picker/constants';
41
+ import CustomGradientPicker from '../custom-gradient-picker';
42
+
43
+ function NameInput( { value, onChange, label } ) {
44
+ return (
45
+ <NameInputControl
46
+ label={ label }
47
+ hideLabelFromVision
48
+ value={ value }
49
+ onChange={ onChange }
50
+ />
51
+ );
52
+ }
53
+
54
+ function Option( {
55
+ canOnlyChangeValues,
56
+ element,
57
+ onChange,
58
+ isEditing,
59
+ onStartEditing,
60
+ onRemove,
61
+ onStopEditing,
62
+ slugPrefix,
63
+ isGradient,
64
+ } ) {
65
+ const focusOutsideProps = useFocusOutside( onStopEditing );
66
+ const value = isGradient ? element.gradient : element.color;
67
+ return (
68
+ <PaletteItem
69
+ as="div"
70
+ onClick={ onStartEditing }
71
+ { ...( isEditing ? focusOutsideProps : {} ) }
72
+ >
73
+ <HStack justify="flex-start">
74
+ <FlexItem>
75
+ <IndicatorStyled
76
+ style={ { background: value, color: 'transparent' } }
77
+ />
78
+ </FlexItem>
79
+ <FlexItem>
80
+ { isEditing && ! canOnlyChangeValues ? (
81
+ <NameInput
82
+ label={
83
+ isGradient
84
+ ? __( 'Gradient name' )
85
+ : __( 'Color name' )
86
+ }
87
+ value={ element.name }
88
+ onChange={ ( nextName ) =>
89
+ onChange( {
90
+ ...element,
91
+ name: nextName,
92
+ slug: slugPrefix + kebabCase( nextName ),
93
+ } )
94
+ }
95
+ />
96
+ ) : (
97
+ <NameContainer>{ element.name }</NameContainer>
98
+ ) }
99
+ </FlexItem>
100
+ { isEditing && ! canOnlyChangeValues && (
101
+ <FlexItem>
102
+ <RemoveButton
103
+ isSmall
104
+ icon={ lineSolid }
105
+ label={ __( 'Remove color' ) }
106
+ onClick={ onRemove }
107
+ />
108
+ </FlexItem>
109
+ ) }
110
+ </HStack>
111
+ { isEditing && (
112
+ <Popover
113
+ position="bottom left"
114
+ className="components-palette-edit__popover"
115
+ >
116
+ { ! isGradient && (
117
+ <ColorPicker
118
+ color={ value }
119
+ onChange={ ( newColor ) =>
120
+ onChange( {
121
+ ...element,
122
+ color: newColor,
123
+ } )
124
+ }
125
+ />
126
+ ) }
127
+ { isGradient && (
128
+ <CustomGradientPicker
129
+ value={ value }
130
+ onChange={ ( newGradient ) =>
131
+ onChange( {
132
+ ...element,
133
+ gradient: newGradient,
134
+ } )
135
+ }
136
+ />
137
+ ) }
138
+ </Popover>
139
+ ) }
140
+ </PaletteItem>
141
+ );
142
+ }
143
+
144
+ function PaletteEditListView( {
145
+ elements,
146
+ onChange,
147
+ editingElement,
148
+ setEditingElement,
149
+ canOnlyChangeValues,
150
+ slugPrefix,
151
+ isGradient,
152
+ } ) {
153
+ // When unmounting the component if there are empty elements (the user did not complete the insertion) clean them.
154
+ const elementsReference = useRef();
155
+ useEffect( () => {
156
+ elementsReference.current = elements;
157
+ }, [ elements ] );
158
+ useEffect( () => {
159
+ return () => {
160
+ if ( elementsReference.current.some( ( { slug } ) => ! slug ) ) {
161
+ const newElements = elementsReference.current.filter(
162
+ ( { slug } ) => slug
163
+ );
164
+ onChange( newElements.length ? newElements : undefined );
165
+ }
166
+ };
167
+ }, [] );
168
+ return (
169
+ <VStack spacing={ 3 }>
170
+ <ItemGroup isBordered isSeparated>
171
+ { elements.map( ( element, index ) => (
172
+ <Option
173
+ isGradient={ isGradient }
174
+ canOnlyChangeValues={ canOnlyChangeValues }
175
+ key={ index }
176
+ element={ element }
177
+ onStartEditing={ () => {
178
+ if ( editingElement !== index ) {
179
+ setEditingElement( index );
180
+ }
181
+ } }
182
+ onChange={ ( newElement ) => {
183
+ onChange(
184
+ elements.map(
185
+ ( currentElement, currentIndex ) => {
186
+ if ( currentIndex === index ) {
187
+ return newElement;
188
+ }
189
+ return currentElement;
190
+ }
191
+ )
192
+ );
193
+ } }
194
+ onRemove={ () => {
195
+ setEditingElement( null );
196
+ const newElements = elements.filter(
197
+ ( _currentElement, currentIndex ) => {
198
+ if ( currentIndex === index ) {
199
+ return false;
200
+ }
201
+ return true;
202
+ }
203
+ );
204
+ onChange(
205
+ newElements.length ? newElements : undefined
206
+ );
207
+ } }
208
+ isEditing={ index === editingElement }
209
+ onStopEditing={ () => {
210
+ if ( index === editingElement ) {
211
+ setEditingElement( null );
212
+ }
213
+ } }
214
+ slugPrefix={ slugPrefix }
215
+ />
216
+ ) ) }
217
+ </ItemGroup>
218
+ </VStack>
219
+ );
220
+ }
221
+
222
+ const EMPTY_ARRAY = [];
223
+
224
+ export default function PaletteEdit( {
225
+ gradients,
226
+ colors = EMPTY_ARRAY,
227
+ onChange,
228
+ paletteLabel,
229
+ emptyMessage,
230
+ canOnlyChangeValues,
231
+ canReset,
232
+ slugPrefix = '',
233
+ } ) {
234
+ const isGradient = !! gradients;
235
+ const elements = isGradient ? gradients : colors;
236
+ const [ isEditing, setIsEditing ] = useState( false );
237
+ const [ editingElement, setEditingElement ] = useState( null );
238
+ const isAdding =
239
+ isEditing &&
240
+ editingElement &&
241
+ elements[ editingElement ] &&
242
+ ! elements[ editingElement ].slug;
243
+
244
+ const hasElements = elements.length > 0;
245
+
246
+ return (
247
+ <PaletteEditStyles>
248
+ <PaletteHStackHeader>
249
+ <PaletteHeading>{ paletteLabel }</PaletteHeading>
250
+ <PaletteActionsContainer>
251
+ { isEditing && (
252
+ <DoneButton
253
+ isSmall
254
+ onClick={ () => {
255
+ setIsEditing( false );
256
+ setEditingElement( null );
257
+ } }
258
+ >
259
+ { __( 'Done' ) }
260
+ </DoneButton>
261
+ ) }
262
+ { ! canOnlyChangeValues && (
263
+ <Button
264
+ isSmall
265
+ isPressed={ isAdding }
266
+ icon={ plus }
267
+ label={
268
+ isGradient
269
+ ? __( 'Add gradient' )
270
+ : __( 'Add color' )
271
+ }
272
+ onClick={ () => {
273
+ onChange( [
274
+ ...elements,
275
+ {
276
+ ...( isGradient
277
+ ? { gradient: DEFAULT_GRADIENT }
278
+ : { color: '#000' } ),
279
+ name: '',
280
+ slug: '',
281
+ },
282
+ ] );
283
+ setIsEditing( true );
284
+ setEditingElement( elements.length );
285
+ } }
286
+ />
287
+ ) }
288
+ { ! isEditing && (
289
+ <Button
290
+ disabled={ ! hasElements }
291
+ isSmall
292
+ icon={ moreVertical }
293
+ label={
294
+ isGradient
295
+ ? __( 'Edit gradients' )
296
+ : __( 'Edit colors' )
297
+ }
298
+ onClick={ () => {
299
+ setIsEditing( true );
300
+ } }
301
+ />
302
+ ) }
303
+ { isEditing && ( canReset || ! canOnlyChangeValues ) && (
304
+ <DropdownMenu
305
+ icon={ moreVertical }
306
+ label={
307
+ isGradient
308
+ ? __( 'Gradient options' )
309
+ : __( 'Color options' )
310
+ }
311
+ toggleProps={ {
312
+ isSmall: true,
313
+ } }
314
+ >
315
+ { ( { onClose } ) => (
316
+ <>
317
+ <NavigableMenu role="menu">
318
+ { ! canOnlyChangeValues && (
319
+ <Button
320
+ variant="tertiary"
321
+ onClick={ () => {
322
+ setEditingElement( null );
323
+ setIsEditing( false );
324
+ onChange();
325
+ onClose();
326
+ } }
327
+ >
328
+ { isGradient
329
+ ? __(
330
+ 'Remove all gradients'
331
+ )
332
+ : __(
333
+ 'Remove all colors'
334
+ ) }
335
+ </Button>
336
+ ) }
337
+ { canReset && (
338
+ <Button
339
+ variant="tertiary"
340
+ onClick={ () => {
341
+ setEditingElement( null );
342
+ onChange();
343
+ onClose();
344
+ } }
345
+ >
346
+ { isGradient
347
+ ? __( 'Reset gradient' )
348
+ : __( 'Reset colors' ) }
349
+ </Button>
350
+ ) }
351
+ </NavigableMenu>
352
+ </>
353
+ ) }
354
+ </DropdownMenu>
355
+ ) }
356
+ </PaletteActionsContainer>
357
+ </PaletteHStackHeader>
358
+ { hasElements && (
359
+ <>
360
+ { isEditing && (
361
+ <PaletteEditListView
362
+ canOnlyChangeValues={ canOnlyChangeValues }
363
+ elements={ elements }
364
+ onChange={ onChange }
365
+ editingElement={ editingElement }
366
+ setEditingElement={ setEditingElement }
367
+ slugPrefix={ slugPrefix }
368
+ isGradient={ isGradient }
369
+ />
370
+ ) }
371
+ { ! isEditing &&
372
+ ( isGradient ? (
373
+ <GradientPicker
374
+ gradients={ gradients }
375
+ onChange={ () => {} }
376
+ clearable={ false }
377
+ disableCustomGradients={ true }
378
+ />
379
+ ) : (
380
+ <ColorPalette
381
+ colors={ colors }
382
+ onChange={ () => {} }
383
+ clearable={ false }
384
+ disableCustomColors={ true }
385
+ />
386
+ ) ) }
387
+ </>
388
+ ) }
389
+ { ! hasElements && emptyMessage }
390
+ </PaletteEditStyles>
391
+ );
392
+ }
@@ -0,0 +1,19 @@
1
+ @include break-medium() {
2
+ .components-palette-edit__popover.components-popover .components-popover__content.components-popover__content.components-popover__content {
3
+ margin-right: #{ math.div($sidebar-width, 2) + $grid-unit-20 };
4
+ margin-top: #{ -($grid-unit-60 + $border-width) };
5
+ }
6
+ }
7
+
8
+ .components-palette-edit__popover {
9
+ .components-custom-gradient-picker__gradient-bar {
10
+ margin-top: 0;
11
+ }
12
+ .components-custom-gradient-picker__ui-line {
13
+ margin-bottom: 0;
14
+ }
15
+ .components-custom-gradient-picker {
16
+ width: 280px;
17
+ padding: 8px;
18
+ }
19
+ }