@wordpress/block-editor 16.2.0 → 17.0.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.
- package/CHANGELOG.md +39 -0
- package/build/components/block-inspector/index.cjs +9 -6
- package/build/components/block-inspector/index.cjs.map +2 -2
- package/build/components/block-keyboard-shortcuts/index.cjs +201 -0
- package/build/components/block-keyboard-shortcuts/index.cjs.map +7 -0
- package/build/components/block-list/block.cjs +10 -3
- package/build/components/block-list/block.cjs.map +2 -2
- package/build/components/block-list/index.cjs +6 -1
- package/build/components/block-list/index.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-focus-first-element.cjs +4 -0
- package/build/components/block-list/use-block-props/use-focus-first-element.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +6 -7
- package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
- package/build/components/block-parent-selector/index.cjs +98 -29
- package/build/components/block-parent-selector/index.cjs.map +3 -3
- package/build/components/block-popover/inbetween.cjs +2 -2
- package/build/components/block-popover/inbetween.cjs.map +2 -2
- package/build/components/block-preview/index.cjs +0 -4
- package/build/components/block-preview/index.cjs.map +2 -2
- package/build/components/block-styles/index.cjs +77 -33
- package/build/components/block-styles/index.cjs.map +3 -3
- package/build/components/block-visibility/constants.cjs.map +2 -2
- package/build/components/child-layout-control/index.cjs.map +2 -2
- package/build/components/colors/with-colors.cjs +55 -71
- package/build/components/colors/with-colors.cjs.map +2 -2
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs +4 -2
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +2 -2
- package/build/components/dimensions-tool/index.cjs +18 -16
- package/build/components/dimensions-tool/index.cjs.map +2 -2
- package/build/components/dimensions-tool/utils.cjs +61 -0
- package/build/components/dimensions-tool/utils.cjs.map +7 -0
- package/build/components/duotone-control/index.cjs +2 -0
- package/build/components/duotone-control/index.cjs.map +2 -2
- package/build/components/global-styles/advanced-panel.cjs.map +3 -3
- package/build/components/global-styles/border-panel.cjs +2 -5
- package/build/components/global-styles/border-panel.cjs.map +2 -2
- package/build/components/global-styles/color-panel.cjs +14 -2
- package/build/components/global-styles/color-panel.cjs.map +2 -2
- package/build/components/global-styles/dimensions-panel.cjs +9 -5
- package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
- package/build/components/global-styles/filters-panel.cjs +12 -8
- package/build/components/global-styles/filters-panel.cjs.map +2 -2
- package/build/components/global-styles/shadow-panel-components.cjs +16 -11
- package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
- package/build/components/global-styles/utils.cjs +9 -0
- package/build/components/global-styles/utils.cjs.map +2 -2
- package/build/components/inner-blocks/index.cjs +5 -3
- package/build/components/inner-blocks/index.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/index.cjs +39 -22
- package/build/components/inserter/block-patterns-explorer/index.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs +21 -55
- package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/pattern-list.cjs +19 -44
- package/build/components/inserter/block-patterns-explorer/pattern-list.cjs.map +3 -3
- package/build/components/inserter/hooks/use-insertion-point.cjs +4 -4
- package/build/components/inserter/hooks/use-insertion-point.cjs.map +2 -2
- package/build/components/inserter/menu.cjs +18 -7
- package/build/components/inserter/menu.cjs.map +2 -2
- package/build/components/inserter/quick-inserter.cjs +30 -27
- package/build/components/inserter/quick-inserter.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/styles-tab.cjs +1 -1
- package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
- package/build/components/list-view/index.cjs +31 -5
- package/build/components/list-view/index.cjs.map +3 -3
- package/build/components/list-view/utils.cjs +13 -1
- package/build/components/list-view/utils.cjs.map +2 -2
- package/build/components/media-placeholder/index.cjs +1 -1
- package/build/components/media-placeholder/index.cjs.map +3 -3
- package/build/components/provider/index.cjs +5 -1
- package/build/components/provider/index.cjs.map +3 -3
- package/build/components/publish-date-time-picker/index.cjs +3 -2
- package/build/components/publish-date-time-picker/index.cjs.map +2 -2
- package/build/components/rich-text/event-listeners/enter.cjs +46 -39
- package/build/components/rich-text/event-listeners/enter.cjs.map +2 -2
- package/build/components/rich-text/index.cjs +7 -5
- package/build/components/rich-text/index.cjs.map +2 -2
- package/build/components/rich-text/multiline.cjs +105 -70
- package/build/components/rich-text/multiline.cjs.map +3 -3
- package/build/components/url-input/index.cjs.map +2 -2
- package/build/components/writing-flow/use-input.cjs +65 -13
- package/build/components/writing-flow/use-input.cjs.map +3 -3
- package/build/hooks/border.cjs +25 -3
- package/build/hooks/border.cjs.map +2 -2
- package/build/hooks/dimensions.cjs +9 -2
- package/build/hooks/dimensions.cjs.map +2 -2
- package/build/hooks/duotone.cjs +4 -3
- package/build/hooks/duotone.cjs.map +2 -2
- package/build/hooks/gap.cjs +8 -2
- package/build/hooks/gap.cjs.map +2 -2
- package/build/hooks/layout-child.cjs +35 -13
- package/build/hooks/layout-child.cjs.map +2 -2
- package/build/hooks/layout.cjs +23 -1
- package/build/hooks/layout.cjs.map +2 -2
- package/build/hooks/states.cjs +7 -4
- package/build/hooks/states.cjs.map +2 -2
- package/build/layouts/constrained.cjs +8 -1
- package/build/layouts/constrained.cjs.map +2 -2
- package/build/layouts/flex.cjs +9 -0
- package/build/layouts/flex.cjs.map +2 -2
- package/build/layouts/flow.cjs +4 -1
- package/build/layouts/flow.cjs.map +2 -2
- package/build/layouts/grid.cjs +5 -1
- package/build/layouts/grid.cjs.map +2 -2
- package/build/private-apis.cjs +3 -1
- package/build/private-apis.cjs.map +2 -2
- package/build/store/actions.cjs +1 -1
- package/build/store/actions.cjs.map +2 -2
- package/build-module/components/block-inspector/index.mjs +9 -6
- package/build-module/components/block-inspector/index.mjs.map +2 -2
- package/build-module/components/block-keyboard-shortcuts/index.mjs +173 -0
- package/build-module/components/block-keyboard-shortcuts/index.mjs.map +7 -0
- package/build-module/components/block-list/block.mjs +10 -3
- package/build-module/components/block-list/block.mjs.map +2 -2
- package/build-module/components/block-list/index.mjs +6 -1
- package/build-module/components/block-list/index.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs +4 -0
- package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +6 -7
- package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
- package/build-module/components/block-parent-selector/index.mjs +101 -32
- package/build-module/components/block-parent-selector/index.mjs.map +2 -2
- package/build-module/components/block-popover/inbetween.mjs +2 -2
- package/build-module/components/block-popover/inbetween.mjs.map +2 -2
- package/build-module/components/block-preview/index.mjs +0 -4
- package/build-module/components/block-preview/index.mjs.map +2 -2
- package/build-module/components/block-styles/index.mjs +79 -35
- package/build-module/components/block-styles/index.mjs.map +2 -2
- package/build-module/components/block-visibility/constants.mjs.map +2 -2
- package/build-module/components/child-layout-control/index.mjs +5 -5
- package/build-module/components/child-layout-control/index.mjs.map +1 -1
- package/build-module/components/colors/with-colors.mjs +56 -72
- package/build-module/components/colors/with-colors.mjs.map +2 -2
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +4 -2
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
- package/build-module/components/dimensions-tool/index.mjs +19 -17
- package/build-module/components/dimensions-tool/index.mjs.map +2 -2
- package/build-module/components/dimensions-tool/utils.mjs +35 -0
- package/build-module/components/dimensions-tool/utils.mjs.map +7 -0
- package/build-module/components/duotone-control/index.mjs +2 -0
- package/build-module/components/duotone-control/index.mjs.map +2 -2
- package/build-module/components/global-styles/advanced-panel.mjs +5 -2
- package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
- package/build-module/components/global-styles/border-panel.mjs +2 -5
- package/build-module/components/global-styles/border-panel.mjs.map +2 -2
- package/build-module/components/global-styles/color-panel.mjs +14 -2
- package/build-module/components/global-styles/color-panel.mjs.map +2 -2
- package/build-module/components/global-styles/dimensions-panel.mjs +9 -5
- package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
- package/build-module/components/global-styles/filters-panel.mjs +16 -9
- package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
- package/build-module/components/global-styles/shadow-panel-components.mjs +16 -11
- package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
- package/build-module/components/global-styles/utils.mjs +8 -0
- package/build-module/components/global-styles/utils.mjs.map +2 -2
- package/build-module/components/inner-blocks/index.mjs +5 -3
- package/build-module/components/inner-blocks/index.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/index.mjs +39 -22
- package/build-module/components/inserter/block-patterns-explorer/index.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs +22 -56
- package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs +20 -45
- package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs.map +2 -2
- package/build-module/components/inserter/hooks/use-insertion-point.mjs +4 -4
- package/build-module/components/inserter/hooks/use-insertion-point.mjs.map +2 -2
- package/build-module/components/inserter/menu.mjs +19 -8
- package/build-module/components/inserter/menu.mjs.map +2 -2
- package/build-module/components/inserter/quick-inserter.mjs +30 -27
- package/build-module/components/inserter/quick-inserter.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs +1 -1
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
- package/build-module/components/list-view/index.mjs +32 -5
- package/build-module/components/list-view/index.mjs.map +3 -3
- package/build-module/components/list-view/utils.mjs +13 -1
- package/build-module/components/list-view/utils.mjs.map +2 -2
- package/build-module/components/media-placeholder/index.mjs +3 -3
- package/build-module/components/media-placeholder/index.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +6 -2
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/publish-date-time-picker/index.mjs +3 -2
- package/build-module/components/publish-date-time-picker/index.mjs.map +2 -2
- package/build-module/components/rich-text/event-listeners/enter.mjs +46 -39
- package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
- package/build-module/components/rich-text/index.mjs +7 -5
- package/build-module/components/rich-text/index.mjs.map +2 -2
- package/build-module/components/rich-text/multiline.mjs +112 -72
- package/build-module/components/rich-text/multiline.mjs.map +2 -2
- package/build-module/components/url-input/index.mjs +2 -2
- package/build-module/components/url-input/index.mjs.map +1 -1
- package/build-module/components/writing-flow/use-input.mjs +66 -14
- package/build-module/components/writing-flow/use-input.mjs.map +3 -3
- package/build-module/hooks/border.mjs +26 -8
- package/build-module/hooks/border.mjs.map +2 -2
- package/build-module/hooks/dimensions.mjs +9 -2
- package/build-module/hooks/dimensions.mjs.map +2 -2
- package/build-module/hooks/duotone.mjs +8 -4
- package/build-module/hooks/duotone.mjs.map +2 -2
- package/build-module/hooks/gap.mjs +6 -1
- package/build-module/hooks/gap.mjs.map +2 -2
- package/build-module/hooks/layout-child.mjs +36 -13
- package/build-module/hooks/layout-child.mjs.map +2 -2
- package/build-module/hooks/layout.mjs +22 -1
- package/build-module/hooks/layout.mjs.map +2 -2
- package/build-module/hooks/states.mjs +8 -5
- package/build-module/hooks/states.mjs.map +2 -2
- package/build-module/layouts/constrained.mjs +8 -1
- package/build-module/layouts/constrained.mjs.map +2 -2
- package/build-module/layouts/flex.mjs +9 -0
- package/build-module/layouts/flex.mjs.map +2 -2
- package/build-module/layouts/flow.mjs +4 -1
- package/build-module/layouts/flow.mjs.map +2 -2
- package/build-module/layouts/grid.mjs +5 -1
- package/build-module/layouts/grid.mjs.map +2 -2
- package/build-module/private-apis.mjs +3 -1
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs +1 -1
- package/build-module/store/actions.mjs.map +2 -2
- package/build-style/style-rtl.css +108 -71
- package/build-style/style.css +108 -71
- package/build-types/components/block-visibility/constants.d.ts +4 -3
- package/build-types/components/block-visibility/constants.d.ts.map +1 -1
- package/package.json +43 -43
- package/src/components/background-image-control/README.md +122 -0
- package/src/components/block-edit-visually-button/README.md +39 -0
- package/src/components/block-editing-mode/README.md +72 -0
- package/src/components/block-inspector/index.js +6 -6
- package/src/components/block-keyboard-shortcuts/index.js +256 -0
- package/src/components/block-list/block.js +7 -0
- package/src/components/block-list/index.js +7 -1
- package/src/components/block-list/use-block-props/use-focus-first-element.js +5 -0
- package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +6 -8
- package/src/components/block-parent-selector/index.js +111 -30
- package/src/components/block-popover/README.md +10 -3
- package/src/components/block-popover/inbetween.js +8 -2
- package/src/components/block-popover/stories/index.story.jsx +143 -0
- package/src/components/block-preview/index.js +0 -2
- package/src/components/block-styles/index.js +95 -43
- package/src/components/block-styles/style.scss +5 -34
- package/src/components/block-tools/style.scss +94 -0
- package/src/components/block-visibility/constants.ts +4 -3
- package/src/components/child-layout-control/index.js +5 -5
- package/src/components/color-palette/test/__snapshots__/control.js.snap +3 -29
- package/src/components/colors/test/with-colors.js +6 -7
- package/src/components/colors/with-colors.js +79 -105
- package/src/components/dimensions-tool/aspect-ratio-tool.js +16 -4
- package/src/components/dimensions-tool/index.js +34 -22
- package/src/components/dimensions-tool/test/index.js +166 -2
- package/src/components/dimensions-tool/test/utils.js +51 -0
- package/src/components/dimensions-tool/utils.js +67 -0
- package/src/components/duotone-control/index.js +2 -0
- package/src/components/duotone-control/test/index.js +100 -0
- package/src/components/global-styles/advanced-panel.js +5 -2
- package/src/components/global-styles/border-panel.js +11 -9
- package/src/components/global-styles/color-panel.js +13 -1
- package/src/components/global-styles/dimensions-panel.js +17 -5
- package/src/components/global-styles/filters-panel.js +24 -10
- package/src/components/global-styles/shadow-panel-components.js +38 -11
- package/src/components/global-styles/test/border-panel.js +230 -0
- package/src/components/global-styles/test/color-panel.js +24 -0
- package/src/components/global-styles/test/dimensions-panel.js +98 -7
- package/src/components/global-styles/test/filters-panel.js +84 -0
- package/src/components/global-styles/test/utils.js +30 -0
- package/src/components/global-styles/utils.js +23 -0
- package/src/components/inner-blocks/index.js +11 -2
- package/src/components/inner-blocks/stories/index.story.jsx +246 -0
- package/src/components/inserter/block-patterns-explorer/index.js +24 -11
- package/src/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +18 -56
- package/src/components/inserter/block-patterns-explorer/pattern-list.js +22 -47
- package/src/components/inserter/hooks/use-insertion-point.js +9 -4
- package/src/components/inserter/menu.js +23 -10
- package/src/components/inserter/quick-inserter.js +15 -13
- package/src/components/inserter/style.scss +44 -62
- package/src/components/inspector-controls-tabs/README.md +92 -0
- package/src/components/inspector-controls-tabs/styles-tab.js +1 -1
- package/src/components/link-control/test/index.js +5 -0
- package/src/components/list-view/index.js +50 -7
- package/src/components/list-view/utils.js +16 -1
- package/src/components/media-placeholder/index.js +9 -4
- package/src/components/plain-text/stories/index.story.jsx +3 -0
- package/src/components/provider/index.js +7 -1
- package/src/components/publish-date-time-picker/README.md +10 -0
- package/src/components/publish-date-time-picker/index.js +17 -14
- package/src/components/rich-text/event-listeners/enter.js +58 -45
- package/src/components/rich-text/index.js +9 -4
- package/src/components/rich-text/multiline.js +126 -86
- package/src/components/url-input/index.js +2 -2
- package/src/components/url-input/test/fixtures/validated-input-control-deprecation.js +27 -0
- package/src/components/url-input/test/index.js +5 -0
- package/src/components/url-popover/README.md +7 -0
- package/src/components/url-popover/stories/index.story.jsx +133 -47
- package/src/components/writing-flow/use-input.js +105 -15
- package/src/hooks/border.js +27 -8
- package/src/hooks/dimensions.js +8 -1
- package/src/hooks/duotone.js +23 -7
- package/src/hooks/gap.js +16 -0
- package/src/hooks/layout-child.js +41 -9
- package/src/hooks/layout.js +117 -71
- package/src/hooks/states.js +8 -5
- package/src/hooks/test/gap.js +31 -1
- package/src/hooks/test/layout-child.js +60 -1
- package/src/hooks/test/layout.js +27 -0
- package/src/layouts/constrained.js +9 -1
- package/src/layouts/flex.js +15 -0
- package/src/layouts/flow.js +4 -1
- package/src/layouts/grid.js +9 -1
- package/src/layouts/test/constrained.js +26 -0
- package/src/layouts/test/flow.js +26 -0
- package/src/layouts/test/grid.js +46 -0
- package/src/private-apis.js +2 -0
- package/src/store/actions.js +14 -1
- package/build/components/floating-toolbar/nav-up-icon.cjs +0 -52
- package/build/components/floating-toolbar/nav-up-icon.cjs.map +0 -7
- package/build/components/gradients/with-gradient.cjs +0 -36
- package/build/components/gradients/with-gradient.cjs.map +0 -7
- package/build/components/inserter-button/sparkles.cjs +0 -36
- package/build/components/inserter-button/sparkles.cjs.map +0 -7
- package/build-module/components/floating-toolbar/nav-up-icon.mjs +0 -31
- package/build-module/components/floating-toolbar/nav-up-icon.mjs.map +0 -7
- package/build-module/components/gradients/with-gradient.mjs +0 -11
- package/build-module/components/gradients/with-gradient.mjs.map +0 -7
- package/build-module/components/inserter-button/sparkles.mjs +0 -15
- package/build-module/components/inserter-button/sparkles.mjs.map +0 -7
- package/build-style/default-editor-styles-rtl.css +0 -68
- package/build-style/default-editor-styles.css +0 -68
- package/src/components/floating-toolbar/nav-up-icon.js +0 -22
- package/src/components/gradients/with-gradient.js +0 -9
- package/src/components/inserter-button/README.md +0 -62
- package/src/components/inserter-button/sparkles.js +0 -12
- package/src/default-editor-styles.scss +0 -25
|
@@ -33,6 +33,7 @@ import { Content, valueToHTMLString } from './content';
|
|
|
33
33
|
import { withDeprecations } from './with-deprecations';
|
|
34
34
|
import BlockContext from '../block-context';
|
|
35
35
|
import { unlock } from '../../lock-unlock';
|
|
36
|
+
import { PrivateBlockContext } from '../block-list/private-block-context';
|
|
36
37
|
|
|
37
38
|
// `RichTextShortcut` and `RichTextInputEvent` now live in
|
|
38
39
|
// `@wordpress/rich-text` so they share the shortcut and input-event contexts
|
|
@@ -48,7 +49,7 @@ const {
|
|
|
48
49
|
|
|
49
50
|
const instanceIdKey = Symbol( 'instanceId' );
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
function RichTextWrapper(
|
|
52
53
|
{
|
|
53
54
|
children,
|
|
54
55
|
tagName = 'div',
|
|
@@ -87,6 +88,7 @@ export function RichTextWrapper(
|
|
|
87
88
|
} );
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
const { supportsSplitting } = useContext( PrivateBlockContext );
|
|
90
92
|
const instanceId = useInstanceId( RichTextWrapper );
|
|
91
93
|
const anchorRef = useRef();
|
|
92
94
|
const [ anchorElement, setAnchorElement ] = useState( null );
|
|
@@ -511,6 +513,7 @@ export function RichTextWrapper(
|
|
|
511
513
|
onSplitAtDoubleLineEnd,
|
|
512
514
|
keyboardShortcuts,
|
|
513
515
|
inputEvents,
|
|
516
|
+
supportsSplitting,
|
|
514
517
|
} ),
|
|
515
518
|
anchorRef,
|
|
516
519
|
setAnchorElement,
|
|
@@ -529,11 +532,13 @@ export function RichTextWrapper(
|
|
|
529
532
|
);
|
|
530
533
|
}
|
|
531
534
|
|
|
535
|
+
const ForwardedRichTextWrapper = forwardRef( RichTextWrapper );
|
|
536
|
+
|
|
537
|
+
export { ForwardedRichTextWrapper as RichTextWrapper };
|
|
538
|
+
|
|
532
539
|
// This is the private API for the RichText component.
|
|
533
540
|
// It allows access to all props, not just the public ones.
|
|
534
|
-
export const PrivateRichText = withDeprecations(
|
|
535
|
-
forwardRef( RichTextWrapper )
|
|
536
|
-
);
|
|
541
|
+
export const PrivateRichText = withDeprecations( ForwardedRichTextWrapper );
|
|
537
542
|
|
|
538
543
|
PrivateRichText.Content = Content;
|
|
539
544
|
PrivateRichText.isEmpty = ( value ) => {
|
|
@@ -1,12 +1,130 @@
|
|
|
1
|
-
import { forwardRef } from '@wordpress/element';
|
|
1
|
+
import { forwardRef, useInsertionEffect, useRef } from '@wordpress/element';
|
|
2
2
|
import deprecated from '@wordpress/deprecated';
|
|
3
3
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
4
4
|
import { ENTER } from '@wordpress/keycodes';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
create,
|
|
7
|
+
split,
|
|
8
|
+
toHTMLString,
|
|
9
|
+
privateApis as richTextPrivateApis,
|
|
10
|
+
} from '@wordpress/rich-text';
|
|
11
|
+
import { useRefEffect } from '@wordpress/compose';
|
|
6
12
|
import { RichTextWrapper } from './';
|
|
7
13
|
import { store as blockEditorStore } from '../../store';
|
|
8
14
|
import { useBlockEditContext } from '../block-edit';
|
|
9
15
|
import { getMultilineTag } from './utils';
|
|
16
|
+
import { unlock } from '../../lock-unlock';
|
|
17
|
+
|
|
18
|
+
const { subscribeOwnedListener } = unlock( richTextPrivateApis );
|
|
19
|
+
|
|
20
|
+
function useEnterRef( props ) {
|
|
21
|
+
const { getSelectionStart, getSelectionEnd } =
|
|
22
|
+
useSelect( blockEditorStore );
|
|
23
|
+
const { selectionChange } = useDispatch( blockEditorStore );
|
|
24
|
+
return useRefEffect( ( element ) => {
|
|
25
|
+
function onKeyDown( event ) {
|
|
26
|
+
if ( event.keyCode !== ENTER ) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
event.preventDefault();
|
|
31
|
+
|
|
32
|
+
const { value, values, onChange, index, identifier, clientId } =
|
|
33
|
+
props.current;
|
|
34
|
+
const { offset: start } = getSelectionStart();
|
|
35
|
+
const { offset: end } = getSelectionEnd();
|
|
36
|
+
|
|
37
|
+
// Cannot split if there is no selection.
|
|
38
|
+
if ( typeof start !== 'number' || typeof end !== 'number' ) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const richTextValue = create( { html: value } );
|
|
43
|
+
richTextValue.start = start;
|
|
44
|
+
richTextValue.end = end;
|
|
45
|
+
|
|
46
|
+
const array = split( richTextValue ).map( ( v ) =>
|
|
47
|
+
toHTMLString( { value: v } )
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const newValues = values.slice();
|
|
51
|
+
newValues.splice( index, 1, ...array );
|
|
52
|
+
onChange( newValues );
|
|
53
|
+
selectionChange( clientId, `${ identifier }-${ index + 1 }`, 0, 0 );
|
|
54
|
+
}
|
|
55
|
+
// Capture phase so this runs before the generic rich text enter
|
|
56
|
+
// listener, which skips events that already had their default
|
|
57
|
+
// prevented.
|
|
58
|
+
return subscribeOwnedListener( element, 'keydown', onKeyDown, true );
|
|
59
|
+
}, [] );
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function Line( lineProps ) {
|
|
63
|
+
const {
|
|
64
|
+
value,
|
|
65
|
+
values,
|
|
66
|
+
onChange,
|
|
67
|
+
index,
|
|
68
|
+
identifier,
|
|
69
|
+
multilineTagName,
|
|
70
|
+
...props
|
|
71
|
+
} = lineProps;
|
|
72
|
+
const { clientId } = useBlockEditContext();
|
|
73
|
+
const { selectionChange } = useDispatch( blockEditorStore );
|
|
74
|
+
const latestRef = useRef();
|
|
75
|
+
useInsertionEffect( () => {
|
|
76
|
+
latestRef.current = { ...lineProps, clientId };
|
|
77
|
+
} );
|
|
78
|
+
const ref = useEnterRef( latestRef );
|
|
79
|
+
return (
|
|
80
|
+
<RichTextWrapper
|
|
81
|
+
key={ index }
|
|
82
|
+
identifier={ `${ identifier }-${ index }` }
|
|
83
|
+
tagName={ multilineTagName }
|
|
84
|
+
value={ value }
|
|
85
|
+
onChange={ ( newValue ) => {
|
|
86
|
+
const newValues = values.slice();
|
|
87
|
+
newValues[ index ] = newValue;
|
|
88
|
+
onChange( newValues );
|
|
89
|
+
} }
|
|
90
|
+
isSelected={ undefined }
|
|
91
|
+
ref={ ref }
|
|
92
|
+
onMerge={ ( forward ) => {
|
|
93
|
+
const newValues = values.slice();
|
|
94
|
+
let offset = 0;
|
|
95
|
+
if ( forward ) {
|
|
96
|
+
if ( ! newValues[ index + 1 ] ) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
newValues.splice(
|
|
100
|
+
index,
|
|
101
|
+
2,
|
|
102
|
+
newValues[ index ] + newValues[ index + 1 ]
|
|
103
|
+
);
|
|
104
|
+
offset = newValues[ index ].length - 1;
|
|
105
|
+
} else {
|
|
106
|
+
if ( ! newValues[ index - 1 ] ) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
newValues.splice(
|
|
110
|
+
index - 1,
|
|
111
|
+
2,
|
|
112
|
+
newValues[ index - 1 ] + newValues[ index ]
|
|
113
|
+
);
|
|
114
|
+
offset = newValues[ index - 1 ].length - 1;
|
|
115
|
+
}
|
|
116
|
+
onChange( newValues );
|
|
117
|
+
selectionChange(
|
|
118
|
+
clientId,
|
|
119
|
+
`${ identifier }-${ index - ( forward ? 0 : 1 ) }`,
|
|
120
|
+
offset,
|
|
121
|
+
offset
|
|
122
|
+
);
|
|
123
|
+
} }
|
|
124
|
+
{ ...props }
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
10
128
|
|
|
11
129
|
function RichTextMultiline(
|
|
12
130
|
{
|
|
@@ -27,11 +145,6 @@ function RichTextMultiline(
|
|
|
27
145
|
link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/',
|
|
28
146
|
} );
|
|
29
147
|
|
|
30
|
-
const { clientId } = useBlockEditContext();
|
|
31
|
-
const { getSelectionStart, getSelectionEnd } =
|
|
32
|
-
useSelect( blockEditorStore );
|
|
33
|
-
const { selectionChange } = useDispatch( blockEditorStore );
|
|
34
|
-
|
|
35
148
|
const multilineTagName = getMultilineTag( multiline );
|
|
36
149
|
value = value || `<${ multilineTagName }></${ multilineTagName }>`;
|
|
37
150
|
const padded = `</${ multilineTagName }>${ value }<${ multilineTagName }>`;
|
|
@@ -54,87 +167,14 @@ function RichTextMultiline(
|
|
|
54
167
|
<TagName ref={ forwardedRef }>
|
|
55
168
|
{ values.map( ( _value, index ) => {
|
|
56
169
|
return (
|
|
57
|
-
<
|
|
170
|
+
<Line
|
|
58
171
|
key={ index }
|
|
59
|
-
|
|
60
|
-
tagName={ multilineTagName }
|
|
172
|
+
values={ values }
|
|
61
173
|
value={ _value }
|
|
62
|
-
onChange={
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} }
|
|
67
|
-
isSelected={ undefined }
|
|
68
|
-
onKeyDown={ ( event ) => {
|
|
69
|
-
if ( event.keyCode !== ENTER ) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
|
|
75
|
-
const { offset: start } = getSelectionStart();
|
|
76
|
-
const { offset: end } = getSelectionEnd();
|
|
77
|
-
|
|
78
|
-
// Cannot split if there is no selection.
|
|
79
|
-
if (
|
|
80
|
-
typeof start !== 'number' ||
|
|
81
|
-
typeof end !== 'number'
|
|
82
|
-
) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const richTextValue = create( { html: _value } );
|
|
87
|
-
richTextValue.start = start;
|
|
88
|
-
richTextValue.end = end;
|
|
89
|
-
|
|
90
|
-
const array = split( richTextValue ).map( ( v ) =>
|
|
91
|
-
toHTMLString( { value: v } )
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const newValues = values.slice();
|
|
95
|
-
newValues.splice( index, 1, ...array );
|
|
96
|
-
_onChange( newValues );
|
|
97
|
-
selectionChange(
|
|
98
|
-
clientId,
|
|
99
|
-
`${ identifier }-${ index + 1 }`,
|
|
100
|
-
0,
|
|
101
|
-
0
|
|
102
|
-
);
|
|
103
|
-
} }
|
|
104
|
-
onMerge={ ( forward ) => {
|
|
105
|
-
const newValues = values.slice();
|
|
106
|
-
let offset = 0;
|
|
107
|
-
if ( forward ) {
|
|
108
|
-
if ( ! newValues[ index + 1 ] ) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
newValues.splice(
|
|
112
|
-
index,
|
|
113
|
-
2,
|
|
114
|
-
newValues[ index ] + newValues[ index + 1 ]
|
|
115
|
-
);
|
|
116
|
-
offset = newValues[ index ].length - 1;
|
|
117
|
-
} else {
|
|
118
|
-
if ( ! newValues[ index - 1 ] ) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
newValues.splice(
|
|
122
|
-
index - 1,
|
|
123
|
-
2,
|
|
124
|
-
newValues[ index - 1 ] + newValues[ index ]
|
|
125
|
-
);
|
|
126
|
-
offset = newValues[ index - 1 ].length - 1;
|
|
127
|
-
}
|
|
128
|
-
_onChange( newValues );
|
|
129
|
-
selectionChange(
|
|
130
|
-
clientId,
|
|
131
|
-
`${ identifier }-${
|
|
132
|
-
index - ( forward ? 0 : 1 )
|
|
133
|
-
}`,
|
|
134
|
-
offset,
|
|
135
|
-
offset
|
|
136
|
-
);
|
|
137
|
-
} }
|
|
174
|
+
onChange={ _onChange }
|
|
175
|
+
index={ index }
|
|
176
|
+
identifier={ identifier }
|
|
177
|
+
multilineTagName={ multilineTagName }
|
|
138
178
|
{ ...props }
|
|
139
179
|
/>
|
|
140
180
|
);
|
|
@@ -6,7 +6,7 @@ import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes';
|
|
|
6
6
|
import {
|
|
7
7
|
BaseControl,
|
|
8
8
|
Button,
|
|
9
|
-
__experimentalInputControl as
|
|
9
|
+
__experimentalInputControl as WCInputControl,
|
|
10
10
|
Spinner,
|
|
11
11
|
Popover,
|
|
12
12
|
privateApis as componentsPrivateApis,
|
|
@@ -436,7 +436,7 @@ function Control( {
|
|
|
436
436
|
|
|
437
437
|
const MaybeValidatedInputControl = isValidated
|
|
438
438
|
? ValidatedInputControl
|
|
439
|
-
:
|
|
439
|
+
: WCInputControl;
|
|
440
440
|
|
|
441
441
|
return (
|
|
442
442
|
<BaseControl { ...controlProps }>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporary test helper while `URLInput` still unlocks the deprecated private
|
|
3
|
+
* `ValidatedInputControl` from `@wordpress/components`.
|
|
4
|
+
*
|
|
5
|
+
* DELETE this file (and remove its imports) once `URLInput` migrates to
|
|
6
|
+
* `@wordpress/ui` `ValidatedInputControl`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const VALIDATED_INPUT_CONTROL_DEPRECATION =
|
|
10
|
+
'wp.components.privateApis.ValidatedInputControl is deprecated since version 7.2. Please use ValidatedInputControl from @wordpress/ui instead. Note: This private API will be completely removed within a few Gutenberg plugin releases.';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Asserts the expected deprecation warning when URL validation rendered the
|
|
14
|
+
* private `ValidatedInputControl`. No-op when validation did not run.
|
|
15
|
+
*/
|
|
16
|
+
export function expectValidatedInputControlDeprecationIfCalled() {
|
|
17
|
+
// eslint-disable-next-line no-console -- jest-console mock inspection.
|
|
18
|
+
const deprecationCalls = console.warn.mock.calls.filter(
|
|
19
|
+
( [ message ] ) => message === VALIDATED_INPUT_CONTROL_DEPRECATION
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if ( deprecationCalls.length > 0 ) {
|
|
23
|
+
expect( console ).toHaveWarnedWith(
|
|
24
|
+
VALIDATED_INPUT_CONTROL_DEPRECATION
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -6,6 +6,7 @@ import { dispatch } from '@wordpress/data';
|
|
|
6
6
|
import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes';
|
|
7
7
|
import URLInput from '../';
|
|
8
8
|
import { store as blockEditorStore } from '../../../store';
|
|
9
|
+
import { expectValidatedInputControlDeprecationIfCalled } from './fixtures/validated-input-control-deprecation';
|
|
9
10
|
|
|
10
11
|
jest.mock( '@wordpress/a11y', () => ( { speak: jest.fn() } ) );
|
|
11
12
|
|
|
@@ -636,6 +637,10 @@ describe( 'URLInput', () => {
|
|
|
636
637
|
} );
|
|
637
638
|
|
|
638
639
|
describe( 'validation', () => {
|
|
640
|
+
afterEach( () => {
|
|
641
|
+
expectValidatedInputControlDeprecationIfCalled();
|
|
642
|
+
} );
|
|
643
|
+
|
|
639
644
|
it( 'should not remount the input when a custom validity is cleared', async () => {
|
|
640
645
|
const user = userEvent.setup();
|
|
641
646
|
const props = {
|
|
@@ -120,6 +120,13 @@ drawer.
|
|
|
120
120
|
- Type: `Function`
|
|
121
121
|
- Required: No
|
|
122
122
|
|
|
123
|
+
### additionalControls
|
|
124
|
+
|
|
125
|
+
Elements rendered in a row below the URL input. They are hidden while the settings drawer is open.
|
|
126
|
+
|
|
127
|
+
- Type: `Element`
|
|
128
|
+
- Required: No
|
|
129
|
+
|
|
123
130
|
## Useful UI pieces
|
|
124
131
|
|
|
125
132
|
The URLPopover exposes two components that may be used as child components to make the UI creation process easier.
|
|
@@ -4,56 +4,142 @@ import { __ } from '@wordpress/i18n';
|
|
|
4
4
|
import { keyboardReturn } from '@wordpress/icons';
|
|
5
5
|
import URLPopover from '../';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'BlockEditor/URLPopover',
|
|
9
|
+
component: URLPopover,
|
|
10
|
+
parameters: {
|
|
11
|
+
// FIXME: Story uses a raw unstyled input whose placeholder fails color-contrast.
|
|
12
|
+
// See: https://github.com/WordPress/gutenberg/issues/81596
|
|
13
|
+
a11y: { test: 'todo' },
|
|
14
|
+
docs: {
|
|
15
|
+
canvas: { sourceState: 'shown' },
|
|
16
|
+
description: {
|
|
17
|
+
component:
|
|
18
|
+
'Popover component used for editing and viewing URLs.',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
argTypes: {
|
|
23
|
+
onClose: {
|
|
24
|
+
action: 'onClose',
|
|
25
|
+
description: 'Callback when the popover is closed.',
|
|
26
|
+
table: {
|
|
27
|
+
type: { summary: 'function' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
renderSettings: {
|
|
31
|
+
description: 'Callback to render settings inside the popover.',
|
|
32
|
+
table: {
|
|
33
|
+
type: { summary: 'function' },
|
|
34
|
+
},
|
|
35
|
+
control: false,
|
|
36
|
+
},
|
|
37
|
+
additionalControls: {
|
|
38
|
+
description:
|
|
39
|
+
'Additional controls rendered below the input row. They are hidden while the settings drawer is open.',
|
|
40
|
+
table: {
|
|
41
|
+
type: { summary: 'Element' },
|
|
42
|
+
},
|
|
43
|
+
control: false,
|
|
44
|
+
},
|
|
45
|
+
placement: {
|
|
46
|
+
control: { type: 'select' },
|
|
47
|
+
options: [
|
|
48
|
+
'top',
|
|
49
|
+
'top-start',
|
|
50
|
+
'top-end',
|
|
51
|
+
'right',
|
|
52
|
+
'right-start',
|
|
53
|
+
'right-end',
|
|
54
|
+
'bottom',
|
|
55
|
+
'bottom-start',
|
|
56
|
+
'bottom-end',
|
|
57
|
+
'left',
|
|
58
|
+
'left-start',
|
|
59
|
+
'left-end',
|
|
60
|
+
'overlay',
|
|
61
|
+
],
|
|
62
|
+
description: 'Placement of the popover relative to its parent.',
|
|
63
|
+
table: {
|
|
64
|
+
type: { summary: 'string' },
|
|
65
|
+
defaultValue: { summary: "'bottom'" },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
focusOnMount: {
|
|
69
|
+
control: { type: 'select' },
|
|
70
|
+
options: [ 'firstElement', 'firstInputElement', true, false ],
|
|
71
|
+
description:
|
|
72
|
+
'Controls which element is focused when the popover mounts.',
|
|
73
|
+
table: {
|
|
74
|
+
type: {
|
|
75
|
+
summary: "boolean | 'firstElement' | 'firstInputElement'",
|
|
76
|
+
},
|
|
77
|
+
defaultValue: { summary: "'firstElement'" },
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
args: {
|
|
82
|
+
placement: 'bottom',
|
|
83
|
+
focusOnMount: 'firstElement',
|
|
84
|
+
},
|
|
85
|
+
};
|
|
8
86
|
|
|
9
|
-
|
|
10
|
-
const [ isVisible, setVisiblility ] = useState( false );
|
|
11
|
-
const [ url, setUrl ] = useState( '' );
|
|
87
|
+
export default meta;
|
|
12
88
|
|
|
13
|
-
|
|
14
|
-
|
|
89
|
+
export const Default = {
|
|
90
|
+
render: function Template( { onClose, ...args } ) {
|
|
91
|
+
const [ isVisible, setIsVisible ] = useState( true );
|
|
92
|
+
const [ url, setUrl ] = useState( '' );
|
|
93
|
+
const [ isOpenInNewTab, setIsOpenInNewTab ] = useState( false );
|
|
15
94
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
95
|
+
// Close the popover.
|
|
96
|
+
const closePopover = () => setIsVisible( false );
|
|
19
97
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
>
|
|
26
|
-
Edit URL
|
|
27
|
-
</Button>
|
|
28
|
-
{ isVisible && (
|
|
29
|
-
<URLPopover
|
|
30
|
-
onClose={ close }
|
|
31
|
-
renderSettings={ () => (
|
|
32
|
-
<ToggleControl
|
|
33
|
-
label={ __( 'Open in new tab' ) }
|
|
34
|
-
onChange={ setTarget }
|
|
35
|
-
/>
|
|
36
|
-
) }
|
|
98
|
+
return (
|
|
99
|
+
<>
|
|
100
|
+
<Button
|
|
101
|
+
__next40pxDefaultSize
|
|
102
|
+
onClick={ () => setIsVisible( true ) }
|
|
37
103
|
>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
104
|
+
{ __( 'Edit URL' ) }
|
|
105
|
+
</Button>
|
|
106
|
+
{ isVisible && (
|
|
107
|
+
<URLPopover
|
|
108
|
+
{ ...args }
|
|
109
|
+
onClose={ ( ...closeArgs ) => {
|
|
110
|
+
onClose( ...closeArgs );
|
|
111
|
+
closePopover();
|
|
112
|
+
} }
|
|
113
|
+
renderSettings={ () => (
|
|
114
|
+
<ToggleControl
|
|
115
|
+
label={ __( 'Open in new tab' ) }
|
|
116
|
+
checked={ isOpenInNewTab }
|
|
117
|
+
onChange={ setIsOpenInNewTab }
|
|
118
|
+
/>
|
|
119
|
+
) }
|
|
120
|
+
>
|
|
121
|
+
<form
|
|
122
|
+
onSubmit={ ( e ) => {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
closePopover();
|
|
125
|
+
} }
|
|
126
|
+
>
|
|
127
|
+
<input
|
|
128
|
+
type="url"
|
|
129
|
+
placeholder={ __( 'Enter URL' ) }
|
|
130
|
+
value={ url }
|
|
131
|
+
onChange={ ( e ) => setUrl( e.target.value ) }
|
|
132
|
+
/>
|
|
133
|
+
<Button
|
|
134
|
+
__next40pxDefaultSize
|
|
135
|
+
icon={ keyboardReturn }
|
|
136
|
+
label={ __( 'Apply' ) }
|
|
137
|
+
type="submit"
|
|
138
|
+
/>
|
|
139
|
+
</form>
|
|
140
|
+
</URLPopover>
|
|
141
|
+
) }
|
|
142
|
+
</>
|
|
143
|
+
);
|
|
144
|
+
},
|
|
59
145
|
};
|