@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,7 +11,6 @@ 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';
15
14
  import { __ } from '@wordpress/i18n';
16
15
 
17
16
  /**
@@ -33,7 +32,6 @@ import {
33
32
  import { ColorDisplay } from './color-display';
34
33
  import { ColorInput } from './color-input';
35
34
  import { Picker } from './picker';
36
- import { useControlledValue } from '../utils/hooks';
37
35
 
38
36
  import type { ColorType } from './types';
39
37
 
@@ -59,32 +57,23 @@ const ColorPicker = (
59
57
  ) => {
60
58
  const {
61
59
  enableAlpha = false,
62
- color: colorProp,
60
+ color,
63
61
  onChange,
64
- defaultValue,
62
+ defaultValue = '#fff',
65
63
  copyFormat,
66
64
  ...divProps
67
65
  } = useContextSystem( props, 'ColorPicker' );
68
66
 
69
- const [ color, setColor ] = useControlledValue( {
70
- onChange,
71
- value: colorProp,
72
- defaultValue,
73
- } );
74
-
75
67
  // Use a safe default value for the color and remove the possibility of `undefined`.
76
68
  const safeColordColor = useMemo( () => {
77
- return color ? colord( color ) : colord( '#fff' );
78
- }, [ color ] );
79
-
80
- // Debounce to prevent rapid changes from conflicting with one another.
81
- const debouncedSetColor = useDebounce( setColor );
69
+ return color ? colord( color ) : colord( defaultValue );
70
+ }, [ color, defaultValue ] );
82
71
 
83
72
  const handleChange = useCallback(
84
73
  ( nextValue: Colord ) => {
85
- debouncedSetColor( nextValue.toHex() );
74
+ onChange( nextValue.toHex() );
86
75
  },
87
- [ debouncedSetColor ]
76
+ [ onChange ]
88
77
  );
89
78
 
90
79
  const [ showInputs, setShowInputs ] = useState< boolean >( false );
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { HslColorPicker, HslaColorPicker } from 'react-colorful';
4
+ import { RgbStringColorPicker, RgbaStringColorPicker } from 'react-colorful';
5
5
  import { colord, Colord } from 'colord';
6
6
 
7
7
  /**
@@ -15,12 +15,14 @@ interface PickerProps {
15
15
  }
16
16
 
17
17
  export const Picker = ( { color, enableAlpha, onChange }: PickerProps ) => {
18
- const Component = enableAlpha ? HslaColorPicker : HslColorPicker;
19
- const hslColor = useMemo( () => color.toHsl(), [ color ] );
18
+ const Component = enableAlpha
19
+ ? RgbaStringColorPicker
20
+ : RgbStringColorPicker;
21
+ const rgbColor = useMemo( () => color.toRgbString(), [ color ] );
20
22
 
21
23
  return (
22
24
  <Component
23
- color={ hslColor }
25
+ color={ rgbColor }
24
26
  onChange={ ( nextColor ) => {
25
27
  onChange( colord( nextColor ) );
26
28
  } }
@@ -41,12 +41,6 @@ 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
-
50
44
  const hslaMatcher = expect.objectContaining( {
51
45
  h: expect.any( Number ),
52
46
  s: expect.any( Number ),
@@ -93,9 +87,6 @@ describe( 'ColorPicker', () => {
93
87
  { pageX: 10, pageY: 10 }
94
88
  );
95
89
 
96
- // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
97
- await sleep( 1 );
98
-
99
90
  expect( onChangeComplete ).toHaveBeenCalledWith(
100
91
  legacyColorMatcher
101
92
  );
@@ -117,9 +108,6 @@ describe( 'ColorPicker', () => {
117
108
  { pageX: 10, pageY: 10 }
118
109
  );
119
110
 
120
- // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
121
- await sleep( 1 );
122
-
123
111
  expect( onChange ).toHaveBeenCalledWith(
124
112
  expect.stringMatching( /^#([a-fA-F0-9]{8})$/ )
125
113
  );
@@ -150,9 +138,6 @@ describe( 'ColorPicker', () => {
150
138
  { pageX: 10, pageY: 10 }
151
139
  );
152
140
 
153
- // `onChange` is debounced so we need to sleep for at least 1ms before checking that onChange was called
154
- await sleep( 1 );
155
-
156
141
  expect( onChange ).toHaveBeenCalledWith(
157
142
  expect.stringMatching( /^#([a-fA-F0-9]{6})$/ )
158
143
  );
@@ -19,7 +19,6 @@ export default function CustomDuotoneBar( { value, onChange } ) {
19
19
  return (
20
20
  <CustomGradientBar
21
21
  disableInserter
22
- disableAlpha
23
22
  background={ background }
24
23
  hasGradient={ hasGradient }
25
24
  value={ controlPoints }
@@ -85,6 +85,7 @@ function DuotonePicker( {
85
85
  colors={ colorPalette }
86
86
  value={ value }
87
87
  disableCustomColors={ disableCustomColors }
88
+ enableAlpha
88
89
  onChange={ ( newColors ) => {
89
90
  if ( ! newColors[ 0 ] ) {
90
91
  newColors[ 0 ] = defaultDark;
@@ -14,18 +14,18 @@ import { useCallback, useMemo } from '@wordpress/element';
14
14
  */
