@wordpress/components 19.0.0 → 19.0.1

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 (213) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/CONTRIBUTING.md +12 -12
  3. package/build/angle-picker-control/index.js +3 -1
  4. package/build/angle-picker-control/index.js.map +1 -1
  5. package/build/angle-picker-control/styles/angle-picker-control-styles.js +4 -4
  6. package/build/angle-picker-control/styles/angle-picker-control-styles.js.map +1 -1
  7. package/build/base-control/index.js +1 -1
  8. package/build/base-control/index.js.map +1 -1
  9. package/build/color-edit/index.js +180 -199
  10. package/build/color-edit/index.js.map +1 -1
  11. package/build/color-edit/styles.js +112 -0
  12. package/build/color-edit/styles.js.map +1 -0
  13. package/build/color-list-picker/index.js +6 -1
  14. package/build/color-list-picker/index.js.map +1 -1
  15. package/build/color-palette/index.js +86 -21
  16. package/build/color-palette/index.js.map +1 -1
  17. package/build/color-palette/styles.js +31 -0
  18. package/build/color-palette/styles.js.map +1 -0
  19. package/build/color-picker/component.js +7 -18
  20. package/build/color-picker/component.js.map +1 -1
  21. package/build/color-picker/picker.js +3 -3
  22. package/build/color-picker/picker.js.map +1 -1
  23. package/build/duotone-picker/custom-duotone-bar.js +0 -1
  24. package/build/duotone-picker/custom-duotone-bar.js.map +1 -1
  25. package/build/duotone-picker/duotone-picker.js +1 -0
  26. package/build/duotone-picker/duotone-picker.js.map +1 -1
  27. package/build/gradient-picker/index.js +69 -9
  28. package/build/gradient-picker/index.js.map +1 -1
  29. package/build/index.native.js +9 -0
  30. package/build/index.native.js.map +1 -1
  31. package/build/mobile/bottom-sheet/cell.native.js +4 -2
  32. package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
  33. package/build/mobile/bottom-sheet/link-cell.native.js +3 -2
  34. package/build/mobile/bottom-sheet/link-cell.native.js.map +1 -1
  35. package/build/mobile/link-settings/image-link-destinations-screen.native.js +140 -0
  36. package/build/mobile/link-settings/image-link-destinations-screen.native.js.map +1 -0
  37. package/build/mobile/link-settings/index.native.js +3 -2
  38. package/build/mobile/link-settings/index.native.js.map +1 -1
  39. package/build/mobile/link-settings/link-settings-navigation.native.js +1 -0
  40. package/build/mobile/link-settings/link-settings-navigation.native.js.map +1 -1
  41. package/build/mobile/link-settings/link-settings-screen.native.js +11 -5
  42. package/build/mobile/link-settings/link-settings-screen.native.js.map +1 -1
  43. package/build/mobile/picker/index.android.js +4 -2
  44. package/build/mobile/picker/index.android.js.map +1 -1
  45. package/build/modal/index.js +10 -3
  46. package/build/modal/index.js.map +1 -1
  47. package/build/navigation/group/index.js +1 -2
  48. package/build/navigation/group/index.js.map +1 -1
  49. package/build/navigation/menu/menu-title-search.js +8 -27
  50. package/build/navigation/menu/menu-title-search.js.map +1 -1
  51. package/build/navigation/menu/menu-title.js +2 -2
  52. package/build/navigation/menu/menu-title.js.map +1 -1
  53. package/build/navigation/styles/navigation-styles.js +34 -29
  54. package/build/navigation/styles/navigation-styles.js.map +1 -1
  55. package/build/popover/index.js +4 -2
  56. package/build/popover/index.js.map +1 -1
  57. package/build/range-control/styles/range-control-styles.js +33 -29
  58. package/build/range-control/styles/range-control-styles.js.map +1 -1
  59. package/build/search-control/index.js +37 -14
  60. package/build/search-control/index.js.map +1 -1
  61. package/build/text/styles.js +7 -7
  62. package/build/text/styles.js.map +1 -1
  63. package/build/tools-panel/styles.js +18 -23
  64. package/build/tools-panel/styles.js.map +1 -1
  65. package/build/tools-panel/tools-panel/component.js +10 -7
  66. package/build/tools-panel/tools-panel/component.js.map +1 -1
  67. package/build/tools-panel/tools-panel/hook.js +3 -1
  68. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  69. package/build/tools-panel/tools-panel-header/component.js +3 -0
  70. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  71. package/build/utils/hooks/index.js +8 -0
  72. package/build/utils/hooks/index.js.map +1 -1
  73. package/build/utils/hooks/use-combined-ref.js +28 -0
  74. package/build/utils/hooks/use-combined-ref.js.map +1 -0
  75. package/build-module/angle-picker-control/index.js +3 -1
  76. package/build-module/angle-picker-control/index.js.map +1 -1
  77. package/build-module/angle-picker-control/styles/angle-picker-control-styles.js +4 -4
  78. package/build-module/angle-picker-control/styles/angle-picker-control-styles.js.map +1 -1
  79. package/build-module/base-control/index.js +1 -1
  80. package/build-module/base-control/index.js.map +1 -1
  81. package/build-module/color-edit/index.js +175 -201
  82. package/build-module/color-edit/index.js.map +1 -1
  83. package/build-module/color-edit/styles.js +90 -0
  84. package/build-module/color-edit/styles.js.map +1 -0
  85. package/build-module/color-list-picker/index.js +6 -1
  86. package/build-module/color-list-picker/index.js.map +1 -1
  87. package/build-module/color-palette/index.js +85 -22
  88. package/build-module/color-palette/index.js.map +1 -1
  89. package/build-module/color-palette/styles.js +27 -0
  90. package/build-module/color-palette/styles.js.map +1 -0
  91. package/build-module/color-picker/component.js +7 -16
  92. package/build-module/color-picker/component.js.map +1 -1
  93. package/build-module/color-picker/picker.js +4 -4
  94. package/build-module/color-picker/picker.js.map +1 -1
  95. package/build-module/duotone-picker/custom-duotone-bar.js +0 -1
  96. package/build-module/duotone-picker/custom-duotone-bar.js.map +1 -1
  97. package/build-module/duotone-picker/duotone-picker.js +1 -0
  98. package/build-module/duotone-picker/duotone-picker.js.map +1 -1
  99. package/build-module/gradient-picker/index.js +67 -9
  100. package/build-module/gradient-picker/index.js.map +1 -1
  101. package/build-module/index.native.js +1 -0
  102. package/build-module/index.native.js.map +1 -1
  103. package/build-module/mobile/bottom-sheet/cell.native.js +4 -2
  104. package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
  105. package/build-module/mobile/bottom-sheet/link-cell.native.js +3 -2
  106. package/build-module/mobile/bottom-sheet/link-cell.native.js.map +1 -1
  107. package/build-module/mobile/link-settings/image-link-destinations-screen.native.js +121 -0
  108. package/build-module/mobile/link-settings/image-link-destinations-screen.native.js.map +1 -0
  109. package/build-module/mobile/link-settings/index.native.js +3 -2
  110. package/build-module/mobile/link-settings/index.native.js.map +1 -1
  111. package/build-module/mobile/link-settings/link-settings-navigation.native.js +1 -0
  112. package/build-module/mobile/link-settings/link-settings-navigation.native.js.map +1 -1
  113. package/build-module/mobile/link-settings/link-settings-screen.native.js +11 -5
  114. package/build-module/mobile/link-settings/link-settings-screen.native.js.map +1 -1
  115. package/build-module/mobile/picker/index.android.js +4 -2
  116. package/build-module/mobile/picker/index.android.js.map +1 -1
  117. package/build-module/modal/index.js +10 -4
  118. package/build-module/modal/index.js.map +1 -1
  119. package/build-module/navigation/group/index.js +1 -2
  120. package/build-module/navigation/group/index.js.map +1 -1
  121. package/build-module/navigation/menu/menu-title-search.js +8 -24
  122. package/build-module/navigation/menu/menu-title-search.js.map +1 -1
  123. package/build-module/navigation/menu/menu-title.js +3 -3
  124. package/build-module/navigation/menu/menu-title.js.map +1 -1
  125. package/build-module/navigation/styles/navigation-styles.js +31 -27
  126. package/build-module/navigation/styles/navigation-styles.js.map +1 -1
  127. package/build-module/popover/index.js +4 -2
  128. package/build-module/popover/index.js.map +1 -1
  129. package/build-module/range-control/styles/range-control-styles.js +33 -29
  130. package/build-module/range-control/styles/range-control-styles.js.map +1 -1
  131. package/build-module/search-control/index.js +36 -15
  132. package/build-module/search-control/index.js.map +1 -1
  133. package/build-module/text/styles.js +7 -7
  134. package/build-module/text/styles.js.map +1 -1
  135. package/build-module/tools-panel/styles.js +16 -23
  136. package/build-module/tools-panel/styles.js.map +1 -1
  137. package/build-module/tools-panel/tools-panel/component.js +10 -6
  138. package/build-module/tools-panel/tools-panel/component.js.map +1 -1
  139. package/build-module/tools-panel/tools-panel/hook.js +2 -1
  140. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  141. package/build-module/tools-panel/tools-panel-header/component.js +3 -0
  142. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  143. package/build-module/utils/hooks/index.js +1 -0
  144. package/build-module/utils/hooks/index.js.map +1 -1
  145. package/build-module/utils/hooks/use-combined-ref.js +25 -0
  146. package/build-module/utils/hooks/use-combined-ref.js.map +1 -0
  147. package/build-style/style-rtl.css +39 -51
  148. package/build-style/style.css +39 -51
  149. package/build-types/range-control/styles/range-control-styles.d.ts.map +1 -1
  150. package/build-types/tools-panel/styles.d.ts +1 -1
  151. package/build-types/tools-panel/styles.d.ts.map +1 -1
  152. package/build-types/tools-panel/tools-panel/component.d.ts.map +1 -1
  153. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  154. package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
  155. package/build-types/utils/hooks/index.d.ts +1 -0
  156. package/build-types/utils/hooks/use-combined-ref.d.ts +8 -0
  157. package/build-types/utils/hooks/use-combined-ref.d.ts.map +1 -0
  158. package/package.json +6 -6
  159. package/src/angle-picker-control/index.js +3 -1
  160. package/src/angle-picker-control/styles/angle-picker-control-styles.js +2 -2
  161. package/src/base-control/index.js +1 -1
  162. package/src/circular-option-picker/style.scss +3 -5
  163. package/src/color-edit/index.js +248 -274
  164. package/src/color-edit/style.scss +4 -45
  165. package/src/color-edit/styles.js +97 -0
  166. package/src/color-list-picker/index.js +5 -0
  167. package/src/color-list-picker/style.scss +4 -0
  168. package/src/color-palette/index.js +90 -26
  169. package/src/color-palette/style.scss +18 -0
  170. package/src/color-palette/styles.js +19 -0
  171. package/src/color-palette/test/__snapshots__/index.js.snap +448 -414
  172. package/src/color-picker/component.tsx +6 -17
  173. package/src/color-picker/picker.tsx +6 -4
  174. package/src/color-picker/test/index.js +0 -15
  175. package/src/duotone-picker/custom-duotone-bar.js +0 -1
  176. package/src/duotone-picker/duotone-picker.js +1 -0
  177. package/src/gradient-picker/index.js +79 -11
  178. package/src/heading/test/__snapshots__/index.js.snap +1 -1
  179. package/src/index.native.js +1 -0
  180. package/src/mobile/bottom-sheet/cell.native.js +7 -2
  181. package/src/mobile/bottom-sheet/cellStyles.android.scss +5 -1
  182. package/src/mobile/bottom-sheet/cellStyles.ios.scss +5 -1
  183. package/src/mobile/bottom-sheet/link-cell.native.js +10 -3
  184. package/src/mobile/link-settings/image-link-destinations-screen.native.js +148 -0
  185. package/src/mobile/link-settings/index.native.js +3 -2
  186. package/src/mobile/link-settings/link-settings-navigation.native.js +1 -0
  187. package/src/mobile/link-settings/link-settings-screen.native.js +6 -2
  188. package/src/mobile/link-settings/style.native.scss +17 -0
  189. package/src/mobile/picker/index.android.js +2 -1
  190. package/src/modal/README.md +8 -0
  191. package/src/modal/index.js +60 -45
  192. package/src/modal/style.scss +5 -0
  193. package/src/navigation/group/index.js +1 -2
  194. package/src/navigation/menu/menu-title-search.js +11 -26
  195. package/src/navigation/menu/menu-title.js +4 -4
  196. package/src/navigation/styles/navigation-styles.js +29 -52
  197. package/src/popover/index.js +2 -2
  198. package/src/range-control/styles/range-control-styles.js +4 -1
  199. package/src/resizable-box/style.scss +5 -0
  200. package/src/search-control/index.js +47 -23
  201. package/src/style.scss +1 -0
  202. package/src/text/styles.js +1 -1
  203. package/src/text/test/__snapshots__/index.js.snap +2 -2
  204. package/src/tools-panel/stories/index.js +21 -19
  205. package/src/tools-panel/styles.ts +18 -26
  206. package/src/tools-panel/tools-panel/component.tsx +7 -4
  207. package/src/tools-panel/tools-panel/hook.ts +4 -1
  208. package/src/tools-panel/tools-panel-header/component.tsx +1 -0
  209. package/src/ui/control-label/test/__snapshots__/index.js.snap +3 -3
  210. package/src/ui/form-group/test/__snapshots__/index.js.snap +2 -2
  211. package/src/utils/hooks/index.js +1 -0
  212. package/src/utils/hooks/use-combined-ref.ts +29 -0
  213. package/tsconfig.tsbuildinfo +1 -1