15
15
  import CircularOptionPicker from '../circular-option-picker';
16
16
  import CustomGradientPicker from '../custom-gradient-picker';
17
+ import { VStack } from '../v-stack';
18
+ import { ColorHeading } from '../color-palette/styles';
17
19
 
18
- export default function GradientPicker( {
20
+ function SingleOrigin( {
19
21
  className,
22
+ clearGradient,
20
23
  gradients,
21
24
  onChange,
22
25
  value,
23
- clearable = true,
24
- disableCustomGradients = false,
26
+ actions,
27
+ content,
25
28
  } ) {
26
- const clearGradient = useCallback( () => onChange( undefined ), [
27
- onChange,
28
- ] );
29
29
  const gradientOptions = useMemo( () => {
30
30
  return map( gradients, ( { gradient, name } ) => (
31
31
  <CircularOptionPicker.Option
@@ -57,6 +57,70 @@ export default function GradientPicker( {
57
57
  <CircularOptionPicker
58
58
  className={ className }
59
59
  options={ gradientOptions }
60
+ actions={ actions }
61
+ >
62
+ { content }
63
+ </CircularOptionPicker>
64
+ );
65
+ }
66
+
67
+ function MultipleOrigin( {
68
+ className,
69
+ clearGradient,
70
+ gradients,
71
+ onChange,
72
+ value,
73
+ actions,
74
+ content,
75
+ } ) {
76
+ return (
77
+ <VStack spacing={ 3 } className={ className }>
78
+ { gradients.map( ( { name, gradients: gradientSet }, index ) => {
79
+ return (
80
+ <VStack spacing={ 2 } key={ index }>
81
+ <ColorHeading>{ name }</ColorHeading>
82
+ <SingleOrigin
83
+ clearGradient={ clearGradient }
84
+ gradients={ gradientSet }
85
+ onChange={ onChange }
86
+ value={ value }
87
+ { ...( gradients.length === index + 1
88
+ ? {
89
+ actions,
90
+ content,
91
+ }
92
+ : {} ) }
93
+ />
94
+ </VStack>
95
+ );
96
+ } ) }
97
+ </VStack>
98
+ );
99
+ }
100
+
101
+ export default function GradientPicker( {
102
+ className,
103
+ gradients,
104
+ onChange,
105
+ value,
106
+ clearable = true,
107
+ disableCustomGradients = false,
108
+ __experimentalHasMultipleOrigins,
109
+ } ) {
110
+ const clearGradient = useCallback( () => onChange( undefined ), [
111
+ onChange,
112
+ ] );
113
+ const Component = __experimentalHasMultipleOrigins
114
+ ? MultipleOrigin
115
+ : SingleOrigin;
116
+ return (
117
+ <Component
118
+ className={ className }
119
+ clearable={ clearable }
120
+ clearGradient={ clearGradient }
121
+ gradients={ gradients }
122
+ onChange={ onChange }
123
+ value={ value }
60
124
  actions={
61
125
  clearable && (
62
126
  <CircularOptionPicker.ButtonAction
@@ -66,10 +130,14 @@ export default function GradientPicker( {
66
130
  </CircularOptionPicker.ButtonAction>
67
131
  )
68
132
  }
69
- >
70
- { ! disableCustomGradients && (
71
- <CustomGradientPicker value={ value } onChange={ onChange } />
72
- ) }
73
- </CircularOptionPicker>
133
+ content={
134
+ ! disableCustomGradients && (
135
+ <CustomGradientPicker
136
+ value={ value }
137
+ onChange={ onChange }
138
+ />
139
+ )
140
+ }
141
+ />
74
142
  );
75
143
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`props should render correctly 1`] = `
4
4
  .emotion-0 {
5
- color: #000;
5
+ color: #1e1e1e;
6
6
  line-height: 1.2;
7
7
  margin: 0;
8
8
  color: #050505;
@@ -103,6 +103,7 @@ export { default as LinkPickerScreen } from './mobile/link-picker/link-picker-sc
103
103
  export { default as LinkSettings } from './mobile/link-settings';
104
104
  export { default as LinkSettingsScreen } from './mobile/link-settings/link-settings-screen';
105
105
  export { default as LinkSettingsNavigation } from './mobile/link-settings/link-settings-navigation';
106
+ export { default as ImageLinkDestinationsScreen } from './mobile/link-settings/image-link-destinations-screen';
106
107
  export { default as SegmentedControl } from './mobile/segmented-control';
107
108
  export { default as Image, IMAGE_DEFAULT_FOCAL_POINT } from './mobile/image';
108
109
  export { default as ImageEditingButton } from './mobile/image/image-editing-button';
@@ -106,6 +106,7 @@ class BottomSheetCell extends Component {
106
106
  valuePlaceholder = '',
107
107
  icon,
108
108
  leftAlign,
109
+ iconStyle = {},
109
110
  labelStyle = {},
110
111
  valueStyle = {},
111
112
  cellContainerStyle = {},
@@ -307,7 +308,7 @@ class BottomSheetCell extends Component {
307
308
  );
308
309
  };
309
310
 
310
- const iconStyle = getStylesFromColorScheme(
311
+ const iconStyleBase = getStylesFromColorScheme(
311
312
  styles.icon,
312
313
  styles.iconDark
313
314
  );
@@ -362,7 +363,11 @@ class BottomSheetCell extends Component {
362
363
  <Icon
363
364
  icon={ icon }
364
365
  size={ 24 }
365
- fill={ iconStyle.color }
366
+ fill={
367
+ iconStyle.color ||
368
+ iconStyleBase.color
369
+ }
370
+ style={ iconStyle }
366
371
  isPressed={ false }
367
372
  />
368
373
  <View
@@ -7,5 +7,9 @@
7
7
  }
8
8
 
9
9
  .isSelected {
10
- color: $blue-wordpress;
10
+ color: $blue-50;
11
+ }
12
+
13
+ .isSelectedDark {
14
+ color: $blue-30;
11
15
  }
@@ -7,7 +7,11 @@
7
7
  }
8
8
 
9
9
  .isSelected {
10
- color: $blue-wordpress;
10
+ color: $blue-50;
11
+ }
12
+
13
+ .isSelectedDark {
14
+ color: $blue-30;
11
15
  }
12
16
 
13
17
  .activeOpacity {
@@ -12,14 +12,21 @@ import styles from './styles.scss';
12
12
 
13
13
  const { placeholderColor } = styles;
14
14
 
15
- export default function LinkCell( { value, onPress, showIcon = true } ) {
15
+ export default function LinkCell( {
16
+ value,
17
+ valueMask,
18
+ onPress,
19
+ showIcon = true,
20
+ } ) {
16
21
  return (
17
22
  <Cell
18
23
  icon={ showIcon && link }
19
24
  label={ __( 'Link to' ) }
20
25
  // since this is not actually editable, we treat value as a placeholder
21
- value={ value || __( 'Search or type URL' ) }
22
- valueStyle={ !! value ? undefined : placeholderColor }
26
+ value={ valueMask || value || __( 'Search or type URL' ) }
27
+ valueStyle={
28
+ !! ( value || valueMask ) ? undefined : placeholderColor
29
+ }
23
30
  onPress={ onPress }
24
31
  >
25
32
  <Icon icon={ chevronRight }></Icon>
@@ -0,0 +1,148 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { useNavigation, useRoute } from '@react-navigation/native';
5
+ import { StyleSheet } from 'react-native';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { __ } from '@wordpress/i18n';
11
+ import { Icon, check, chevronRight } from '@wordpress/icons';
12
+ import { blockSettingsScreens } from '@wordpress/block-editor';
13
+ import { usePreferredColorSchemeStyle } from '@wordpress/compose';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import styles from './style.scss';
19
+ import PanelBody from '../../panel/body';
20
+ import BottomSheet from '../bottom-sheet';
21
+
22
+ const LINK_DESTINATION_NONE = 'none';
23
+ const LINK_DESTINATION_MEDIA = 'media';
24
+ const LINK_DESTINATION_ATTACHMENT = 'attachment';
25
+ const LINK_DESTINATION_CUSTOM = 'custom';
26
+
27
+ function LinkDestination( {
28
+ children,
29
+ isSelected,
30
+ label,
31
+ onPress,
32
+ value,
33
+ valueStyle,
34
+ } ) {
35
+ const optionIcon = usePreferredColorSchemeStyle(
36
+ styles.optionIcon,
37
+ styles.optionIconDark
38
+ );
39
+ return (
40
+ <BottomSheet.Cell
41
+ icon={ check }
42
+ iconStyle={ StyleSheet.flatten( [
43
+ optionIcon,
44
+ ! isSelected && styles.unselectedOptionIcon,
45
+ ] ) }
46
+ label={ label }
47
+ leftAlign
48
+ onPress={ onPress }
49
+ value={ value }
50
+ valueStyle={ valueStyle }
51
+ separatorType="leftMargin"
52
+ >
53
+ { children }
54
+ </BottomSheet.Cell>
55
+ );
56
+ }
57
+
58
+ function ImageLinkDestinationsScreen( props ) {
59
+ const navigation = useNavigation();
60
+ const route = useRoute();
61
+ const { url = '' } = props;
62
+ const { inputValue = url, imageUrl, attachmentPageUrl, linkDestination } =
63
+ route.params || {};
64
+
65
+ function goToLinkPicker() {
66
+ navigation.navigate( blockSettingsScreens.linkPicker, {
67
+ inputValue:
68
+ linkDestination === LINK_DESTINATION_CUSTOM ? inputValue : '',
69
+ } );
70
+ }
71
+
72
+ const setLinkDestination = ( newLinkDestination ) => () => {
73
+ let newUrl;
74
+ switch ( newLinkDestination ) {
75
+ case LINK_DESTINATION_MEDIA:
76
+ newUrl = imageUrl;
77
+ break;
78
+ case LINK_DESTINATION_ATTACHMENT:
79
+ newUrl = attachmentPageUrl;
80
+ break;
81
+ default:
82
+ newUrl = '';
83
+ break;
84
+ }
85
+
86
+ navigation.navigate( blockSettingsScreens.settings, {
87
+ // The `inputValue` name is reused from LinkPicker, as it helps avoid
88
+ // bugs from stale values remaining in the React Navigation route
89
+ // parameters
90
+ inputValue: newUrl,
91
+ // Clear link text value that may be set from LinkPicker
92
+ text: '',
93
+ } );
94
+ };
95
+
96
+ return (
97
+ <>
98
+ <BottomSheet.NavBar>
99
+ <BottomSheet.NavBar.BackButton onPress={ navigation.goBack } />
100
+ <BottomSheet.NavBar.Heading>
101
+ { __( 'Link To' ) }
102
+ </BottomSheet.NavBar.Heading>
103
+ </BottomSheet.NavBar>
104
+ <PanelBody>
105
+ <LinkDestination
106
+ isSelected={ linkDestination === LINK_DESTINATION_NONE }
107
+ label={ __( 'None' ) }
108
+ onPress={ setLinkDestination( LINK_DESTINATION_NONE ) }
109
+ />
110
+ <LinkDestination
111
+ isSelected={ linkDestination === LINK_DESTINATION_MEDIA }
112
+ label={ __( 'Media File' ) }
113
+ onPress={ setLinkDestination( LINK_DESTINATION_MEDIA ) }
114
+ />
115
+ { !! attachmentPageUrl && (
116
+ <LinkDestination
117
+ isSelected={
118
+ linkDestination === LINK_DESTINATION_ATTACHMENT
119
+ }
120
+ label={ __( 'Attachment Page' ) }
121
+ onPress={ setLinkDestination(
122
+ LINK_DESTINATION_ATTACHMENT
123
+ ) }
124
+ />
125
+ ) }
126
+ <LinkDestination
127
+ isSelected={ linkDestination === LINK_DESTINATION_CUSTOM }
128
+ label={ __( 'Custom URL' ) }
129
+ onPress={ goToLinkPicker }
130
+ value={
131
+ linkDestination === LINK_DESTINATION_CUSTOM
132
+ ? inputValue
133
+ : ''
134
+ }
135
+ valueStyle={
136
+ linkDestination === LINK_DESTINATION_CUSTOM
137
+ ? undefined
138
+ : styles.placeholderTextColor
139
+ }
140
+ >
141
+ <Icon icon={ chevronRight }></Icon>
142
+ </LinkDestination>
143
+ </PanelBody>
144
+ </>
145
+ );
146
+ }
147
+
148
+ export default ImageLinkDestinationsScreen;
@@ -86,9 +86,9 @@ function LinkSettings( {
86
86
  urlValue,
87
87
  // Attributes properties
88
88
  url,
89
- label,
89
+ label = '',
90
90
  linkTarget,
91
- rel,
91
+ rel = '',
92
92
  } ) {
93
93
  const [ urlInputValue, setUrlInputValue ] = useState( '' );
94
94
  const [ labelInputValue, setLabelInputValue ] = useState( '' );
@@ -226,6 +226,7 @@ function LinkSettings( {
226
226
  <BottomSheet.LinkCell
227
227
  showIcon={ showIcon }
228
228
  value={ url }
229
+ valueMask={ options.url.valueMask }
229
230
  onPress={ onLinkCellPressed }
230
231
  />
231
232
  ) : (
@@ -23,6 +23,7 @@ function LinkSettingsNavigation( props ) {
23
23
  isVisible={ props.isVisible }
24
24
  onClose={ props.onClose }
25
25
  onDismiss={ props.onDismiss }
26
+ testID={ props.testID }
26
27
  hideHeader
27
28
  hasNavigation
28
29
  >
@@ -20,17 +20,21 @@ const LinkSettingsScreen = ( props ) => {
20
20
  const { inputValue = url } = route.params || {};
21
21
 
22
22
  const onLinkCellPressed = () => {
23
- navigation.navigate( 'linkPicker', { inputValue } );
23
+ if ( props.onLinkCellPressed ) {
24
+ props.onLinkCellPressed( { navigation } );
25
+ } else {
26
+ navigation.navigate( 'linkPicker', { inputValue } );
27
+ }
24
28
  };
25
29
 
26
30
  return useMemo( () => {
27
31
  return (
28
32
  <LinkSettings
33
+ { ...props }
29
34
  onLinkCellPressed={
30
35
  props.hasPicker ? onLinkCellPressed : undefined
31
36
  }
32
37
  urlValue={ inputValue }
33
- { ...props }
34
38
  />
35
39
  );
36
40
  }, [ props, inputValue, navigation, route ] );
@@ -2,3 +2,20 @@
2
2
  padding-left: 0;
3
3
  padding-right: 0;
4
4
  }
5
+
6
+ // used in both light and dark modes
7
+ .placeholderTextColor {
8
+ color: #87a6bc;
9
+ }
10
+
11
+ .optionIcon {
12
+ color: $blue-50;
13
+ }
14
+
15
+ .optionIconDark {
16
+ color: $blue-30;
17
+ }
18
+
19
+ .unselectedOptionIcon {
20
+ opacity: 0;
21
+ }
@@ -71,7 +71,7 @@ export default class Picker extends Component {
71
71
  }
72
72
 
73
73
  render() {
74
- const { hideCancelButton, title } = this.props;
74
+ const { hideCancelButton, title, testID } = this.props;
75
75
  const { isVisible } = this.state;
76
76
 
77
77
  return (
@@ -80,6 +80,7 @@ export default class Picker extends Component {
80
80
  onClose={ this.onClose }
81
81
  style={ { paddingBottom: 20 } }
82
82
  hideHeader
83
+ testID={ testID }
83
84
  >
84
85
  <PanelBody title={ title } style={ styles.panelBody }>
85
86
  { this.getOptions() }
@@ -247,6 +247,14 @@ If this property is added, it will an additional class name to the modal overlay
247
247
  - Type: `String`
248
248
  - Required: No
249
249
 
250
+ #### isFullScreen
251
+
252
+ This property when set to `true` will render a full screen modal.
253
+
254
+ - Type: `boolean`
255
+ - Required: No
256
+ - Default: `false`
257
+
250
258
  ## Related components
251
259
 
252
260
  - To notify a user with a message of medium importance, use `Notice`.