@@ -11,10 +11,10 @@ $color-palette-circle-spacing: 12px;
11
11
  justify-content: flex-end;
12
12
  }
13
13
 
14
- // Effectively negates the end swatch spacing to keep the swatches
15
- // from wrapping before necessary.
16
14
  .components-circular-option-picker__swatches {
17
- margin-right: -$color-palette-circle-spacing;
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ gap: $color-palette-circle-spacing;
18
18
  }
19
19
  }
20
20
 
@@ -22,8 +22,6 @@ $color-palette-circle-spacing: 12px;
22
22
  display: inline-block;
23
23
  height: $color-palette-circle-size;
24
24
  width: $color-palette-circle-size;
25
- margin-right: $color-palette-circle-spacing;
26
- margin-bottom: $color-palette-circle-spacing;
27
25
  vertical-align: top;
28
26
  transform: scale(1);
29
27
  transition: 100ms transform ease;
@@ -1,326 +1,300 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import classnames from 'classnames';
5
- import { isEmpty, kebabCase } from 'lodash';
4
+ import kebabCase from 'lodash';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
9
8
  */
10
- import { __, sprintf } from '@wordpress/i18n';
11
- import { useEffect, useState } from '@wordpress/element';
12
- import { edit, close, chevronDown, chevronUp, plus } from '@wordpress/icons';
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
13
 
14
14
  /**
15
15
  * Internal dependencies
16
16
  */
17
- import Dropdown from '../dropdown';
18
- import CircularOptionPicker from '../circular-option-picker';
19
- import { ColorPicker } from '../color-picker';
20
17
  import Button from '../button';
21
- import TextControl from '../text-control';
22
- import BaseControl from '../base-control';
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 ColorPalette from '../color-palette';
24
+ import DropdownMenu from '../dropdown-menu';
25
+ import Popover from '../popover';
26
+ import {
27
+ ColorActionsContainer,
28
+ ColorEditStyles,
29
+ ColorHeading,
30
+ ColorHStackHeader,
31
+ ColorIndicatorStyled,
32
+ ColorItem,
33
+ ColorNameContainer,
34
+ ColorNameInputControl,
35
+ DoneButton,
36
+ RemoveButton,
37
+ } from './styles';
38
+ import { NavigableMenu } from '../navigable-container';
23
39
 
24
- function DropdownOpenOnMount( { shouldOpen, isOpen, onToggle } ) {
25
- useEffect( () => {
26
- if ( shouldOpen && ! isOpen ) {
27
- onToggle();
28
- }
29
- }, [] );
30
- return null;
40
+ function ColorNameInput( { value, onChange } ) {
41
+ return (
42
+ <ColorNameInputControl
43
+ label={ __( 'Color name' ) }
44
+ hideLabelFromVision
45
+ value={ value }
46
+ onChange={ onChange }
47
+ />
48
+ );
31
49
  }
32
50
 
33
51
  function ColorOption( {
34
52
  color,
35
- name,
36
- slug,
37
53
  onChange,
54
+ isEditing,
55
+ onStartEditing,
38
56
  onRemove,
39
- onConfirm,
40
- confirmLabel = __( 'OK' ),
41
- isEditingNameOnMount = false,
42
- isEditingColorOnMount = false,
43
- onCancel,
44
- immutableColorSlugs = [],
57
+ onStopEditing,
45
58
  } ) {
46
- const [ isHover, setIsHover ] = useState( false );
47
- const [ isFocused, setIsFocused ] = useState( false );
48
- const [ isEditingName, setIsEditingName ] = useState(
49
- isEditingNameOnMount
50
- );
51
- const [ isShowingAdvancedPanel, setIsShowingAdvancedPanel ] = useState(
52
- false
53
- );
54
-
55
- const isShowingControls =
56
- ( isHover || isFocused || isEditingName || isShowingAdvancedPanel ) &&
57
- ! immutableColorSlugs.includes( slug );
58
-
59
+ const focusOutsideProps = useFocusOutside( onStopEditing );
59
60
  return (
60
- <div
61
- tabIndex={ 0 }
62
- className={ classnames( 'components-color-edit__color-option', {
63
- 'is-hover':
64
- isHover && ! isEditingName && ! isShowingAdvancedPanel,
65
- } ) }
66
- onMouseEnter={ () => setIsHover( true ) }
67
- onMouseLeave={ () => setIsHover( false ) }
68
- onFocus={ () => setIsFocused( true ) }
69
- onBlur={ () => setIsFocused( false ) }
70
- aria-label={
71
- name
72
- ? // translators: %s: The name of the color e.g: "vivid red".
73
- sprintf( __( 'Color: %s' ), name )
74
- : // translators: %s: color hex code e.g: "#f00".
75
- sprintf( __( 'Color code: %s' ), color )
76
- }
61
+ <ColorItem
62
+ as="div"
63
+ onClick={ onStartEditing }
64
+ { ...( isEditing ? focusOutsideProps : {} ) }
77
65
  >
78
- <div className="components-color-edit__color-option-main-area">
79
- <Dropdown
80
- renderToggle={ ( { isOpen, onToggle } ) => (
81
- <>
82
- <DropdownOpenOnMount
83
- shouldOpen={ isEditingColorOnMount }
84
- isOpen={ isOpen }
85
- onToggle={ onToggle }
86
- />
87
- <CircularOptionPicker.Option
88
- style={ { backgroundColor: color, color } }
89
- aria-expanded={ isOpen }
90
- aria-haspopup="true"
91
- onClick={ onToggle }
92
- aria-label={ __( 'Edit color value' ) }
93
- />
94
- </>
95
- ) }
96
- renderContent={ () => (
97
- <ColorPicker
98
- color={ color }
99
- onChange={ ( newColor ) =>
66
+ <HStack justify="flex-start">
67
+ <FlexItem>
68
+ <ColorIndicatorStyled colorValue={ color.color } />
69
+ </FlexItem>
70
+ <FlexItem>
71
+ { isEditing ? (
72
+ <ColorNameInput
73
+ value={ color.name }
74
+ onChange={ ( nextName ) =>
100
75
  onChange( {
101
- color: newColor,
102
- slug,
103
- name,
76
+ ...color,
77
+ name: nextName,
78
+ slug: kebabCase( nextName ),
104
79
  } )
105
80
  }
106
81
  />
82
+ ) : (
83
+ <ColorNameContainer>{ color.name }</ColorNameContainer>
107
84
  ) }
108
- />
109
- { ! isEditingName && (
110
- <div className="components-color-edit__color-option-color-name">
111
- { name }
112
- </div>
113
- ) }
114
- { isEditingName && (
115
- <>
116
- <TextControl
117
- className="components-color-edit__color-option-color-name-input"
118
- hideLabelFromVision
119
- onChange={ ( newColorName ) =>
120
- onChange( {
121
- color,
122
- slug: kebabCase( newColorName ),
123
- name: newColorName,
124
- } )
125
- }
126
- label={ __( 'Color name' ) }
127
- placeholder={ __( 'Name' ) }
128
- value={ name }
129
- />
130
- <Button
131
- onClick={ () => {
132
- setIsEditingName( false );
133
- setIsFocused( false );
134
- if ( onConfirm ) {
135
- onConfirm();
136
- }
137
- } }
138
- variant="primary"
139
- >
140
- { confirmLabel }
141
- </Button>
142
- </>
143
- ) }
144
- { ! isEditingName && (
145
- <>
146
- <Button
147
- className={ classnames( {
148
- 'components-color-edit__hidden-control': ! isShowingControls,
149
- } ) }
150
- icon={ edit }
151
- label={ __( 'Edit color name' ) }
152
- onClick={ () => setIsEditingName( true ) }
153
- />
154
- <Button
155
- className={ classnames( {
156
- 'components-color-edit__hidden-control': ! isShowingControls,
157
- } ) }
158
- icon={ close }
85
+ </FlexItem>
86
+ { isEditing && (
87
+ <FlexItem>
88
+ <RemoveButton
89
+ isSmall
90
+ icon={ lineSolid }
159
91
  label={ __( 'Remove color' ) }
160
92
  onClick={ onRemove }
161
93
  />
162
- </>
94
+ </FlexItem>
163
95
  ) }
164
- <Button
165
- className={ classnames( {
166
- 'components-color-edit__hidden-control': ! isShowingControls,
167
- } ) }
168
- icon={ isShowingAdvancedPanel ? chevronUp : chevronDown }
169
- label={ __( 'Additional color settings' ) }
170
- onClick={ () => {
171
- if ( isShowingAdvancedPanel ) {
172
- setIsFocused( false );
173
- }
174
- setIsShowingAdvancedPanel( ! isShowingAdvancedPanel );
175
- } }
176
- aria-expanded={ isShowingAdvancedPanel }
177
- />
178
- </div>
179
- { onCancel && (
180
- <Button
181
- className="components-color-edit__cancel-button"
182
- onClick={ onCancel }
96
+ </HStack>
97
+ { isEditing && (
98
+ <Popover
99
+ position="bottom left"
100
+ className="components-color-edit__color-popover"
183
101
  >
184
- { __( 'Cancel' ) }
185
- </Button>
186
- ) }
187
- { isShowingAdvancedPanel && (
188
- <TextControl
189
- className="components-color-edit__slug-input"
190
- onChange={ ( newSlug ) =>
191
- onChange( {
192
- color,
193
- slug: newSlug,
194
- name,
195
- } )
196
- }
197
- label={ __( 'Slug' ) }
198
- value={ slug }
199
- />
102
+ <ColorPicker
103
+ color={ color.color }
104
+ onChange={ ( newColor ) =>
105
+ onChange( {
106
+ ...color,
107
+ color: newColor,
108
+ } )
109
+ }
110
+ />
111
+ </Popover>
200
112
  ) }
201
- </div>
113
+ </ColorItem>
202
114
  );
203
115
  }
204
116
 
205
- function ColorInserter( { onInsert, onCancel } ) {
206
- const [ color, setColor ] = useState( {
207
- color: '#fff',
208
- name: '',
209
- slug: '',
210
- } );
117
+ function ColorPaletteEditListView( {
118
+ colors,
119
+ onChange,
120
+ editingColor,
121
+ setEditingColor,
122
+ } ) {
123
+ // When unmounting the component if there are empty colors (the user did not complete the insertion) clean them.
124
+ const colorReference = useRef();
125
+ useEffect( () => {
126
+ colorReference.current = colors;
127
+ }, [ colors ] );
128
+ useEffect( () => {
129
+ return () => {
130
+ if ( colorReference.current.some( ( { slug } ) => ! slug ) ) {
131
+ const newColors = colorReference.current.filter(
132
+ ( { slug } ) => slug
133
+ );
134
+ onChange( newColors.length ? newColors : undefined );
135
+ }
136
+ };
137
+ }, [] );
211
138
  return (
212
- <ColorOption
213
- color={ color.color }
214
- name={ color.name }
215
- slug={ color.slug }
216
- onChange={ setColor }
217
- confirmLabel={ __( 'Save' ) }
218
- onConfirm={ () => onInsert( color ) }
219
- isEditingNameOnMount
220
- isEditingColorOnMount
221
- onCancel={ onCancel }
222
- />
139
+ <VStack spacing={ 3 }>
140
+ <ItemGroup isBordered isSeparated>
141
+ { colors.map( ( color, index ) => (
142
+ <ColorOption
143
+ key={ index }
144
+ color={ color }
145
+ onStartEditing={ () => {
146
+ if ( editingColor !== index ) {
147
+ setEditingColor( index );
148
+ }
149
+ } }
150
+ onChange={ ( newColor ) => {
151
+ onChange(
152
+ colors.map( ( currentColor, currentIndex ) => {
153
+ if ( currentIndex === index ) {
154
+ return newColor;
155
+ }
156
+ return currentColor;
157
+ } )
158
+ );
159
+ } }
160
+ onRemove={ () => {
161
+ setEditingColor( null );
162
+ const newColors = colors.filter(
163
+ ( _currentColor, currentIndex ) => {
164
+ if ( currentIndex === index ) {
165
+ return false;
166
+ }
167
+ return true;
168
+ }
169
+ );
170
+ onChange(
171
+ newColors.length ? newColors : undefined
172
+ );
173
+ } }
174
+ isEditing={ index === editingColor }
175
+ onStopEditing={ () => {
176
+ if ( index === editingColor ) {
177
+ setEditingColor( null );
178
+ }
179
+ } }
180
+ />
181
+ ) ) }
182
+ </ItemGroup>
183
+ </VStack>
223
184
  );
224
185
  }
225
186
 
226
- export default function ColorEdit( {
227
- colors,
228
- onChange,
229
- emptyUI,
230
- immutableColorSlugs,
231
- canReset = true,
232
- } ) {
233
- const [ isInsertingColor, setIsInsertingColor ] = useState( false );
187
+ const EMPTY_ARRAY = [];
188
+
189
+ export default function ColorEdit( { colors = EMPTY_ARRAY, onChange } ) {
190
+ const [ isEditing, setIsEditing ] = useState( false );
191
+ const [ editingColor, setEditingColor ] = useState( null );
192
+ const isAdding =
193
+ isEditing &&
194
+ editingColor &&
195
+ colors[ editingColor ] &&
196
+ ! colors[ editingColor ].slug;
197
+
198
+ const hasColors = colors.length > 0;
199
+
234
200
  return (
235
- <BaseControl>
236
- <fieldset>
237
- <div className="components-color-edit__label-and-insert-container">
238
- <legend>
239
- <div>
240
- <BaseControl.VisualLabel>
241
- { __( 'Color palette' ) }
242
- </BaseControl.VisualLabel>
243
- </div>
244
- </legend>
245
- { ! isInsertingColor && (
201
+ <ColorEditStyles>
202
+ <ColorHStackHeader>
203
+ <ColorHeading>{ __( 'Custom' ) }</ColorHeading>
204
+ <ColorActionsContainer>
205
+ { isEditing && (
206
+ <DoneButton
207
+ isSmall
208
+ onClick={ () => {
209
+ setIsEditing( false );
210
+ setEditingColor( null );
211
+ } }
212
+ >
213
+ { __( 'Done' ) }
214
+ </DoneButton>
215
+ ) }
216
+ <Button
217
+ isSmall
218
+ isPressed={ isAdding }
219
+ icon={ plus }
220
+ label={ __( 'Add custom color' ) }
221
+ onClick={ () => {
222
+ onChange( [
223
+ ...colors,
224
+ {
225
+ color: '#000',
226
+ name: '',
227
+ slug: '',
228
+ },
229
+ ] );
230
+ setIsEditing( true );
231
+ setEditingColor( colors.length );
232
+ } }
233
+ />
234
+ { ! isEditing && (
246
235
  <Button
236
+ disabled={ ! hasColors }
237
+ isSmall
238
+ icon={ moreVertical }
239
+ label={ __( 'Edit colors' ) }
247
240
  onClick={ () => {
248
- setIsInsertingColor( true );
241
+ setIsEditing( true );
249
242
  } }
250
- className="components-color-edit__insert-button"
251
- icon={ plus }
252
243
  />
253
244
  ) }
254
- </div>
255
- <div>
256
- { ! isEmpty( colors ) &&
257
- colors.map( ( color, index ) => {
258
- return (
259
- <ColorOption
260
- key={ index }
261
- color={ color.color }
262
- name={ color.name }
263
- slug={ color.slug }
264
- immutableColorSlugs={ immutableColorSlugs }
265
- onChange={ ( newColor ) => {
266
- onChange(
267
- colors.map(
268
- (
269
- currentColor,
270
- currentIndex
271
- ) => {
272
- if (
273
- currentIndex === index
274
- ) {
275
- return newColor;
276
- }
277
- return currentColor;
278
- }
279
- )
280
- );
281
- } }
282
- onRemove={ () => {
283
- onChange(
284
- colors.filter(
285
- (
286
- _currentColor,
287
- currentIndex
288
- ) => {
289
- if (
290
- currentIndex === index
291
- ) {
292
- return false;
293
- }
294
- return true;
295
- }
296
- )
297
- );
298
- } }
299
- />
300
- );
301
- } ) }
302
- { isInsertingColor && (
303
- <ColorInserter
304
- onInsert={ ( newColor ) => {
305
- setIsInsertingColor( false );
306
- onChange( [ ...( colors || [] ), newColor ] );
245
+ { isEditing && (
246
+ <DropdownMenu
247
+ icon={ moreVertical }
248
+ label={ __( 'Custom color options' ) }
249
+ toggleProps={ {
250
+ isSmall: true,
307
251
  } }
308
- onCancel={ () => setIsInsertingColor( false ) }
252
+ >
253
+ { ( { onClose } ) => (
254
+ <>
255
+ <NavigableMenu role="menu">
256
+ <Button
257
+ variant="tertiary"
258
+ onClick={ () => {
259
+ setEditingColor( null );
260
+ setIsEditing( false );
261
+ onChange();
262
+ onClose();
263
+ } }
264
+ >
265
+ { __( 'Remove all custom colors' ) }
266
+ </Button>
267
+ </NavigableMenu>
268
+ </>
269
+ ) }
270
+ </DropdownMenu>
271
+ ) }
272
+ </ColorActionsContainer>
273
+ </ColorHStackHeader>
274
+ { hasColors && (
275
+ <>
276
+ { isEditing && (
277
+ <ColorPaletteEditListView
278
+ colors={ colors }
279
+ onChange={ onChange }
280
+ editingColor={ editingColor }
281
+ setEditingColor={ setEditingColor }
309
282
  />
310
283
  ) }
311
- { ! isInsertingColor && isEmpty( colors ) && emptyUI }
312
- </div>
313
- { !! canReset && (
314
- <Button
315
- isSmall
316
- variant="secondary"
317
- className="components-color-edit__reset-button"
318
- onClick={ () => onChange() }
319
- >
320
- { __( 'Reset' ) }
321
- </Button>
284
+ { ! isEditing && (
285
+ <ColorPalette
286
+ colors={ colors }
287
+ onChange={ () => {} }
288
+ clearable={ false }
289
+ disableCustomColors={ true }
290
+ />
291
+ ) }
292
+ </>
293
+ ) }
294
+ { ! hasColors &&
295
+ __(
296
+ 'Custom colors are empty! Add some colors to create your own color palette.'
322
297
  ) }
323
- </fieldset>
324
- </BaseControl>
298
+ </ColorEditStyles>
325
299
  );
326
300
  }
@@ -1,47 +1,6 @@
1
- .components-color-edit__color-option-main-area {
2
- display: flex;
3
- align-items: center;
4
- div.components-circular-option-picker__option-wrapper {
5
- display: block;
6
- margin: $grid-unit-10;
1
+ @include break-medium() {
2
+ .components-color-edit__color-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) };
7
5
  }
8
6
  }
9
-
10
- .components-color-edit__color-option.is-hover {
11
- background: $gray-200;
12
- }
13
-
14
- .components-color-edit__cancel-button {
15
- float: right;
16
- }
17
-
18
- .components-color-edit__color-option-color-name {
19
- width: 100%;
20
- }
21
- .components-color-edit__label-and-insert-container {
22
- display: flex;
23
- align-items: center;
24
- justify-content: space-between;
25
- }
26
-
27
- .components-color-edit__insert-button {
28
- margin-top: -$grid-unit-10;
29
- }
30
-
31
- .components-color-edit__hidden-control {
32
- position: relative;
33
- left: -9999px;
34
- }
35
-
36
- .components-color-edit__color-option-color-name-input .components-base-control__field {
37
- margin-bottom: 0;
38
- margin-right: $grid-unit-10;
39
- }
40
-
41
- .components-color-edit__slug-input {
42
- margin-left: $grid-unit-10;
43
- }
44
-
45
- .components-color-edit__reset-button {
46
- float: right;
47
- }