@wordpress/block-editor 15.9.1-next.8b30e05b0.0 → 15.10.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 +2 -0
- package/README.md +8 -0
- package/build/components/block-alignment-matrix-control/index.js +1 -8
- package/build/components/block-alignment-matrix-control/index.js.map +2 -2
- package/build/components/block-bindings/attribute-control.js +172 -0
- package/build/components/block-bindings/attribute-control.js.map +7 -0
- package/build/components/block-bindings/index.js +47 -0
- package/build/components/block-bindings/index.js.map +7 -0
- package/build/components/block-bindings/source-fields-list.js +135 -0
- package/build/components/block-bindings/source-fields-list.js.map +7 -0
- package/build/components/block-bindings/use-block-bindings-utils.js +66 -0
- package/build/components/block-bindings/use-block-bindings-utils.js.map +7 -0
- package/build/components/block-edit/edit.js +1 -3
- package/build/components/block-edit/edit.js.map +2 -2
- package/build/components/block-inspector/edit-contents.js +93 -14
- package/build/components/block-inspector/edit-contents.js.map +3 -3
- package/build/components/block-inspector/index.js +44 -28
- package/build/components/block-inspector/index.js.map +2 -2
- package/build/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
- package/build/components/block-settings-menu-controls/edit-section-menu-item.js.map +3 -3
- package/build/components/block-styles/preview-panel.js +3 -5
- package/build/components/block-styles/preview-panel.js.map +2 -2
- package/build/components/block-styles/use-styles-for-block.js +2 -2
- package/build/components/block-styles/use-styles-for-block.js.map +2 -2
- package/build/components/block-toolbar/index.js +1 -8
- package/build/components/block-toolbar/index.js.map +3 -3
- package/build/components/content-only-controls/index.js +2 -25
- package/build/components/content-only-controls/index.js.map +2 -2
- package/build/components/content-only-controls/link/index.js +3 -3
- package/build/components/content-only-controls/link/index.js.map +2 -2
- package/build/components/content-only-controls/media/index.js +3 -3
- package/build/components/content-only-controls/media/index.js.map +2 -2
- package/build/components/content-only-controls/rich-text/index.js +3 -2
- package/build/components/content-only-controls/rich-text/index.js.map +2 -2
- package/build/components/dimensions-tool/width-height-tool.js +4 -16
- package/build/components/dimensions-tool/width-height-tool.js.map +3 -3
- package/build/components/grid/grid-item-resizer.js +9 -5
- package/build/components/grid/grid-item-resizer.js.map +2 -2
- package/build/components/image-editor/cropper.js +3 -34
- package/build/components/image-editor/cropper.js.map +3 -3
- package/build/components/image-editor/index.js +9 -3
- package/build/components/image-editor/index.js.map +2 -2
- package/build/components/image-editor/use-transform-image.js +62 -32
- package/build/components/image-editor/use-transform-image.js.map +2 -2
- package/build/components/image-editor/zoom-dropdown.js +2 -2
- package/build/components/image-editor/zoom-dropdown.js.map +2 -2
- package/build/components/index.js +7 -3
- package/build/components/index.js.map +2 -2
- package/build/components/inserter/hooks/use-insertion-point.js +5 -2
- package/build/components/inserter/hooks/use-insertion-point.js.map +2 -2
- package/build/components/inserter-draggable-blocks/index.js +8 -4
- package/build/components/inserter-draggable-blocks/index.js.map +2 -2
- package/build/components/inspector-controls-tabs/content-tab.js +3 -2
- package/build/components/inspector-controls-tabs/content-tab.js.map +2 -2
- package/build/components/link-control/index.js +1 -1
- package/build/components/link-control/index.js.map +2 -2
- package/build/components/link-control/search-input.js +2 -2
- package/build/components/link-control/search-input.js.map +2 -2
- package/build/hooks/block-bindings.js +22 -260
- package/build/hooks/block-bindings.js.map +3 -3
- package/build/layouts/grid.js +23 -28
- package/build/layouts/grid.js.map +2 -2
- package/build/private-apis.js +1 -0
- package/build/private-apis.js.map +2 -2
- package/build/store/private-keys.js +3 -0
- package/build/store/private-keys.js.map +2 -2
- package/build/store/private-selectors.js +2 -1
- package/build/store/private-selectors.js.map +2 -2
- package/build/store/reducer.js +3 -2
- package/build/store/reducer.js.map +2 -2
- package/build/utils/block-bindings.js +2 -44
- package/build/utils/block-bindings.js.map +3 -3
- package/build/utils/index.js +2 -5
- package/build/utils/index.js.map +2 -2
- package/build-module/components/block-alignment-matrix-control/index.js +1 -8
- package/build-module/components/block-alignment-matrix-control/index.js.map +2 -2
- package/build-module/components/block-bindings/attribute-control.js +150 -0
- package/build-module/components/block-bindings/attribute-control.js.map +7 -0
- package/build-module/components/block-bindings/index.js +10 -0
- package/build-module/components/block-bindings/index.js.map +7 -0
- package/build-module/components/block-bindings/source-fields-list.js +104 -0
- package/build-module/components/block-bindings/source-fields-list.js.map +7 -0
- package/build-module/components/block-bindings/use-block-bindings-utils.js +45 -0
- package/build-module/components/block-bindings/use-block-bindings-utils.js.map +7 -0
- package/build-module/components/block-edit/edit.js +1 -3
- package/build-module/components/block-edit/edit.js.map +2 -2
- package/build-module/components/block-inspector/edit-contents.js +93 -14
- package/build-module/components/block-inspector/edit-contents.js.map +2 -2
- package/build-module/components/block-inspector/index.js +44 -28
- package/build-module/components/block-inspector/index.js.map +2 -2
- package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
- package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js.map +2 -2
- package/build-module/components/block-styles/preview-panel.js +3 -5
- package/build-module/components/block-styles/preview-panel.js.map +2 -2
- package/build-module/components/block-styles/use-styles-for-block.js +2 -2
- package/build-module/components/block-styles/use-styles-for-block.js.map +2 -2
- package/build-module/components/block-toolbar/index.js +1 -8
- package/build-module/components/block-toolbar/index.js.map +2 -2
- package/build-module/components/content-only-controls/index.js +2 -25
- package/build-module/components/content-only-controls/index.js.map +2 -2
- package/build-module/components/content-only-controls/link/index.js +3 -3
- package/build-module/components/content-only-controls/link/index.js.map +2 -2
- package/build-module/components/content-only-controls/media/index.js +3 -3
- package/build-module/components/content-only-controls/media/index.js.map +2 -2
- package/build-module/components/content-only-controls/rich-text/index.js +3 -2
- package/build-module/components/content-only-controls/rich-text/index.js.map +2 -2
- package/build-module/components/dimensions-tool/width-height-tool.js +4 -6
- package/build-module/components/dimensions-tool/width-height-tool.js.map +2 -2
- package/build-module/components/grid/grid-item-resizer.js +9 -5
- package/build-module/components/grid/grid-item-resizer.js.map +2 -2
- package/build-module/components/image-editor/cropper.js +3 -34
- package/build-module/components/image-editor/cropper.js.map +2 -2
- package/build-module/components/image-editor/index.js +9 -3
- package/build-module/components/image-editor/index.js.map +2 -2
- package/build-module/components/image-editor/use-transform-image.js +63 -33
- package/build-module/components/image-editor/use-transform-image.js.map +2 -2
- package/build-module/components/image-editor/zoom-dropdown.js +2 -2
- package/build-module/components/image-editor/zoom-dropdown.js.map +2 -2
- package/build-module/components/index.js +74 -68
- package/build-module/components/index.js.map +2 -2
- package/build-module/components/inserter/hooks/use-insertion-point.js +5 -2
- package/build-module/components/inserter/hooks/use-insertion-point.js.map +2 -2
- package/build-module/components/inserter-draggable-blocks/index.js +8 -4
- package/build-module/components/inserter-draggable-blocks/index.js.map +2 -2
- package/build-module/components/inspector-controls-tabs/content-tab.js +3 -2
- package/build-module/components/inspector-controls-tabs/content-tab.js.map +2 -2
- package/build-module/components/link-control/index.js +1 -1
- package/build-module/components/link-control/index.js.map +2 -2
- package/build-module/components/link-control/search-input.js +2 -2
- package/build-module/components/link-control/search-input.js.map +2 -2
- package/build-module/hooks/block-bindings.js +27 -270
- package/build-module/hooks/block-bindings.js.map +2 -2
- package/build-module/layouts/grid.js +23 -28
- package/build-module/layouts/grid.js.map +2 -2
- package/build-module/private-apis.js +3 -1
- package/build-module/private-apis.js.map +2 -2
- package/build-module/store/private-keys.js +2 -0
- package/build-module/store/private-keys.js.map +2 -2
- package/build-module/store/private-selectors.js +4 -2
- package/build-module/store/private-selectors.js.map +2 -2
- package/build-module/store/reducer.js +4 -3
- package/build-module/store/reducer.js.map +2 -2
- package/build-module/utils/block-bindings.js +1 -42
- package/build-module/utils/block-bindings.js.map +2 -2
- package/build-module/utils/index.js +1 -3
- package/build-module/utils/index.js.map +2 -2
- package/build-style/style-rtl.css +6 -6
- package/build-style/style.css +6 -6
- package/package.json +39 -40
- package/src/components/block-alignment-matrix-control/index.js +1 -5
- package/src/components/block-bindings/attribute-control.js +174 -0
- package/src/components/block-bindings/index.js +6 -0
- package/src/components/block-bindings/source-fields-list.js +130 -0
- package/src/components/block-bindings/use-block-bindings-utils.js +156 -0
- package/src/components/block-edit/edit.js +1 -3
- package/src/components/block-inspector/edit-contents.js +108 -18
- package/src/components/block-inspector/index.js +53 -30
- package/src/components/block-settings-menu-controls/edit-section-menu-item.js +50 -6
- package/src/components/block-styles/preview-panel.js +3 -5
- package/src/components/block-styles/use-styles-for-block.js +2 -2
- package/src/components/block-toolbar/index.js +1 -6
- package/src/components/block-toolbar/style.scss +6 -6
- package/src/components/content-only-controls/index.js +2 -27
- package/src/components/content-only-controls/link/index.js +3 -3
- package/src/components/content-only-controls/media/index.js +3 -3
- package/src/components/content-only-controls/rich-text/index.js +3 -2
- package/src/components/dimensions-tool/width-height-tool.js +6 -13
- package/src/components/grid/grid-item-resizer.js +18 -5
- package/src/components/image-editor/cropper.js +3 -32
- package/src/components/image-editor/index.js +34 -29
- package/src/components/image-editor/use-transform-image.js +80 -34
- package/src/components/image-editor/zoom-dropdown.js +2 -2
- package/src/components/index.js +5 -1
- package/src/components/inserter/hooks/use-insertion-point.js +3 -0
- package/src/components/inserter/style.scss +1 -1
- package/src/components/inserter-draggable-blocks/index.js +19 -8
- package/src/components/inspector-controls-tabs/content-tab.js +6 -2
- package/src/components/link-control/index.js +1 -1
- package/src/components/link-control/search-input.js +8 -2
- package/src/components/link-control/test/index.js +146 -7
- package/src/hooks/block-bindings.js +27 -347
- package/src/layouts/grid.js +40 -72
- package/src/layouts/test/grid.js +14 -0
- package/src/private-apis.js +2 -0
- package/src/store/private-keys.js +1 -0
- package/src/store/private-selectors.js +8 -1
- package/src/store/reducer.js +10 -3
- package/src/utils/block-bindings.js +0 -157
- package/src/utils/index.js +0 -1
- package/tsconfig.json +1 -0
- package/build/components/block-toolbar/block-name-context.js +0 -30
- package/build/components/block-toolbar/block-name-context.js.map +0 -7
- package/build-module/components/block-toolbar/block-name-context.js +0 -9
- package/build-module/components/block-toolbar/block-name-context.js.map +0 -7
- package/src/components/block-toolbar/block-name-context.js +0 -9
- /package/src/{utils → components/block-bindings}/test/use-block-bindings-utils.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/link-control/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tSpinner,\n\tNotice,\n\tTextControl,\n\t__experimentalHStack as HStack,\n\t__experimentalInputControlSuffixWrapper as InputControlSuffixWrapper,\n} from '@wordpress/components';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { useRef, useState, useEffect, useMemo } from '@wordpress/element';\nimport { useInstanceId } from '@wordpress/compose';\nimport { focus } from '@wordpress/dom';\nimport { ENTER } from '@wordpress/keycodes';\nimport { isShallowEqualObjects } from '@wordpress/is-shallow-equal';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport { keyboardReturn, linkOff } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport LinkControlSettingsDrawer from './settings-drawer';\nimport LinkControlSearchInput from './search-input';\nimport LinkPreview from './link-preview';\nimport LinkSettings from './settings';\nimport useCreatePage from './use-create-page';\nimport useInternalValue from './use-internal-value';\nimport { ViewerFill } from './viewer-slot';\nimport { DEFAULT_LINK_SETTINGS } from './constants';\nimport deprecated from '@wordpress/deprecated';\n\n/**\n * Default properties associated with a link control value.\n *\n * @typedef WPLinkControlDefaultValue\n *\n * @property {string} url Link URL.\n * @property {string=} title Link title.\n * @property {boolean=} opensInNewTab Whether link should open in a new browser\n * tab. This value is only assigned if not\n * providing a custom `settings` prop.\n */\n\n/**\n * Custom settings values associated with a link.\n *\n * @typedef {{[setting:string]:any}} WPLinkControlSettingsValue\n */\n\n/**\n * Custom settings values associated with a link.\n *\n * @typedef WPLinkControlSetting\n *\n * @property {string} id Identifier to use as property for setting value.\n * @property {string} title Human-readable label to show in user interface.\n */\n\n/**\n * Properties associated with a link control value, composed as a union of the\n * default properties and any custom settings values.\n *\n * @typedef {WPLinkControlDefaultValue&WPLinkControlSettingsValue} WPLinkControlValue\n */\n\n/** @typedef {(nextValue:WPLinkControlValue)=>void} WPLinkControlOnChangeProp */\n\n/**\n * Properties associated with a search suggestion used within the LinkControl.\n *\n * @typedef WPLinkControlSuggestion\n *\n * @property {string} id Identifier to use to uniquely identify the suggestion.\n * @property {string} type Identifies the type of the suggestion (eg: `post`,\n * `page`, `url`...etc)\n * @property {string} title Human-readable label to show in user interface.\n * @property {string} url A URL for the suggestion.\n */\n\n/** @typedef {(title:string)=>WPLinkControlSuggestion} WPLinkControlCreateSuggestionProp */\n\n/**\n * @typedef WPLinkControlProps\n *\n * @property {(WPLinkControlSetting[])=} settings An array of settings objects. Each object will used to\n * render a `ToggleControl` for that setting.\n * @property {boolean=} forceIsEditingLink If passed as either `true` or `false`, controls the\n * internal editing state of the component to respective\n * show or not show the URL input field.\n * @property {WPLinkControlValue=} value Current link value.\n * @property {WPLinkControlOnChangeProp=} onChange Value change handler, called with the updated value if\n * the user selects a new link or updates settings.\n * @property {boolean=} noDirectEntry Whether to allow turning a URL-like search query directly into a link.\n * @property {boolean=} showSuggestions Whether to present suggestions when typing the URL.\n * @property {boolean=} showInitialSuggestions Whether to present initial suggestions immediately.\n * @property {boolean=} withCreateSuggestion Whether to allow creation of link value from suggestion.\n * @property {Object=} suggestionsQuery Query parameters to pass along to wp.blockEditor.__experimentalFetchLinkSuggestions.\n * @property {boolean=} noURLSuggestion Whether to add a fallback suggestion which treats the search query as a URL.\n * @property {boolean=} hasTextControl Whether to add a text field to the UI to update the value.title.\n * @property {string|Function|undefined} createSuggestionButtonText The text to use in the button that calls createSuggestion.\n * @property {Function} renderControlBottom Optional controls to be rendered at the bottom of the component.\n * @property {boolean=} handleEntities Whether to handle entity links (links with ID). When true and a link has an ID, the input will be disabled and show an unlink button.\n */\n\nconst noop = () => {};\n\nconst PREFERENCE_SCOPE = 'core/block-editor';\nconst PREFERENCE_KEY = 'linkControlSettingsDrawer';\n\n/**\n * Renders a link control. A link control is a controlled input which maintains\n * a value associated with a link (HTML anchor element) and relevant settings\n * for how that link is expected to behave.\n *\n * @param {WPLinkControlProps} props Component props.\n */\nfunction LinkControl( {\n\tsearchInputPlaceholder,\n\tvalue,\n\tsettings = DEFAULT_LINK_SETTINGS,\n\tonChange = noop,\n\tonRemove,\n\tonCancel,\n\tnoDirectEntry = false,\n\tshowSuggestions = true,\n\tshowInitialSuggestions,\n\tforceIsEditingLink,\n\tcreateSuggestion,\n\twithCreateSuggestion,\n\tinputValue: propInputValue = '',\n\tsuggestionsQuery = {},\n\tnoURLSuggestion = false,\n\tcreateSuggestionButtonText,\n\thasRichPreviews = false,\n\thasTextControl = false,\n\trenderControlBottom = null,\n\thandleEntities = false,\n} ) {\n\tif ( withCreateSuggestion === undefined && createSuggestion ) {\n\t\twithCreateSuggestion = true;\n\t}\n\n\tconst [ settingsOpen, setSettingsOpen ] = useState( false );\n\n\tconst { advancedSettingsPreference } = useSelect( ( select ) => {\n\t\tconst prefsStore = select( preferencesStore );\n\n\t\treturn {\n\t\t\tadvancedSettingsPreference:\n\t\t\t\tprefsStore.get( PREFERENCE_SCOPE, PREFERENCE_KEY ) ?? false,\n\t\t};\n\t}, [] );\n\n\tconst { set: setPreference } = useDispatch( preferencesStore );\n\n\t/**\n\t * Sets the open/closed state of the Advanced Settings Drawer,\n\t * optionlly persisting the state to the user's preferences.\n\t *\n\t * Note that Block Editor components can be consumed by non-WordPress\n\t * environments which may not have preferences setup.\n\t * Therefore a local state is also used as a fallback.\n\t *\n\t * @param {boolean} prefVal the open/closed state of the Advanced Settings Drawer.\n\t */\n\tconst setSettingsOpenWithPreference = ( prefVal ) => {\n\t\tif ( setPreference ) {\n\t\t\tsetPreference( PREFERENCE_SCOPE, PREFERENCE_KEY, prefVal );\n\t\t}\n\t\tsetSettingsOpen( prefVal );\n\t};\n\n\t// Block Editor components can be consumed by non-WordPress environments\n\t// which may not have these preferences setup.\n\t// Therefore a local state is used as a fallback.\n\tconst isSettingsOpen = advancedSettingsPreference || settingsOpen;\n\n\tconst isMountingRef = useRef( true );\n\tconst wrapperNode = useRef();\n\tconst textInputRef = useRef();\n\tconst searchInputRef = useRef();\n\t// TODO: Remove entityUrlFallbackRef and previewValue in favor of value prop after taxonomy entity binding\n\t// is stable and returns the correct URL instead of null while resolving when creating the entity.\n\t//\n\t// Preserve the URL from entity suggestions before binding overrides it\n\t// This is due to entity binding not being available immediately after the suggestion is selected.\n\t// The URL can return null, especially for taxonomy entities, while entity binding is being resolved.\n\t// To avoid unnecessary rerenders and focus loss, we preserve the URL from the suggestion and use it\n\t// as a fallback until the entity binding is available.\n\tconst entityUrlFallbackRef = useRef();\n\n\tconst settingsKeys = settings.map( ( { id } ) => id );\n\n\tconst [\n\t\tinternalControlValue,\n\t\tsetInternalControlValue,\n\t\tsetInternalURLInputValue,\n\t\tsetInternalTextInputValue,\n\t\tcreateSetInternalSettingValueHandler,\n\t] = useInternalValue( value );\n\n\t// Compute isEntity internally based on handleEntities prop and presence of ID\n\tconst isEntity = handleEntities && !! internalControlValue?.id;\n\n\t// Generate help text ID for accessibility association\n\tconst baseId = useInstanceId( LinkControl, 'link-control' );\n\tconst helpTextId = isEntity ? `${ baseId }__help` : null;\n\n\tconst valueHasChanges =\n\t\tvalue && ! isShallowEqualObjects( internalControlValue, value );\n\n\tconst [ isEditingLink, setIsEditingLink ] = useState(\n\t\tforceIsEditingLink !== undefined\n\t\t\t? forceIsEditingLink\n\t\t\t: ! value || ! value.url\n\t);\n\n\tconst { createPage, isCreatingPage, errorMessage } =\n\t\tuseCreatePage( createSuggestion );\n\n\tuseEffect( () => {\n\t\tif ( forceIsEditingLink === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsEditingLink( forceIsEditingLink );\n\t}, [ forceIsEditingLink ] );\n\n\tuseEffect( () => {\n\t\t// We don't auto focus into the Link UI on mount\n\t\t// because otherwise using the keyboard to select text\n\t\t// *within* the link format is not possible.\n\t\tif ( isMountingRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Scenario - when:\n\t\t// - switching between editable and non editable LinkControl\n\t\t// - clicking on a link\n\t\t// ...then move focus to the *first* element to avoid focus loss\n\t\t// and to ensure focus is *within* the Link UI.\n\t\tconst nextFocusTarget =\n\t\t\tfocus.focusable.find( wrapperNode.current )[ 0 ] ||\n\t\t\twrapperNode.current;\n\n\t\tnextFocusTarget.focus();\n\t}, [ isEditingLink, isCreatingPage ] );\n\n\t// The component mounting reference is maintained separately\n\t// to correctly reset values in `StrictMode`.\n\tuseEffect( () => {\n\t\tisMountingRef.current = false;\n\n\t\treturn () => {\n\t\t\tisMountingRef.current = true;\n\t\t};\n\t}, [] );\n\n\tconst hasLinkValue = value?.url?.trim()?.length > 0;\n\n\t/**\n\t * Cancels editing state.\n\t */\n\tconst stopEditing = () => {\n\t\tsetIsEditingLink( false );\n\t};\n\n\tconst handleSelectSuggestion = ( updatedValue ) => {\n\t\t// Preserve the URL for taxonomy entities before binding overrides it\n\t\tif ( updatedValue?.kind === 'taxonomy' && updatedValue?.url ) {\n\t\t\tentityUrlFallbackRef.current = updatedValue.url;\n\t\t}\n\n\t\t// Suggestions may contains \"settings\" values (e.g. `opensInNewTab`)\n\t\t// which should not override any existing settings values set by the\n\t\t// user. This filters out any settings values from the suggestion.\n\t\tconst nonSettingsChanges = Object.keys( updatedValue ).reduce(\n\t\t\t( acc, key ) => {\n\t\t\t\tif ( ! settingsKeys.includes( key ) ) {\n\t\t\t\t\tacc[ key ] = updatedValue[ key ];\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{}\n\t\t);\n\n\t\tonChange( {\n\t\t\t...internalControlValue,\n\t\t\t...nonSettingsChanges,\n\t\t\t// As title is not a setting, it must be manually applied\n\t\t\t// in such a way as to preserve the users changes over\n\t\t\t// any \"title\" value provided by the \"suggestion\".\n\t\t\ttitle: internalControlValue?.title || updatedValue?.title,\n\t\t} );\n\n\t\tstopEditing();\n\t};\n\n\tconst handleSubmit = () => {\n\t\tif ( valueHasChanges ) {\n\t\t\t// Submit the original value with new stored values applied\n\t\t\t// on top. URL is a special case as it may also be a prop.\n\t\t\tonChange( {\n\t\t\t\t...value,\n\t\t\t\t...internalControlValue,\n\t\t\t\turl: currentUrlInputValue,\n\t\t\t} );\n\t\t}\n\t\tstopEditing();\n\t};\n\n\tconst handleSubmitWithEnter = ( event ) => {\n\t\tconst { keyCode } = event;\n\n\t\tif (\n\t\t\tkeyCode === ENTER &&\n\t\t\t! currentInputIsEmpty // Disallow submitting empty values.\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t\thandleSubmit();\n\t\t}\n\t};\n\n\tconst resetInternalValues = () => {\n\t\tsetInternalControlValue( value );\n\t};\n\n\tconst handleCancel = ( event ) => {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\t// Ensure that any unsubmitted input changes are reset.\n\t\tresetInternalValues();\n\n\t\tif ( hasLinkValue ) {\n\t\t\t// If there is a link then exist editing mode and show preview.\n\t\t\tstopEditing();\n\t\t} else {\n\t\t\t// If there is no link value, then remove the link entirely.\n\t\t\tonRemove?.();\n\t\t}\n\n\t\tonCancel?.();\n\t};\n\n\tconst [ shouldFocusSearchInput, setShouldFocusSearchInput ] =\n\t\tuseState( false );\n\n\tconst handleUnlink = () => {\n\t\t// Clear the internal state to remove the ID and re-enable the field\n\t\t// Explicitly set id, kind, and type to undefined so they override\n\t\t// the original values when spread in handleSubmit. This ensures that\n\t\t// when the user types a custom URL and submits, the entity link is\n\t\t// properly severed (not just when selecting a different entity from suggestions).\n\t\tconst { id, kind, type, ...restValue } = internalControlValue;\n\t\tsetInternalControlValue( {\n\t\t\t...restValue,\n\t\t\tid: undefined,\n\t\t\tkind: undefined,\n\t\t\ttype: undefined,\n\t\t\turl: undefined,\n\t\t} );\n\n\t\t// Request focus after the component re-renders with the cleared state\n\t\t// We can't focus immediately because the input might still be disabled\n\t\tsetShouldFocusSearchInput( true );\n\t};\n\n\t// Focus the search input when requested, once the component has re-rendered\n\t// This ensures the input is enabled and ready to receive focus\n\tuseEffect( () => {\n\t\tif ( shouldFocusSearchInput ) {\n\t\t\tsearchInputRef.current?.focus();\n\t\t\tsetShouldFocusSearchInput( false );\n\t\t}\n\t}, [ shouldFocusSearchInput ] );\n\n\tconst currentUrlInputValue =\n\t\tpropInputValue || internalControlValue?.url || '';\n\n\tconst currentInputIsEmpty = ! currentUrlInputValue?.trim()?.length;\n\n\tconst shownUnlinkControl =\n\t\tonRemove && value && ! isEditingLink && ! isCreatingPage;\n\n\tconst showActions = isEditingLink && hasLinkValue;\n\n\t// Only show text control once a URL value has been committed\n\t// and it isn't just empty whitespace.\n\t// See https://github.com/WordPress/gutenberg/pull/33849/#issuecomment-932194927.\n\tconst showTextControl = hasLinkValue && hasTextControl;\n\n\tconst isEditing = ( isEditingLink || ! value ) && ! isCreatingPage;\n\tconst isDisabled = ! valueHasChanges || currentInputIsEmpty;\n\tconst showSettings = !! settings?.length && isEditingLink && hasLinkValue;\n\n\tconst previewValue = useMemo( () => {\n\t\t// There is a chance that the value is not yet set from the entity binding, so we use the preserved URL.\n\t\tif (\n\t\t\tvalue?.kind === 'taxonomy' &&\n\t\t\t! value?.url &&\n\t\t\tentityUrlFallbackRef.current\n\t\t) {\n\t\t\t// combine the value prop with the preserved URL from the suggestion\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t\turl: entityUrlFallbackRef.current,\n\t\t\t};\n\t\t}\n\n\t\t// If we don't have a fallback URL, use the value prop.\n\t\treturn value;\n\t}, [ value ] );\n\n\treturn (\n\t\t<div\n\t\t\ttabIndex={ -1 }\n\t\t\tref={ wrapperNode }\n\t\t\tclassName=\"block-editor-link-control\"\n\t\t>\n\t\t\t{ isCreatingPage && (\n\t\t\t\t<div className=\"block-editor-link-control__loading\">\n\t\t\t\t\t<Spinner /> { __( 'Creating' ) }\u2026\n\t\t\t\t</div>\n\t\t\t) }\n\n\t\t\t{ isEditing && (\n\t\t\t\t<>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={ clsx( {\n\t\t\t\t\t\t\t'block-editor-link-control__search-input-wrapper': true,\n\t\t\t\t\t\t\t'has-text-control': showTextControl,\n\t\t\t\t\t\t\t'has-actions': showActions,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ showTextControl && (\n\t\t\t\t\t\t\t<TextControl\n\t\t\t\t\t\t\t\t__nextHasNoMarginBottom\n\t\t\t\t\t\t\t\tref={ textInputRef }\n\t\t\t\t\t\t\t\tclassName=\"block-editor-link-control__field block-editor-link-control__text-content\"\n\t\t\t\t\t\t\t\tlabel={ __( 'Text' ) }\n\t\t\t\t\t\t\t\tvalue={ internalControlValue?.title }\n\t\t\t\t\t\t\t\tonChange={ setInternalTextInputValue }\n\t\t\t\t\t\t\t\tonKeyDown={ handleSubmitWithEnter }\n\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<LinkControlSearchInput\n\t\t\t\t\t\t\tref={ searchInputRef }\n\t\t\t\t\t\t\tcurrentLink={ value }\n\t\t\t\t\t\t\tclassName=\"block-editor-link-control__field block-editor-link-control__search-input\"\n\t\t\t\t\t\t\tplaceholder={ searchInputPlaceholder }\n\t\t\t\t\t\t\tvalue={ currentUrlInputValue }\n\t\t\t\t\t\t\twithCreateSuggestion={ withCreateSuggestion }\n\t\t\t\t\t\t\tonCreateSuggestion={ createPage }\n\t\t\t\t\t\t\tonChange={ setInternalURLInputValue }\n\t\t\t\t\t\t\tonSelect={ handleSelectSuggestion }\n\t\t\t\t\t\t\tshowInitialSuggestions={ showInitialSuggestions }\n\t\t\t\t\t\t\tallowDirectEntry={ ! noDirectEntry }\n\t\t\t\t\t\t\tshowSuggestions={ showSuggestions }\n\t\t\t\t\t\t\tsuggestionsQuery={ suggestionsQuery }\n\t\t\t\t\t\t\twithURLSuggestion={ ! noURLSuggestion }\n\t\t\t\t\t\t\tcreateSuggestionButtonText={\n\t\t\t\t\t\t\t\tcreateSuggestionButtonText\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\thideLabelFromVision={ ! showTextControl }\n\t\t\t\t\t\t\tisEntity={ isEntity }\n\t\t\t\t\t\t\tsuffix={\n\t\t\t\t\t\t\t\t<SearchSuffixControl\n\t\t\t\t\t\t\t\t\tisEntity={ isEntity }\n\t\t\t\t\t\t\t\t\tshowActions={ showActions }\n\t\t\t\t\t\t\t\t\tisDisabled={ isDisabled }\n\t\t\t\t\t\t\t\t\tonUnlink={ handleUnlink }\n\t\t\t\t\t\t\t\t\tonSubmit={ handleSubmit }\n\t\t\t\t\t\t\t\t\thelpTextId={ helpTextId }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ isEntity && helpTextId && (\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tid={ helpTextId }\n\t\t\t\t\t\t\t\tclassName=\"block-editor-link-control__help\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{ sprintf(\n\t\t\t\t\t\t\t\t\t/* translators: %s: entity type (e.g., page, post) */\n\t\t\t\t\t\t\t\t\t__( 'Synced with the selected %s.' ),\n\t\t\t\t\t\t\t\t\tinternalControlValue?.type || 'item'\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t\t{ errorMessage && (\n\t\t\t\t\t\t<Notice\n\t\t\t\t\t\t\tclassName=\"block-editor-link-control__search-error\"\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\tisDismissible={ false }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ errorMessage }\n\t\t\t\t\t\t</Notice>\n\t\t\t\t\t) }\n\t\t\t\t</>\n\t\t\t) }\n\n\t\t\t{ value && ! isEditingLink && ! isCreatingPage && (\n\t\t\t\t<LinkPreview\n\t\t\t\t\tkey={ previewValue?.url } // force remount when URL changes to avoid race conditions for rich previews\n\t\t\t\t\tvalue={ previewValue }\n\t\t\t\t\tonEditClick={ () => setIsEditingLink( true ) }\n\t\t\t\t\thasRichPreviews={ hasRichPreviews }\n\t\t\t\t\thasUnlinkControl={ shownUnlinkControl }\n\t\t\t\t\tonRemove={ () => {\n\t\t\t\t\t\tonRemove();\n\t\t\t\t\t\tsetIsEditingLink( true );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\n\t\t\t{ showSettings && (\n\t\t\t\t<div className=\"block-editor-link-control__tools\">\n\t\t\t\t\t{ ! currentInputIsEmpty && (\n\t\t\t\t\t\t<LinkControlSettingsDrawer\n\t\t\t\t\t\t\tsettingsOpen={ isSettingsOpen }\n\t\t\t\t\t\t\tsetSettingsOpen={ setSettingsOpenWithPreference }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<LinkSettings\n\t\t\t\t\t\t\t\tvalue={ internalControlValue }\n\t\t\t\t\t\t\t\tsettings={ settings }\n\t\t\t\t\t\t\t\tonChange={ createSetInternalSettingValueHandler(\n\t\t\t\t\t\t\t\t\tsettingsKeys\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</LinkControlSettingsDrawer>\n\t\t\t\t\t) }\n\t\t\t\t</div>\n\t\t\t) }\n\n\t\t\t{ showActions && (\n\t\t\t\t<HStack\n\t\t\t\t\tjustify=\"right\"\n\t\t\t\t\tclassName=\"block-editor-link-control__search-actions\"\n\t\t\t\t>\n\t\t\t\t\t<Button\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\tonClick={ handleCancel }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Cancel' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\tonClick={ isDisabled ? noop : handleSubmit }\n\t\t\t\t\t\tclassName=\"block-editor-link-control__search-submit\"\n\t\t\t\t\t\taria-disabled={ isDisabled }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Apply' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t) }\n\n\t\t\t{ ! isCreatingPage && renderControlBottom && renderControlBottom() }\n\t\t</div>\n\t);\n}\n\n/**\n * Suffix control component for LinkControl search input.\n * Handles the display of unlink button for entities and submit button for regular links.\n *\n * @param {Object} props - Component props\n * @param {boolean} props.isEntity - Whether the link is bound to an entity\n * @param {boolean} props.showActions - Whether to show action buttons\n * @param {boolean} props.isDisabled - Whether the submit button should be disabled\n * @param {Function} props.onUnlink - Callback when unlink button is clicked\n * @param {Function} props.onSubmit - Callback when submit button is clicked\n * @param {string} props.helpTextId - ID of the help text element for accessibility\n */\nfunction SearchSuffixControl( {\n\tisEntity,\n\tshowActions,\n\tisDisabled,\n\tonUnlink,\n\tonSubmit,\n\thelpTextId,\n} ) {\n\tif ( isEntity ) {\n\t\treturn (\n\t\t\t<Button\n\t\t\t\ticon={ linkOff }\n\t\t\t\tonClick={ onUnlink }\n\t\t\t\taria-describedby={ helpTextId }\n\t\t\t\tshowTooltip\n\t\t\t\tlabel={ __( 'Unsync and edit' ) }\n\t\t\t\t__next40pxDefaultSize\n\t\t\t/>\n\t\t);\n\t}\n\n\tif ( showActions ) {\n\t\treturn undefined;\n\t}\n\n\treturn (\n\t\t<InputControlSuffixWrapper variant=\"control\">\n\t\t\t<Button\n\t\t\t\tonClick={ isDisabled ? noop : onSubmit }\n\t\t\t\tlabel={ __( 'Submit' ) }\n\t\t\t\ticon={ keyboardReturn }\n\t\t\t\tclassName=\"block-editor-link-control__search-submit\"\n\t\t\t\taria-disabled={ isDisabled }\n\t\t\t\tsize=\"small\"\n\t\t\t/>\n\t\t</InputControlSuffixWrapper>\n\t);\n}\n\nLinkControl.ViewerFill = ViewerFill;\nLinkControl.DEFAULT_LINK_SETTINGS = DEFAULT_LINK_SETTINGS;\n\nconst DeprecatedExperimentalLinkControl = ( props ) => {\n\tdeprecated( 'wp.blockEditor.__experimentalLinkControl', {\n\t\tsince: '6.8',\n\t\talternative: 'wp.blockEditor.LinkControl',\n\t} );\n\n\treturn <LinkControl { ...props } />;\n};\n\nDeprecatedExperimentalLinkControl.ViewerFill = LinkControl.ViewerFill;\nDeprecatedExperimentalLinkControl.DEFAULT_LINK_SETTINGS =\n\tLinkControl.DEFAULT_LINK_SETTINGS;\n\nexport { DeprecatedExperimentalLinkControl };\nexport default LinkControl;\n"],
|
|
5
|
-
"mappings": ";AAGA,OAAO,UAAU;AAKjB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,wBAAwB;AAAA,EACxB,2CAA2C;AAAA,OACrC;AACP,SAAS,IAAI,eAAe;AAC5B,SAAS,QAAQ,UAAU,WAAW,eAAe;AACrD,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,6BAA6B;AACtC,SAAS,WAAW,mBAAmB;AACvC,SAAS,SAAS,wBAAwB;AAC1C,SAAS,gBAAgB,eAAe;
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tSpinner,\n\tNotice,\n\tTextControl,\n\t__experimentalHStack as HStack,\n\t__experimentalInputControlSuffixWrapper as InputControlSuffixWrapper,\n} from '@wordpress/components';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { useRef, useState, useEffect, useMemo } from '@wordpress/element';\nimport { useInstanceId } from '@wordpress/compose';\nimport { focus } from '@wordpress/dom';\nimport { ENTER } from '@wordpress/keycodes';\nimport { isShallowEqualObjects } from '@wordpress/is-shallow-equal';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport { keyboardReturn, linkOff } from '@wordpress/icons';\nimport deprecated from '@wordpress/deprecated';\n\n/**\n * Internal dependencies\n */\nimport LinkControlSettingsDrawer from './settings-drawer';\nimport LinkControlSearchInput from './search-input';\nimport LinkPreview from './link-preview';\nimport LinkSettings from './settings';\nimport useCreatePage from './use-create-page';\nimport useInternalValue from './use-internal-value';\nimport { ViewerFill } from './viewer-slot';\nimport { DEFAULT_LINK_SETTINGS } from './constants';\n\n/**\n * Default properties associated with a link control value.\n *\n * @typedef WPLinkControlDefaultValue\n *\n * @property {string} url Link URL.\n * @property {string=} title Link title.\n * @property {boolean=} opensInNewTab Whether link should open in a new browser\n * tab. This value is only assigned if not\n * providing a custom `settings` prop.\n */\n\n/**\n * Custom settings values associated with a link.\n *\n * @typedef {{[setting:string]:any}} WPLinkControlSettingsValue\n */\n\n/**\n * Custom settings values associated with a link.\n *\n * @typedef WPLinkControlSetting\n *\n * @property {string} id Identifier to use as property for setting value.\n * @property {string} title Human-readable label to show in user interface.\n */\n\n/**\n * Properties associated with a link control value, composed as a union of the\n * default properties and any custom settings values.\n *\n * @typedef {WPLinkControlDefaultValue&WPLinkControlSettingsValue} WPLinkControlValue\n */\n\n/** @typedef {(nextValue:WPLinkControlValue)=>void} WPLinkControlOnChangeProp */\n\n/**\n * Properties associated with a search suggestion used within the LinkControl.\n *\n * @typedef WPLinkControlSuggestion\n *\n * @property {string} id Identifier to use to uniquely identify the suggestion.\n * @property {string} type Identifies the type of the suggestion (eg: `post`,\n * `page`, `url`...etc)\n * @property {string} title Human-readable label to show in user interface.\n * @property {string} url A URL for the suggestion.\n */\n\n/** @typedef {(title:string)=>WPLinkControlSuggestion} WPLinkControlCreateSuggestionProp */\n\n/**\n * @typedef WPLinkControlProps\n *\n * @property {(WPLinkControlSetting[])=} settings An array of settings objects. Each object will used to\n * render a `ToggleControl` for that setting.\n * @property {boolean=} forceIsEditingLink If passed as either `true` or `false`, controls the\n * internal editing state of the component to respective\n * show or not show the URL input field.\n * @property {WPLinkControlValue=} value Current link value.\n * @property {WPLinkControlOnChangeProp=} onChange Value change handler, called with the updated value if\n * the user selects a new link or updates settings.\n * @property {boolean=} noDirectEntry Whether to allow turning a URL-like search query directly into a link.\n * @property {boolean=} showSuggestions Whether to present suggestions when typing the URL.\n * @property {boolean=} showInitialSuggestions Whether to present initial suggestions immediately.\n * @property {boolean=} withCreateSuggestion Whether to allow creation of link value from suggestion.\n * @property {Object=} suggestionsQuery Query parameters to pass along to wp.blockEditor.__experimentalFetchLinkSuggestions.\n * @property {boolean=} noURLSuggestion Whether to add a fallback suggestion which treats the search query as a URL.\n * @property {boolean=} hasTextControl Whether to add a text field to the UI to update the value.title.\n * @property {string|Function|undefined} createSuggestionButtonText The text to use in the button that calls createSuggestion.\n * @property {Function} renderControlBottom Optional controls to be rendered at the bottom of the component.\n * @property {boolean=} handleEntities Whether to handle entity links (links with ID). When true and a link has an ID, the input will be disabled and show an unlink button.\n */\n\nconst noop = () => {};\n\nconst PREFERENCE_SCOPE = 'core/block-editor';\nconst PREFERENCE_KEY = 'linkControlSettingsDrawer';\n\n/**\n * Renders a link control. A link control is a controlled input which maintains\n * a value associated with a link (HTML anchor element) and relevant settings\n * for how that link is expected to behave.\n *\n * @param {WPLinkControlProps} props Component props.\n */\nfunction LinkControl( {\n\tsearchInputPlaceholder,\n\tvalue,\n\tsettings = DEFAULT_LINK_SETTINGS,\n\tonChange = noop,\n\tonRemove,\n\tonCancel,\n\tnoDirectEntry = false,\n\tshowSuggestions = true,\n\tshowInitialSuggestions,\n\tforceIsEditingLink,\n\tcreateSuggestion,\n\twithCreateSuggestion,\n\tinputValue: propInputValue = '',\n\tsuggestionsQuery = {},\n\tnoURLSuggestion = false,\n\tcreateSuggestionButtonText,\n\thasRichPreviews = false,\n\thasTextControl = false,\n\trenderControlBottom = null,\n\thandleEntities = false,\n} ) {\n\tif ( withCreateSuggestion === undefined && createSuggestion ) {\n\t\twithCreateSuggestion = true;\n\t}\n\n\tconst [ settingsOpen, setSettingsOpen ] = useState( false );\n\n\tconst { advancedSettingsPreference } = useSelect( ( select ) => {\n\t\tconst prefsStore = select( preferencesStore );\n\n\t\treturn {\n\t\t\tadvancedSettingsPreference:\n\t\t\t\tprefsStore.get( PREFERENCE_SCOPE, PREFERENCE_KEY ) ?? false,\n\t\t};\n\t}, [] );\n\n\tconst { set: setPreference } = useDispatch( preferencesStore );\n\n\t/**\n\t * Sets the open/closed state of the Advanced Settings Drawer,\n\t * optionlly persisting the state to the user's preferences.\n\t *\n\t * Note that Block Editor components can be consumed by non-WordPress\n\t * environments which may not have preferences setup.\n\t * Therefore a local state is also used as a fallback.\n\t *\n\t * @param {boolean} prefVal the open/closed state of the Advanced Settings Drawer.\n\t */\n\tconst setSettingsOpenWithPreference = ( prefVal ) => {\n\t\tif ( setPreference ) {\n\t\t\tsetPreference( PREFERENCE_SCOPE, PREFERENCE_KEY, prefVal );\n\t\t}\n\t\tsetSettingsOpen( prefVal );\n\t};\n\n\t// Block Editor components can be consumed by non-WordPress environments\n\t// which may not have these preferences setup.\n\t// Therefore a local state is used as a fallback.\n\tconst isSettingsOpen = advancedSettingsPreference || settingsOpen;\n\n\tconst isMountingRef = useRef( true );\n\tconst wrapperNode = useRef();\n\tconst textInputRef = useRef();\n\tconst searchInputRef = useRef();\n\t// TODO: Remove entityUrlFallbackRef and previewValue in favor of value prop after taxonomy entity binding\n\t// is stable and returns the correct URL instead of null while resolving when creating the entity.\n\t//\n\t// Preserve the URL from entity suggestions before binding overrides it\n\t// This is due to entity binding not being available immediately after the suggestion is selected.\n\t// The URL can return null, especially for taxonomy entities, while entity binding is being resolved.\n\t// To avoid unnecessary rerenders and focus loss, we preserve the URL from the suggestion and use it\n\t// as a fallback until the entity binding is available.\n\tconst entityUrlFallbackRef = useRef();\n\n\tconst settingsKeys = settings.map( ( { id } ) => id );\n\n\tconst [\n\t\tinternalControlValue,\n\t\tsetInternalControlValue,\n\t\tsetInternalURLInputValue,\n\t\tsetInternalTextInputValue,\n\t\tcreateSetInternalSettingValueHandler,\n\t] = useInternalValue( value );\n\n\t// Compute isEntity internally based on handleEntities prop and presence of ID\n\tconst isEntity = handleEntities && !! internalControlValue?.id;\n\n\t// Generate help text ID for accessibility association\n\tconst baseId = useInstanceId( LinkControl, 'link-control' );\n\tconst helpTextId = isEntity ? `${ baseId }__help` : null;\n\n\tconst valueHasChanges =\n\t\tvalue && ! isShallowEqualObjects( internalControlValue, value );\n\n\tconst [ isEditingLink, setIsEditingLink ] = useState(\n\t\tforceIsEditingLink !== undefined\n\t\t\t? forceIsEditingLink\n\t\t\t: ! value || ! value.url\n\t);\n\n\tconst { createPage, isCreatingPage, errorMessage } =\n\t\tuseCreatePage( createSuggestion );\n\n\tuseEffect( () => {\n\t\tif ( forceIsEditingLink === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsEditingLink( forceIsEditingLink );\n\t}, [ forceIsEditingLink ] );\n\n\tuseEffect( () => {\n\t\t// We don't auto focus into the Link UI on mount\n\t\t// because otherwise using the keyboard to select text\n\t\t// *within* the link format is not possible.\n\t\tif ( isMountingRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Scenario - when:\n\t\t// - switching between editable and non editable LinkControl\n\t\t// - clicking on a link\n\t\t// ...then move focus to the *first* element to avoid focus loss\n\t\t// and to ensure focus is *within* the Link UI.\n\t\tconst nextFocusTarget =\n\t\t\tfocus.focusable.find( wrapperNode.current )[ 0 ] ||\n\t\t\twrapperNode.current;\n\n\t\tnextFocusTarget.focus();\n\t}, [ isEditingLink, isCreatingPage ] );\n\n\t// The component mounting reference is maintained separately\n\t// to correctly reset values in `StrictMode`.\n\tuseEffect( () => {\n\t\tisMountingRef.current = false;\n\n\t\treturn () => {\n\t\t\tisMountingRef.current = true;\n\t\t};\n\t}, [] );\n\n\tconst hasLinkValue = value?.url?.trim()?.length > 0;\n\n\t/**\n\t * Cancels editing state.\n\t */\n\tconst stopEditing = () => {\n\t\tsetIsEditingLink( false );\n\t};\n\n\tconst handleSelectSuggestion = ( updatedValue ) => {\n\t\t// Preserve the URL for taxonomy entities before binding overrides it\n\t\tif ( updatedValue?.kind === 'taxonomy' && updatedValue?.url ) {\n\t\t\tentityUrlFallbackRef.current = updatedValue.url;\n\t\t}\n\n\t\t// Suggestions may contains \"settings\" values (e.g. `opensInNewTab`)\n\t\t// which should not override any existing settings values set by the\n\t\t// user. This filters out any settings values from the suggestion.\n\t\tconst nonSettingsChanges = Object.keys( updatedValue ).reduce(\n\t\t\t( acc, key ) => {\n\t\t\t\tif ( ! settingsKeys.includes( key ) ) {\n\t\t\t\t\tacc[ key ] = updatedValue[ key ];\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{}\n\t\t);\n\n\t\tonChange( {\n\t\t\t...internalControlValue,\n\t\t\t...nonSettingsChanges,\n\t\t\t// As title is not a setting, it must be manually applied\n\t\t\t// in such a way as to preserve the users changes over\n\t\t\t// any \"title\" value provided by the \"suggestion\".\n\t\t\ttitle: internalControlValue?.title || updatedValue?.title,\n\t\t} );\n\n\t\tstopEditing();\n\t};\n\n\tconst handleSubmit = () => {\n\t\tif ( valueHasChanges ) {\n\t\t\t// Submit the original value with new stored values applied\n\t\t\t// on top. URL is a special case as it may also be a prop.\n\t\t\tonChange( {\n\t\t\t\t...value,\n\t\t\t\t...internalControlValue,\n\t\t\t\turl: currentUrlInputValue,\n\t\t\t} );\n\t\t}\n\t\tstopEditing();\n\t};\n\n\tconst handleSubmitWithEnter = ( event ) => {\n\t\tconst { keyCode } = event;\n\n\t\tif (\n\t\t\tkeyCode === ENTER &&\n\t\t\t! currentInputIsEmpty // Disallow submitting empty values.\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t\thandleSubmit();\n\t\t}\n\t};\n\n\tconst resetInternalValues = () => {\n\t\tsetInternalControlValue( value );\n\t};\n\n\tconst handleCancel = ( event ) => {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\t// Ensure that any unsubmitted input changes are reset.\n\t\tresetInternalValues();\n\n\t\tif ( hasLinkValue ) {\n\t\t\t// If there is a link then exist editing mode and show preview.\n\t\t\tstopEditing();\n\t\t} else {\n\t\t\t// If there is no link value, then remove the link entirely.\n\t\t\tonRemove?.();\n\t\t}\n\n\t\tonCancel?.();\n\t};\n\n\tconst [ shouldFocusSearchInput, setShouldFocusSearchInput ] =\n\t\tuseState( false );\n\n\tconst handleUnlink = () => {\n\t\t// Clear the internal state to remove the ID and re-enable the field\n\t\t// Explicitly set id, kind, and type to undefined so they override\n\t\t// the original values when spread in handleSubmit. This ensures that\n\t\t// when the user types a custom URL and submits, the entity link is\n\t\t// properly severed (not just when selecting a different entity from suggestions).\n\t\tconst { id, kind, type, ...restValue } = internalControlValue;\n\t\tsetInternalControlValue( {\n\t\t\t...restValue,\n\t\t\tid: undefined,\n\t\t\tkind: undefined,\n\t\t\ttype: undefined,\n\t\t\turl: undefined,\n\t\t} );\n\n\t\t// Request focus after the component re-renders with the cleared state\n\t\t// We can't focus immediately because the input might still be disabled\n\t\tsetShouldFocusSearchInput( true );\n\t};\n\n\t// Focus the search input when requested, once the component has re-rendered\n\t// This ensures the input is enabled and ready to receive focus\n\tuseEffect( () => {\n\t\tif ( shouldFocusSearchInput ) {\n\t\t\tsearchInputRef.current?.focus();\n\t\t\tsetShouldFocusSearchInput( false );\n\t\t}\n\t}, [ shouldFocusSearchInput ] );\n\n\tconst currentUrlInputValue =\n\t\tpropInputValue || internalControlValue?.url || '';\n\n\tconst currentInputIsEmpty = ! currentUrlInputValue?.trim()?.length;\n\n\tconst shownUnlinkControl =\n\t\tonRemove && value && ! isEditingLink && ! isCreatingPage;\n\n\tconst showActions = isEditingLink && hasLinkValue;\n\n\t// Only show text control once a URL value has been committed\n\t// and it isn't just empty whitespace.\n\t// See https://github.com/WordPress/gutenberg/pull/33849/#issuecomment-932194927.\n\tconst showTextControl = hasLinkValue && hasTextControl;\n\n\tconst isEditing = ( isEditingLink || ! value ) && ! isCreatingPage;\n\tconst isDisabled = ! valueHasChanges || currentInputIsEmpty;\n\tconst showSettings = !! settings?.length && isEditingLink && hasLinkValue;\n\n\tconst previewValue = useMemo( () => {\n\t\t// There is a chance that the value is not yet set from the entity binding, so we use the preserved URL.\n\t\tif (\n\t\t\tvalue?.kind === 'taxonomy' &&\n\t\t\t! value?.url &&\n\t\t\tentityUrlFallbackRef.current\n\t\t) {\n\t\t\t// combine the value prop with the preserved URL from the suggestion\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t\turl: entityUrlFallbackRef.current,\n\t\t\t};\n\t\t}\n\n\t\t// If we don't have a fallback URL, use the value prop.\n\t\treturn value;\n\t}, [ value ] );\n\n\treturn (\n\t\t<div\n\t\t\ttabIndex={ -1 }\n\t\t\tref={ wrapperNode }\n\t\t\tclassName=\"block-editor-link-control\"\n\t\t>\n\t\t\t{ isCreatingPage && (\n\t\t\t\t<div className=\"block-editor-link-control__loading\">\n\t\t\t\t\t<Spinner /> { __( 'Creating' ) }\u2026\n\t\t\t\t</div>\n\t\t\t) }\n\n\t\t\t{ isEditing && (\n\t\t\t\t<>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={ clsx( {\n\t\t\t\t\t\t\t'block-editor-link-control__search-input-wrapper': true,\n\t\t\t\t\t\t\t'has-text-control': showTextControl,\n\t\t\t\t\t\t\t'has-actions': showActions,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ showTextControl && (\n\t\t\t\t\t\t\t<TextControl\n\t\t\t\t\t\t\t\t__nextHasNoMarginBottom\n\t\t\t\t\t\t\t\tref={ textInputRef }\n\t\t\t\t\t\t\t\tclassName=\"block-editor-link-control__field block-editor-link-control__text-content\"\n\t\t\t\t\t\t\t\tlabel={ __( 'Text' ) }\n\t\t\t\t\t\t\t\tvalue={ internalControlValue?.title }\n\t\t\t\t\t\t\t\tonChange={ setInternalTextInputValue }\n\t\t\t\t\t\t\t\tonKeyDown={ handleSubmitWithEnter }\n\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<LinkControlSearchInput\n\t\t\t\t\t\t\tref={ searchInputRef }\n\t\t\t\t\t\t\tcurrentLink={ value }\n\t\t\t\t\t\t\tclassName=\"block-editor-link-control__field block-editor-link-control__search-input\"\n\t\t\t\t\t\t\tplaceholder={ searchInputPlaceholder }\n\t\t\t\t\t\t\tvalue={ currentUrlInputValue }\n\t\t\t\t\t\t\twithCreateSuggestion={ withCreateSuggestion }\n\t\t\t\t\t\t\tonCreateSuggestion={ createPage }\n\t\t\t\t\t\t\tonChange={ setInternalURLInputValue }\n\t\t\t\t\t\t\tonSelect={ handleSelectSuggestion }\n\t\t\t\t\t\t\tshowInitialSuggestions={ showInitialSuggestions }\n\t\t\t\t\t\t\tallowDirectEntry={ ! noDirectEntry }\n\t\t\t\t\t\t\tshowSuggestions={ showSuggestions }\n\t\t\t\t\t\t\tsuggestionsQuery={ suggestionsQuery }\n\t\t\t\t\t\t\twithURLSuggestion={ ! noURLSuggestion }\n\t\t\t\t\t\t\tcreateSuggestionButtonText={\n\t\t\t\t\t\t\t\tcreateSuggestionButtonText\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\thideLabelFromVision={ ! showTextControl }\n\t\t\t\t\t\t\tisEntity={ isEntity }\n\t\t\t\t\t\t\tsuffix={\n\t\t\t\t\t\t\t\t<SearchSuffixControl\n\t\t\t\t\t\t\t\t\tisEntity={ isEntity }\n\t\t\t\t\t\t\t\t\tshowActions={ showActions }\n\t\t\t\t\t\t\t\t\tisDisabled={ isDisabled }\n\t\t\t\t\t\t\t\t\tonUnlink={ handleUnlink }\n\t\t\t\t\t\t\t\t\tonSubmit={ handleSubmit }\n\t\t\t\t\t\t\t\t\thelpTextId={ helpTextId }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ isEntity && helpTextId && (\n\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\tid={ helpTextId }\n\t\t\t\t\t\t\t\tclassName=\"block-editor-link-control__help\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{ sprintf(\n\t\t\t\t\t\t\t\t\t/* translators: %s: entity type (e.g., page, post) */\n\t\t\t\t\t\t\t\t\t__( 'Synced with the selected %s.' ),\n\t\t\t\t\t\t\t\t\tinternalControlValue?.type || 'item'\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t\t{ errorMessage && (\n\t\t\t\t\t\t<Notice\n\t\t\t\t\t\t\tclassName=\"block-editor-link-control__search-error\"\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\tisDismissible={ false }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ errorMessage }\n\t\t\t\t\t\t</Notice>\n\t\t\t\t\t) }\n\t\t\t\t</>\n\t\t\t) }\n\n\t\t\t{ value && ! isEditingLink && ! isCreatingPage && (\n\t\t\t\t<LinkPreview\n\t\t\t\t\tkey={ previewValue?.url } // force remount when URL changes to avoid race conditions for rich previews\n\t\t\t\t\tvalue={ previewValue }\n\t\t\t\t\tonEditClick={ () => setIsEditingLink( true ) }\n\t\t\t\t\thasRichPreviews={ hasRichPreviews }\n\t\t\t\t\thasUnlinkControl={ shownUnlinkControl }\n\t\t\t\t\tonRemove={ () => {\n\t\t\t\t\t\tonRemove();\n\t\t\t\t\t\tsetIsEditingLink( true );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\n\t\t\t{ showSettings && (\n\t\t\t\t<div className=\"block-editor-link-control__tools\">\n\t\t\t\t\t{ ! currentInputIsEmpty && (\n\t\t\t\t\t\t<LinkControlSettingsDrawer\n\t\t\t\t\t\t\tsettingsOpen={ isSettingsOpen }\n\t\t\t\t\t\t\tsetSettingsOpen={ setSettingsOpenWithPreference }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<LinkSettings\n\t\t\t\t\t\t\t\tvalue={ internalControlValue }\n\t\t\t\t\t\t\t\tsettings={ settings }\n\t\t\t\t\t\t\t\tonChange={ createSetInternalSettingValueHandler(\n\t\t\t\t\t\t\t\t\tsettingsKeys\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</LinkControlSettingsDrawer>\n\t\t\t\t\t) }\n\t\t\t\t</div>\n\t\t\t) }\n\n\t\t\t{ showActions && (\n\t\t\t\t<HStack\n\t\t\t\t\tjustify=\"right\"\n\t\t\t\t\tclassName=\"block-editor-link-control__search-actions\"\n\t\t\t\t>\n\t\t\t\t\t<Button\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\tonClick={ handleCancel }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Cancel' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\tonClick={ isDisabled ? noop : handleSubmit }\n\t\t\t\t\t\tclassName=\"block-editor-link-control__search-submit\"\n\t\t\t\t\t\taria-disabled={ isDisabled }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ __( 'Apply' ) }\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t) }\n\n\t\t\t{ ! isCreatingPage && renderControlBottom && renderControlBottom() }\n\t\t</div>\n\t);\n}\n\n/**\n * Suffix control component for LinkControl search input.\n * Handles the display of unlink button for entities and submit button for regular links.\n *\n * @param {Object} props - Component props\n * @param {boolean} props.isEntity - Whether the link is bound to an entity\n * @param {boolean} props.showActions - Whether to show action buttons\n * @param {boolean} props.isDisabled - Whether the submit button should be disabled\n * @param {Function} props.onUnlink - Callback when unlink button is clicked\n * @param {Function} props.onSubmit - Callback when submit button is clicked\n * @param {string} props.helpTextId - ID of the help text element for accessibility\n */\nfunction SearchSuffixControl( {\n\tisEntity,\n\tshowActions,\n\tisDisabled,\n\tonUnlink,\n\tonSubmit,\n\thelpTextId,\n} ) {\n\tif ( isEntity ) {\n\t\treturn (\n\t\t\t<Button\n\t\t\t\ticon={ linkOff }\n\t\t\t\tonClick={ onUnlink }\n\t\t\t\taria-describedby={ helpTextId }\n\t\t\t\tshowTooltip\n\t\t\t\tlabel={ __( 'Unsync and edit' ) }\n\t\t\t\t__next40pxDefaultSize\n\t\t\t/>\n\t\t);\n\t}\n\n\tif ( showActions ) {\n\t\treturn undefined;\n\t}\n\n\treturn (\n\t\t<InputControlSuffixWrapper variant=\"control\">\n\t\t\t<Button\n\t\t\t\tonClick={ isDisabled ? noop : onSubmit }\n\t\t\t\tlabel={ __( 'Submit' ) }\n\t\t\t\ticon={ keyboardReturn }\n\t\t\t\tclassName=\"block-editor-link-control__search-submit\"\n\t\t\t\taria-disabled={ isDisabled }\n\t\t\t\tsize=\"small\"\n\t\t\t/>\n\t\t</InputControlSuffixWrapper>\n\t);\n}\n\nLinkControl.ViewerFill = ViewerFill;\nLinkControl.DEFAULT_LINK_SETTINGS = DEFAULT_LINK_SETTINGS;\n\nconst DeprecatedExperimentalLinkControl = ( props ) => {\n\tdeprecated( 'wp.blockEditor.__experimentalLinkControl', {\n\t\tsince: '6.8',\n\t\talternative: 'wp.blockEditor.LinkControl',\n\t} );\n\n\treturn <LinkControl { ...props } />;\n};\n\nDeprecatedExperimentalLinkControl.ViewerFill = LinkControl.ViewerFill;\nDeprecatedExperimentalLinkControl.DEFAULT_LINK_SETTINGS =\n\tLinkControl.DEFAULT_LINK_SETTINGS;\n\nexport { DeprecatedExperimentalLinkControl };\nexport default LinkControl;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// packages/block-editor/src/components/link-control/search-input.js
|
|
2
2
|
import { forwardRef, useState } from "@wordpress/element";
|
|
3
3
|
import { __ } from "@wordpress/i18n";
|
|
4
|
+
import deprecated from "@wordpress/deprecated";
|
|
4
5
|
import { URLInput } from "../";
|
|
5
6
|
import LinkControlSearchResults from "./search-results";
|
|
6
7
|
import { CREATE_TYPE } from "./constants";
|
|
7
8
|
import useSearchHandler from "./use-search-handler";
|
|
8
|
-
import deprecated from "@wordpress/deprecated";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
var noopSearchHandler = () => Promise.resolve([]);
|
|
11
11
|
var noop = () => {
|
|
@@ -72,7 +72,7 @@ var LinkControlSearchInput = forwardRef(
|
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
if (allowDirectEntry || suggestion && Object.keys(suggestion).length >= 1) {
|
|
75
|
-
const { id, url, ...restLinkProps } = currentLink ?? {};
|
|
75
|
+
const { id, url, kind, type, ...restLinkProps } = currentLink ?? {};
|
|
76
76
|
onSelect(
|
|
77
77
|
// Some direct entries don't have types or IDs, and we still need to clear the previous ones.
|
|
78
78
|
{ ...restLinkProps, ...suggestion },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/link-control/search-input.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { forwardRef, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { URLInput } from '../';\nimport LinkControlSearchResults from './search-results';\nimport { CREATE_TYPE } from './constants';\nimport useSearchHandler from './use-search-handler';\
|
|
5
|
-
"mappings": ";AAGA,SAAS,YAAY,gBAAgB;AACrC,SAAS,UAAU;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { forwardRef, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport deprecated from '@wordpress/deprecated';\n\n/**\n * Internal dependencies\n */\nimport { URLInput } from '../';\nimport LinkControlSearchResults from './search-results';\nimport { CREATE_TYPE } from './constants';\nimport useSearchHandler from './use-search-handler';\n\n// Must be a function as otherwise URLInput will default\n// to the fetchLinkSuggestions passed in block editor settings\n// which will cause an unintended http request.\nconst noopSearchHandler = () => Promise.resolve( [] );\n\nconst noop = () => {};\n\nconst LinkControlSearchInput = forwardRef(\n\t(\n\t\t{\n\t\t\tvalue,\n\t\t\tchildren,\n\t\t\tcurrentLink = {},\n\t\t\tclassName = null,\n\t\t\tplaceholder = null,\n\t\t\twithCreateSuggestion = false,\n\t\t\tonCreateSuggestion = noop,\n\t\t\tonChange = noop,\n\t\t\tonSelect = noop,\n\t\t\tshowSuggestions = true,\n\t\t\trenderSuggestions = ( props ) => (\n\t\t\t\t<LinkControlSearchResults { ...props } />\n\t\t\t),\n\t\t\tfetchSuggestions = null,\n\t\t\tallowDirectEntry = true,\n\t\t\tshowInitialSuggestions = false,\n\t\t\tsuggestionsQuery = {},\n\t\t\twithURLSuggestion = true,\n\t\t\tcreateSuggestionButtonText,\n\t\t\thideLabelFromVision = false,\n\t\t\tsuffix,\n\t\t\tisEntity = false,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst genericSearchHandler = useSearchHandler(\n\t\t\tsuggestionsQuery,\n\t\t\tallowDirectEntry,\n\t\t\twithCreateSuggestion,\n\t\t\twithURLSuggestion\n\t\t);\n\n\t\tconst searchHandler = showSuggestions\n\t\t\t? fetchSuggestions || genericSearchHandler\n\t\t\t: noopSearchHandler;\n\n\t\tconst [ focusedSuggestion, setFocusedSuggestion ] = useState();\n\n\t\t/**\n\t\t * Handles the user moving between different suggestions. Does not handle\n\t\t * choosing an individual item.\n\t\t *\n\t\t * @param {string} selection the url of the selected suggestion.\n\t\t * @param {Object} suggestion the suggestion object.\n\t\t */\n\t\tconst onInputChange = ( selection, suggestion ) => {\n\t\t\tonChange( selection );\n\t\t\tsetFocusedSuggestion( suggestion );\n\t\t};\n\n\t\tconst handleRenderSuggestions = ( props ) =>\n\t\t\trenderSuggestions( {\n\t\t\t\t...props,\n\t\t\t\twithCreateSuggestion,\n\t\t\t\tcreateSuggestionButtonText,\n\t\t\t\tsuggestionsQuery,\n\t\t\t\thandleSuggestionClick: ( suggestion ) => {\n\t\t\t\t\tif ( props.handleSuggestionClick ) {\n\t\t\t\t\t\tprops.handleSuggestionClick( suggestion );\n\t\t\t\t\t}\n\t\t\t\t\tonSuggestionSelected( suggestion );\n\t\t\t\t},\n\t\t\t} );\n\n\t\tconst onSuggestionSelected = async ( selectedSuggestion ) => {\n\t\t\tlet suggestion = selectedSuggestion;\n\t\t\tif ( CREATE_TYPE === selectedSuggestion.type ) {\n\t\t\t\t// Create a new page and call onSelect with the output from the onCreateSuggestion callback.\n\t\t\t\ttry {\n\t\t\t\t\tsuggestion = await onCreateSuggestion(\n\t\t\t\t\t\tselectedSuggestion.title\n\t\t\t\t\t);\n\t\t\t\t\tif ( suggestion?.url ) {\n\t\t\t\t\t\tonSelect( suggestion );\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tallowDirectEntry ||\n\t\t\t\t( suggestion && Object.keys( suggestion ).length >= 1 )\n\t\t\t) {\n\t\t\t\t// Strip out id, url, kind, and type from the current link to prevent\n\t\t\t\t// entity metadata from persisting when switching to a different link type.\n\t\t\t\t// For example, when changing from an entity link (kind: 'post-type', type: 'page')\n\t\t\t\t// to a custom URL (type: 'link', no kind), we need to ensure the old 'kind'\n\t\t\t\t// doesn't carry over. We do want to preserve other properites like title, though.\n\t\t\t\tconst { id, url, kind, type, ...restLinkProps } =\n\t\t\t\t\tcurrentLink ?? {};\n\t\t\t\tonSelect(\n\t\t\t\t\t// Some direct entries don't have types or IDs, and we still need to clear the previous ones.\n\t\t\t\t\t{ ...restLinkProps, ...suggestion },\n\t\t\t\t\tsuggestion\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst _placeholder = placeholder ?? __( 'Search or type URL' );\n\n\t\tconst label =\n\t\t\thideLabelFromVision && placeholder !== ''\n\t\t\t\t? _placeholder\n\t\t\t\t: __( 'Link' );\n\n\t\treturn (\n\t\t\t<div className=\"block-editor-link-control__search-input-container\">\n\t\t\t\t<URLInput\n\t\t\t\t\tdisableSuggestions={ currentLink?.url === value }\n\t\t\t\t\tlabel={ label }\n\t\t\t\t\thideLabelFromVision={ hideLabelFromVision }\n\t\t\t\t\tclassName={ className }\n\t\t\t\t\tvalue={ value }\n\t\t\t\t\tonChange={ onInputChange }\n\t\t\t\t\tplaceholder={ _placeholder }\n\t\t\t\t\t__experimentalRenderSuggestions={\n\t\t\t\t\t\tshowSuggestions ? handleRenderSuggestions : null\n\t\t\t\t\t}\n\t\t\t\t\t__experimentalFetchLinkSuggestions={ searchHandler }\n\t\t\t\t\t__experimentalHandleURLSuggestions\n\t\t\t\t\t__experimentalShowInitialSuggestions={\n\t\t\t\t\t\tshowInitialSuggestions\n\t\t\t\t\t}\n\t\t\t\t\tonSubmit={ ( suggestion, event ) => {\n\t\t\t\t\t\tconst hasSuggestion = suggestion || focusedSuggestion;\n\n\t\t\t\t\t\t// If there is no suggestion and the value (ie: any manually entered URL) is empty\n\t\t\t\t\t\t// then don't allow submission otherwise we get empty links.\n\t\t\t\t\t\tif ( ! hasSuggestion && ! value?.trim()?.length ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonSuggestionSelected(\n\t\t\t\t\t\t\t\thasSuggestion || { url: value }\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t\tinputRef={ ref }\n\t\t\t\t\tsuffix={ suffix }\n\t\t\t\t\tdisabled={ isEntity }\n\t\t\t\t/>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nexport default LinkControlSearchInput;\n\nexport const __experimentalLinkControlSearchInput = ( props ) => {\n\tdeprecated( 'wp.blockEditor.__experimentalLinkControlSearchInput', {\n\t\tsince: '6.8',\n\t} );\n\n\treturn <LinkControlSearchInput { ...props } />;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
// packages/block-editor/src/hooks/block-bindings.js
|
|
2
|
-
import fastDeepEqual from "fast-deep-equal/es6";
|
|
3
2
|
import { __ } from "@wordpress/i18n";
|
|
4
|
-
import {
|
|
5
|
-
getBlockBindingsSource,
|
|
6
|
-
getBlockType,
|
|
7
|
-
store as blockStore
|
|
8
|
-
} from "@wordpress/blocks";
|
|
3
|
+
import { store as blocksStore } from "@wordpress/blocks";
|
|
9
4
|
import {
|
|
10
5
|
__experimentalItemGroup as ItemGroup,
|
|
11
|
-
__experimentalItem as Item,
|
|
12
6
|
__experimentalText as Text,
|
|
13
|
-
__experimentalToolsPanel as ToolsPanel
|
|
14
|
-
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
15
|
-
__experimentalVStack as VStack,
|
|
16
|
-
privateApis as componentsPrivateApis
|
|
7
|
+
__experimentalToolsPanel as ToolsPanel
|
|
17
8
|
} from "@wordpress/components";
|
|
18
9
|
import { useSelect } from "@wordpress/data";
|
|
19
10
|
import { useContext } from "@wordpress/element";
|
|
20
11
|
import { useViewportMatch } from "@wordpress/compose";
|
|
21
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
BlockBindingsAttributeControl,
|
|
14
|
+
useBlockBindingsUtils
|
|
15
|
+
} from "../components/block-bindings";
|
|
22
16
|
import { unlock } from "../lock-unlock";
|
|
23
17
|
import InspectorControls from "../components/inspector-controls";
|
|
24
18
|
import BlockContext from "../components/block-context";
|
|
25
|
-
import { useBlockEditContext } from "../components/block-edit";
|
|
26
19
|
import { store as blockEditorStore } from "../store";
|
|
27
20
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
-
var { Menu } = unlock(componentsPrivateApis);
|
|
29
|
-
var getAttributeType = (blockName, attribute) => {
|
|
30
|
-
const _attributeType = getBlockType(blockName).attributes?.[attribute]?.type;
|
|
31
|
-
return _attributeType === "rich-text" ? "string" : _attributeType;
|
|
32
|
-
};
|
|
33
21
|
var useToolsPanelDropdownMenuProps = () => {
|
|
34
22
|
const isMobile = useViewportMatch("medium", "<");
|
|
35
23
|
return !isMobile ? {
|
|
@@ -40,241 +28,33 @@ var useToolsPanelDropdownMenuProps = () => {
|
|
|
40
28
|
}
|
|
41
29
|
} : {};
|
|
42
30
|
};
|
|
43
|
-
function BlockBindingsPanelMenuContent({ attribute, binding, sources }) {
|
|
44
|
-
const { clientId } = useBlockEditContext();
|
|
45
|
-
const { updateBlockBindings } = useBlockBindingsUtils();
|
|
46
|
-
const isMobile = useViewportMatch("medium", "<");
|
|
47
|
-
const blockContext = useContext(BlockContext);
|
|
48
|
-
const { attributeType, select } = useSelect(
|
|
49
|
-
(_select) => {
|
|
50
|
-
const { name: blockName } = _select(blockEditorStore).getBlock(clientId);
|
|
51
|
-
return {
|
|
52
|
-
attributeType: getAttributeType(blockName, attribute),
|
|
53
|
-
select: _select
|
|
54
|
-
};
|
|
55
|
-
},
|
|
56
|
-
[clientId, attribute]
|
|
57
|
-
);
|
|
58
|
-
return /* @__PURE__ */ jsx(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: Object.entries(sources).map(([sourceKey, data]) => {
|
|
59
|
-
const sourceDataItems = data.filter(
|
|
60
|
-
(item) => item.type === attributeType
|
|
61
|
-
);
|
|
62
|
-
const noItemsAvailable = !sourceDataItems || sourceDataItems.length === 0;
|
|
63
|
-
if (noItemsAvailable) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
const source = getBlockBindingsSource(sourceKey);
|
|
67
|
-
return /* @__PURE__ */ jsxs(
|
|
68
|
-
Menu,
|
|
69
|
-
{
|
|
70
|
-
placement: isMobile ? "bottom-start" : "left-start",
|
|
71
|
-
children: [
|
|
72
|
-
/* @__PURE__ */ jsx(Menu.SubmenuTriggerItem, { children: /* @__PURE__ */ jsx(Menu.ItemLabel, { children: source.label }) }),
|
|
73
|
-
/* @__PURE__ */ jsx(Menu.Popover, { gutter: 8, children: /* @__PURE__ */ jsx(Menu.Group, { children: sourceDataItems.map((item) => {
|
|
74
|
-
const itemBindings = {
|
|
75
|
-
source: sourceKey,
|
|
76
|
-
args: item.args || {
|
|
77
|
-
key: item.key
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
let values = {};
|
|
81
|
-
try {
|
|
82
|
-
values = source.getValues({
|
|
83
|
-
select,
|
|
84
|
-
context: blockContext,
|
|
85
|
-
bindings: {
|
|
86
|
-
[attribute]: itemBindings
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
} catch (e) {
|
|
90
|
-
}
|
|
91
|
-
return /* @__PURE__ */ jsxs(
|
|
92
|
-
Menu.CheckboxItem,
|
|
93
|
-
{
|
|
94
|
-
onChange: () => {
|
|
95
|
-
const isCurrentlySelected = fastDeepEqual(
|
|
96
|
-
binding?.args,
|
|
97
|
-
item.args
|
|
98
|
-
) ?? // Deprecate key dependency in 7.0.
|
|
99
|
-
item.key === binding?.args?.key;
|
|
100
|
-
if (isCurrentlySelected) {
|
|
101
|
-
updateBlockBindings({
|
|
102
|
-
[attribute]: void 0
|
|
103
|
-
});
|
|
104
|
-
} else {
|
|
105
|
-
updateBlockBindings({
|
|
106
|
-
[attribute]: itemBindings
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
name: attribute + "-binding",
|
|
111
|
-
value: values[attribute],
|
|
112
|
-
checked: fastDeepEqual(
|
|
113
|
-
binding?.args,
|
|
114
|
-
item.args
|
|
115
|
-
) ?? // Deprecate key dependency in 7.0.
|
|
116
|
-
item.key === binding?.args?.key,
|
|
117
|
-
children: [
|
|
118
|
-
/* @__PURE__ */ jsx(Menu.ItemLabel, { children: item.label }),
|
|
119
|
-
/* @__PURE__ */ jsx(Menu.ItemHelpText, { children: values[attribute] })
|
|
120
|
-
]
|
|
121
|
-
},
|
|
122
|
-
sourceKey + JSON.stringify(
|
|
123
|
-
item.args
|
|
124
|
-
) || item.key
|
|
125
|
-
);
|
|
126
|
-
}) }) })
|
|
127
|
-
]
|
|
128
|
-
},
|
|
129
|
-
sourceKey
|
|
130
|
-
);
|
|
131
|
-
}) });
|
|
132
|
-
}
|
|
133
|
-
function BlockBindingsAttribute({ attribute, binding, sources, blockName }) {
|
|
134
|
-
const { source: sourceName, args } = binding || {};
|
|
135
|
-
const data = sources?.[sourceName];
|
|
136
|
-
const source = getBlockBindingsSource(sourceName);
|
|
137
|
-
let displayText;
|
|
138
|
-
let isValid = true;
|
|
139
|
-
const isNotBound = binding === void 0;
|
|
140
|
-
if (isNotBound) {
|
|
141
|
-
const attributeType = getAttributeType(blockName, attribute);
|
|
142
|
-
const hasCompatibleSources = Object.values(sources).some(
|
|
143
|
-
(items) => items.some((item) => item.type === attributeType)
|
|
144
|
-
);
|
|
145
|
-
if (!hasCompatibleSources) {
|
|
146
|
-
displayText = __("No sources available");
|
|
147
|
-
} else {
|
|
148
|
-
displayText = __("Not connected");
|
|
149
|
-
}
|
|
150
|
-
isValid = true;
|
|
151
|
-
} else if (!source) {
|
|
152
|
-
isValid = false;
|
|
153
|
-
displayText = __("Source not registered");
|
|
154
|
-
} else {
|
|
155
|
-
displayText = data?.find((item) => fastDeepEqual(item.args, args))?.label || source?.label || sourceName;
|
|
156
|
-
}
|
|
157
|
-
return /* @__PURE__ */ jsxs(VStack, { className: "block-editor-bindings__item", spacing: 0, children: [
|
|
158
|
-
/* @__PURE__ */ jsx(Text, { truncate: true, children: attribute }),
|
|
159
|
-
/* @__PURE__ */ jsx(
|
|
160
|
-
Text,
|
|
161
|
-
{
|
|
162
|
-
truncate: true,
|
|
163
|
-
variant: isValid ? "muted" : void 0,
|
|
164
|
-
isDestructive: !isValid,
|
|
165
|
-
children: displayText
|
|
166
|
-
}
|
|
167
|
-
)
|
|
168
|
-
] });
|
|
169
|
-
}
|
|
170
|
-
function ReadOnlyBlockBindingsPanelItem({
|
|
171
|
-
attribute,
|
|
172
|
-
binding,
|
|
173
|
-
sources,
|
|
174
|
-
blockName
|
|
175
|
-
}) {
|
|
176
|
-
const isMobile = useViewportMatch("medium", "<");
|
|
177
|
-
return /* @__PURE__ */ jsx(ToolsPanelItem, { hasValue: () => !!binding, label: attribute, children: /* @__PURE__ */ jsx(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: /* @__PURE__ */ jsx(Menu.TriggerButton, { render: /* @__PURE__ */ jsx(Item, {}), disabled: true, children: /* @__PURE__ */ jsx(
|
|
178
|
-
BlockBindingsAttribute,
|
|
179
|
-
{
|
|
180
|
-
attribute,
|
|
181
|
-
binding,
|
|
182
|
-
sources,
|
|
183
|
-
blockName
|
|
184
|
-
}
|
|
185
|
-
) }) }) });
|
|
186
|
-
}
|
|
187
|
-
function EditableBlockBindingsPanelItem({
|
|
188
|
-
attribute,
|
|
189
|
-
binding,
|
|
190
|
-
sources,
|
|
191
|
-
blockName
|
|
192
|
-
}) {
|
|
193
|
-
const { updateBlockBindings } = useBlockBindingsUtils();
|
|
194
|
-
const isMobile = useViewportMatch("medium", "<");
|
|
195
|
-
return /* @__PURE__ */ jsx(
|
|
196
|
-
ToolsPanelItem,
|
|
197
|
-
{
|
|
198
|
-
hasValue: () => !!binding,
|
|
199
|
-
label: attribute,
|
|
200
|
-
onDeselect: () => {
|
|
201
|
-
updateBlockBindings({
|
|
202
|
-
[attribute]: void 0
|
|
203
|
-
});
|
|
204
|
-
},
|
|
205
|
-
children: /* @__PURE__ */ jsxs(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: [
|
|
206
|
-
/* @__PURE__ */ jsx(Menu.TriggerButton, { render: /* @__PURE__ */ jsx(Item, {}), children: /* @__PURE__ */ jsx(
|
|
207
|
-
BlockBindingsAttribute,
|
|
208
|
-
{
|
|
209
|
-
attribute,
|
|
210
|
-
binding,
|
|
211
|
-
sources,
|
|
212
|
-
blockName
|
|
213
|
-
}
|
|
214
|
-
) }),
|
|
215
|
-
/* @__PURE__ */ jsx(Menu.Popover, { gutter: isMobile ? 8 : 36, children: /* @__PURE__ */ jsx(
|
|
216
|
-
BlockBindingsPanelMenuContent,
|
|
217
|
-
{
|
|
218
|
-
attribute,
|
|
219
|
-
binding,
|
|
220
|
-
sources
|
|
221
|
-
}
|
|
222
|
-
) })
|
|
223
|
-
] })
|
|
224
|
-
}
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
31
|
var BlockBindingsPanel = ({ name: blockName, metadata }) => {
|
|
228
32
|
const blockContext = useContext(BlockContext);
|
|
229
33
|
const { removeAllBlockBindings } = useBlockBindingsUtils();
|
|
230
34
|
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
|
|
231
|
-
const {
|
|
35
|
+
const { bindableAttributes, hasCompatibleFields } = useSelect(
|
|
232
36
|
(select) => {
|
|
233
37
|
const { __experimentalBlockBindingsSupportedAttributes } = select(blockEditorStore).getSettings();
|
|
38
|
+
const {
|
|
39
|
+
getAllBlockBindingsSources,
|
|
40
|
+
getBlockBindingsSourceFieldsList
|
|
41
|
+
} = unlock(select(blocksStore));
|
|
234
42
|
return {
|
|
235
|
-
|
|
236
|
-
|
|
43
|
+
bindableAttributes: __experimentalBlockBindingsSupportedAttributes?.[blockName],
|
|
44
|
+
hasCompatibleFields: Object.values(
|
|
45
|
+
getAllBlockBindingsSources()
|
|
46
|
+
).some(
|
|
47
|
+
(source) => getBlockBindingsSourceFieldsList(source, blockContext)?.length > 0
|
|
48
|
+
)
|
|
237
49
|
};
|
|
238
50
|
},
|
|
239
|
-
[blockName]
|
|
240
|
-
);
|
|
241
|
-
const sources = useSelect(
|
|
242
|
-
(select) => {
|
|
243
|
-
const { getAllBlockBindingsSources } = unlock(
|
|
244
|
-
select(blockStore)
|
|
245
|
-
);
|
|
246
|
-
const data = {};
|
|
247
|
-
Object.entries(getAllBlockBindingsSources()).forEach(
|
|
248
|
-
([sourceName, source]) => {
|
|
249
|
-
if (!source.getFieldsList) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const context = {};
|
|
253
|
-
if (source.usesContext?.length) {
|
|
254
|
-
for (const key of source.usesContext) {
|
|
255
|
-
context[key] = blockContext[key];
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
const items = source.getFieldsList({
|
|
259
|
-
select,
|
|
260
|
-
context
|
|
261
|
-
});
|
|
262
|
-
if (items?.length) {
|
|
263
|
-
data[sourceName] = items;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
);
|
|
267
|
-
return data;
|
|
268
|
-
},
|
|
269
|
-
[blockContext]
|
|
51
|
+
[blockName, blockContext]
|
|
270
52
|
);
|
|
271
53
|
if (!bindableAttributes || bindableAttributes.length === 0) {
|
|
272
54
|
return null;
|
|
273
55
|
}
|
|
274
56
|
const { bindings } = metadata || {};
|
|
275
|
-
|
|
276
|
-
const readOnly = !canUpdateBlockBindings || !hasCompatibleData;
|
|
277
|
-
if (bindings === void 0 && !hasCompatibleData) {
|
|
57
|
+
if (bindings === void 0 && !hasCompatibleFields) {
|
|
278
58
|
return null;
|
|
279
59
|
}
|
|
280
60
|
return /* @__PURE__ */ jsx(InspectorControls, { group: "bindings", children: /* @__PURE__ */ jsxs(
|
|
@@ -287,38 +67,15 @@ var BlockBindingsPanel = ({ name: blockName, metadata }) => {
|
|
|
287
67
|
dropdownMenuProps,
|
|
288
68
|
className: "block-editor-bindings__panel",
|
|
289
69
|
children: [
|
|
290
|
-
/* @__PURE__ */ jsx(ItemGroup, { isBordered: true, isSeparated: true, children: bindableAttributes.map((attribute) =>
|
|
291
|
-
|
|
292
|
-
|
|
70
|
+
/* @__PURE__ */ jsx(ItemGroup, { isBordered: true, isSeparated: true, children: bindableAttributes.map((attribute) => /* @__PURE__ */ jsx(
|
|
71
|
+
BlockBindingsAttributeControl,
|
|
72
|
+
{
|
|
73
|
+
attribute,
|
|
293
74
|
blockName,
|
|
294
|
-
attribute
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
).some(
|
|
299
|
-
(data) => data.some((item) => item.type === attributeType)
|
|
300
|
-
);
|
|
301
|
-
const isAttributeReadOnly = readOnly || !hasCompatibleDataForAttribute;
|
|
302
|
-
return isAttributeReadOnly ? /* @__PURE__ */ jsx(
|
|
303
|
-
ReadOnlyBlockBindingsPanelItem,
|
|
304
|
-
{
|
|
305
|
-
attribute,
|
|
306
|
-
binding,
|
|
307
|
-
sources,
|
|
308
|
-
blockName
|
|
309
|
-
},
|
|
310
|
-
attribute
|
|
311
|
-
) : /* @__PURE__ */ jsx(
|
|
312
|
-
EditableBlockBindingsPanelItem,
|
|
313
|
-
{
|
|
314
|
-
attribute,
|
|
315
|
-
binding,
|
|
316
|
-
sources,
|
|
317
|
-
blockName
|
|
318
|
-
},
|
|
319
|
-
attribute
|
|
320
|
-
);
|
|
321
|
-
}) }),
|
|
75
|
+
binding: bindings?.[attribute]
|
|
76
|
+
},
|
|
77
|
+
attribute
|
|
78
|
+
)) }),
|
|
322
79
|
/* @__PURE__ */ jsx(Text, { as: "div", variant: "muted", children: /* @__PURE__ */ jsx("p", { children: __(
|
|
323
80
|
"Attributes connected to custom fields or other dynamic data."
|
|
324
81
|
) }) })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/block-bindings.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tgetBlockBindingsSource,\n\tgetBlockType,\n\tstore as blockStore,\n} from '@wordpress/blocks';\nimport {\n\t__experimentalItemGroup as ItemGroup,\n\t__experimentalItem as Item,\n\t__experimentalText as Text,\n\t__experimentalToolsPanel as ToolsPanel,\n\t__experimentalToolsPanelItem as ToolsPanelItem,\n\t__experimentalVStack as VStack,\n\tprivateApis as componentsPrivateApis,\n} from '@wordpress/components';\nimport { useSelect } from '@wordpress/data';\nimport { useContext } from '@wordpress/element';\nimport { useViewportMatch } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport { useBlockBindingsUtils } from '../utils/block-bindings';\nimport { unlock } from '../lock-unlock';\nimport InspectorControls from '../components/inspector-controls';\nimport BlockContext from '../components/block-context';\nimport { useBlockEditContext } from '../components/block-edit';\nimport { store as blockEditorStore } from '../store';\n\nconst { Menu } = unlock( componentsPrivateApis );\n\n/**\n * Get the normalized attribute type for block bindings.\n * Converts 'rich-text' to 'string' since rich-text is stored as string.\n *\n * @param {string} blockName The block name.\n * @param {string} attribute The attribute name.\n * @return {string} The normalized attribute type.\n */\nconst getAttributeType = ( blockName, attribute ) => {\n\tconst _attributeType =\n\t\tgetBlockType( blockName ).attributes?.[ attribute ]?.type;\n\treturn _attributeType === 'rich-text' ? 'string' : _attributeType;\n};\n\nconst useToolsPanelDropdownMenuProps = () => {\n\tconst isMobile = useViewportMatch( 'medium', '<' );\n\treturn ! isMobile\n\t\t? {\n\t\t\t\tpopoverProps: {\n\t\t\t\t\tplacement: 'left-start',\n\t\t\t\t\t// For non-mobile, inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px)\n\t\t\t\t\toffset: 259,\n\t\t\t\t},\n\t\t }\n\t\t: {};\n};\n\nfunction BlockBindingsPanelMenuContent( { attribute, binding, sources } ) {\n\tconst { clientId } = useBlockEditContext();\n\tconst { updateBlockBindings } = useBlockBindingsUtils();\n\tconst isMobile = useViewportMatch( 'medium', '<' );\n\tconst blockContext = useContext( BlockContext );\n\tconst { attributeType, select } = useSelect(\n\t\t( _select ) => {\n\t\t\tconst { name: blockName } =\n\t\t\t\t_select( blockEditorStore ).getBlock( clientId );\n\t\t\treturn {\n\t\t\t\tattributeType: getAttributeType( blockName, attribute ),\n\t\t\t\tselect: _select,\n\t\t\t};\n\t\t},\n\t\t[ clientId, attribute ]\n\t);\n\treturn (\n\t\t<Menu placement={ isMobile ? 'bottom-start' : 'left-start' }>\n\t\t\t{ Object.entries( sources ).map( ( [ sourceKey, data ] ) => {\n\t\t\t\t// Only show sources that have compatible data for this specific attribute.\n\t\t\t\tconst sourceDataItems = data.filter(\n\t\t\t\t\t( item ) => item.type === attributeType\n\t\t\t\t);\n\n\t\t\t\tconst noItemsAvailable =\n\t\t\t\t\t! sourceDataItems || sourceDataItems.length === 0;\n\n\t\t\t\tif ( noItemsAvailable ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst source = getBlockBindingsSource( sourceKey );\n\n\t\t\t\treturn (\n\t\t\t\t\t<Menu\n\t\t\t\t\t\tkey={ sourceKey }\n\t\t\t\t\t\tplacement={ isMobile ? 'bottom-start' : 'left-start' }\n\t\t\t\t\t>\n\t\t\t\t\t\t<Menu.SubmenuTriggerItem>\n\t\t\t\t\t\t\t<Menu.ItemLabel>{ source.label }</Menu.ItemLabel>\n\t\t\t\t\t\t</Menu.SubmenuTriggerItem>\n\t\t\t\t\t\t<Menu.Popover gutter={ 8 }>\n\t\t\t\t\t\t\t<Menu.Group>\n\t\t\t\t\t\t\t\t{ sourceDataItems.map( ( item ) => {\n\t\t\t\t\t\t\t\t\tconst itemBindings = {\n\t\t\t\t\t\t\t\t\t\tsource: sourceKey,\n\t\t\t\t\t\t\t\t\t\targs: item.args || {\n\t\t\t\t\t\t\t\t\t\t\tkey: item.key,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tlet values = {};\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tvalues = source.getValues( {\n\t\t\t\t\t\t\t\t\t\t\tselect,\n\t\t\t\t\t\t\t\t\t\t\tcontext: blockContext,\n\t\t\t\t\t\t\t\t\t\t\tbindings: {\n\t\t\t\t\t\t\t\t\t\t\t\t[ attribute ]: itemBindings,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t} catch ( e ) {}\n\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<Menu.CheckboxItem\n\t\t\t\t\t\t\t\t\t\t\tkey={\n\t\t\t\t\t\t\t\t\t\t\t\tsourceKey +\n\t\t\t\t\t\t\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\titem.args\n\t\t\t\t\t\t\t\t\t\t\t\t\t) || item.key\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tonChange={ () => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst isCurrentlySelected =\n\t\t\t\t\t\t\t\t\t\t\t\t\tfastDeepEqual(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbinding?.args,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\titem.args\n\t\t\t\t\t\t\t\t\t\t\t\t\t) ??\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Deprecate key dependency in 7.0.\n\t\t\t\t\t\t\t\t\t\t\t\t\titem.key ===\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbinding?.args?.key;\n\n\t\t\t\t\t\t\t\t\t\t\t\tif ( isCurrentlySelected ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Unset if the same item is selected again.\n\t\t\t\t\t\t\t\t\t\t\t\t\tupdateBlockBindings( {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[ attribute ]:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\tupdateBlockBindings( {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[ attribute ]:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\titemBindings,\n\t\t\t\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t\t\t\tname={ attribute + '-binding' }\n\t\t\t\t\t\t\t\t\t\t\tvalue={ values[ attribute ] }\n\t\t\t\t\t\t\t\t\t\t\tchecked={\n\t\t\t\t\t\t\t\t\t\t\t\tfastDeepEqual(\n\t\t\t\t\t\t\t\t\t\t\t\t\tbinding?.args,\n\t\t\t\t\t\t\t\t\t\t\t\t\titem.args\n\t\t\t\t\t\t\t\t\t\t\t\t) ??\n\t\t\t\t\t\t\t\t\t\t\t\t// Deprecate key dependency in 7.0.\n\t\t\t\t\t\t\t\t\t\t\t\titem.key === binding?.args?.key\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Menu.ItemLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t{ item.label }\n\t\t\t\t\t\t\t\t\t\t\t</Menu.ItemLabel>\n\t\t\t\t\t\t\t\t\t\t\t<Menu.ItemHelpText>\n\t\t\t\t\t\t\t\t\t\t\t\t{ values[ attribute ] }\n\t\t\t\t\t\t\t\t\t\t\t</Menu.ItemHelpText>\n\t\t\t\t\t\t\t\t\t\t</Menu.CheckboxItem>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} ) }\n\t\t\t\t\t\t\t</Menu.Group>\n\t\t\t\t\t\t</Menu.Popover>\n\t\t\t\t\t</Menu>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t</Menu>\n\t);\n}\n\nfunction BlockBindingsAttribute( { attribute, binding, sources, blockName } ) {\n\tconst { source: sourceName, args } = binding || {};\n\tconst data = sources?.[ sourceName ];\n\tconst source = getBlockBindingsSource( sourceName );\n\n\tlet displayText;\n\tlet isValid = true;\n\tconst isNotBound = binding === undefined;\n\n\tif ( isNotBound ) {\n\t\t// Check if there are any compatible sources for this attribute type.\n\t\tconst attributeType = getAttributeType( blockName, attribute );\n\n\t\tconst hasCompatibleSources = Object.values( sources ).some( ( items ) =>\n\t\t\titems.some( ( item ) => item.type === attributeType )\n\t\t);\n\n\t\tif ( ! hasCompatibleSources ) {\n\t\t\tdisplayText = __( 'No sources available' );\n\t\t} else {\n\t\t\tdisplayText = __( 'Not connected' );\n\t\t}\n\t\tisValid = true;\n\t} else if ( ! source ) {\n\t\t// If there's a binding but the source is not found, it's invalid.\n\t\tisValid = false;\n\t\tdisplayText = __( 'Source not registered' );\n\t} else {\n\t\tdisplayText =\n\t\t\tdata?.find( ( item ) => fastDeepEqual( item.args, args ) )?.label ||\n\t\t\tsource?.label ||\n\t\t\tsourceName;\n\t}\n\n\treturn (\n\t\t<VStack className=\"block-editor-bindings__item\" spacing={ 0 }>\n\t\t\t<Text truncate>{ attribute }</Text>\n\t\t\t<Text\n\t\t\t\ttruncate\n\t\t\t\tvariant={ isValid ? 'muted' : undefined }\n\t\t\t\tisDestructive={ ! isValid }\n\t\t\t>\n\t\t\t\t{ displayText }\n\t\t\t</Text>\n\t\t</VStack>\n\t);\n}\n\nfunction ReadOnlyBlockBindingsPanelItem( {\n\tattribute,\n\tbinding,\n\tsources,\n\tblockName,\n} ) {\n\tconst isMobile = useViewportMatch( 'medium', '<' );\n\n\treturn (\n\t\t<ToolsPanelItem hasValue={ () => !! binding } label={ attribute }>\n\t\t\t<Menu placement={ isMobile ? 'bottom-start' : 'left-start' }>\n\t\t\t\t<Menu.TriggerButton render={ <Item /> } disabled>\n\t\t\t\t\t<BlockBindingsAttribute\n\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\tbinding={ binding }\n\t\t\t\t\t\tsources={ sources }\n\t\t\t\t\t\tblockName={ blockName }\n\t\t\t\t\t/>\n\t\t\t\t</Menu.TriggerButton>\n\t\t\t</Menu>\n\t\t</ToolsPanelItem>\n\t);\n}\n\nfunction EditableBlockBindingsPanelItem( {\n\tattribute,\n\tbinding,\n\tsources,\n\tblockName,\n} ) {\n\tconst { updateBlockBindings } = useBlockBindingsUtils();\n\tconst isMobile = useViewportMatch( 'medium', '<' );\n\n\treturn (\n\t\t<ToolsPanelItem\n\t\t\thasValue={ () => !! binding }\n\t\t\tlabel={ attribute }\n\t\t\tonDeselect={ () => {\n\t\t\t\tupdateBlockBindings( {\n\t\t\t\t\t[ attribute ]: undefined,\n\t\t\t\t} );\n\t\t\t} }\n\t\t>\n\t\t\t<Menu placement={ isMobile ? 'bottom-start' : 'left-start' }>\n\t\t\t\t<Menu.TriggerButton render={ <Item /> }>\n\t\t\t\t\t<BlockBindingsAttribute\n\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\tbinding={ binding }\n\t\t\t\t\t\tsources={ sources }\n\t\t\t\t\t\tblockName={ blockName }\n\t\t\t\t\t/>\n\t\t\t\t</Menu.TriggerButton>\n\t\t\t\t<Menu.Popover gutter={ isMobile ? 8 : 36 }>\n\t\t\t\t\t<BlockBindingsPanelMenuContent\n\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\tbinding={ binding }\n\t\t\t\t\t\tsources={ sources }\n\t\t\t\t\t/>\n\t\t\t\t</Menu.Popover>\n\t\t\t</Menu>\n\t\t</ToolsPanelItem>\n\t);\n}\n\nexport const BlockBindingsPanel = ( { name: blockName, metadata } ) => {\n\tconst blockContext = useContext( BlockContext );\n\tconst { removeAllBlockBindings } = useBlockBindingsUtils();\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\n\t// Use useSelect to ensure sources are updated whenever there are updates in block context\n\t// or when underlying data changes.\n\tconst { canUpdateBlockBindings, bindableAttributes } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { __experimentalBlockBindingsSupportedAttributes } =\n\t\t\t\tselect( blockEditorStore ).getSettings();\n\n\t\t\treturn {\n\t\t\t\tcanUpdateBlockBindings:\n\t\t\t\t\tselect( blockEditorStore ).getSettings()\n\t\t\t\t\t\t.canUpdateBlockBindings,\n\t\t\t\tbindableAttributes:\n\t\t\t\t\t__experimentalBlockBindingsSupportedAttributes?.[\n\t\t\t\t\t\tblockName\n\t\t\t\t\t],\n\t\t\t};\n\t\t},\n\t\t[ blockName ]\n\t);\n\n\tconst sources = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getAllBlockBindingsSources } = unlock(\n\t\t\t\tselect( blockStore )\n\t\t\t);\n\t\t\tconst data = {};\n\t\t\tObject.entries( getAllBlockBindingsSources() ).forEach(\n\t\t\t\t( [ sourceName, source ] ) => {\n\t\t\t\t\tif ( ! source.getFieldsList ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst context = {};\n\t\t\t\t\tif ( source.usesContext?.length ) {\n\t\t\t\t\t\tfor ( const key of source.usesContext ) {\n\t\t\t\t\t\t\tcontext[ key ] = blockContext[ key ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst items = source.getFieldsList( {\n\t\t\t\t\t\tselect,\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t} );\n\t\t\t\t\tif ( items?.length ) {\n\t\t\t\t\t\tdata[ sourceName ] = items;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t\treturn data;\n\t\t},\n\t\t[ blockContext ]\n\t);\n\n\t// Return early if there are no bindable attributes.\n\tif ( ! bindableAttributes || bindableAttributes.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst { bindings } = metadata || {};\n\n\tconst hasCompatibleData = Object.keys( sources ).length > 0;\n\n\t// Lock the UI when the user can't update bindings or there are no fields to connect to.\n\tconst readOnly = ! canUpdateBlockBindings || ! hasCompatibleData;\n\n\tif ( bindings === undefined && ! hasCompatibleData ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<InspectorControls group=\"bindings\">\n\t\t\t<ToolsPanel\n\t\t\t\tlabel={ __( 'Attributes' ) }\n\t\t\t\tresetAll={ () => {\n\t\t\t\t\tremoveAllBlockBindings();\n\t\t\t\t} }\n\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\tclassName=\"block-editor-bindings__panel\"\n\t\t\t>\n\t\t\t\t<ItemGroup isBordered isSeparated>\n\t\t\t\t\t{ bindableAttributes.map( ( attribute ) => {\n\t\t\t\t\t\tconst binding = bindings?.[ attribute ];\n\n\t\t\t\t\t\t// Check if this specific attribute has compatible data from any source.\n\t\t\t\t\t\tconst attributeType = getAttributeType(\n\t\t\t\t\t\t\tblockName,\n\t\t\t\t\t\t\tattribute\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst hasCompatibleDataForAttribute = Object.values(\n\t\t\t\t\t\t\tsources\n\t\t\t\t\t\t).some( ( data ) =>\n\t\t\t\t\t\t\tdata.some( ( item ) => item.type === attributeType )\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst isAttributeReadOnly =\n\t\t\t\t\t\t\treadOnly || ! hasCompatibleDataForAttribute;\n\n\t\t\t\t\t\treturn isAttributeReadOnly ? (\n\t\t\t\t\t\t\t<ReadOnlyBlockBindingsPanelItem\n\t\t\t\t\t\t\t\tkey={ attribute }\n\t\t\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\t\t\tbinding={ binding }\n\t\t\t\t\t\t\t\tsources={ sources }\n\t\t\t\t\t\t\t\tblockName={ blockName }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<EditableBlockBindingsPanelItem\n\t\t\t\t\t\t\t\tkey={ attribute }\n\t\t\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\t\t\tbinding={ binding }\n\t\t\t\t\t\t\t\tsources={ sources }\n\t\t\t\t\t\t\t\tblockName={ blockName }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</ItemGroup>\n\t\t\t\t{ /*\n\t\t\t\t\tUse a div element to make the ToolsPanelHiddenInnerWrapper\n\t\t\t\t\ttoggle the visibility of this help text automatically.\n\t\t\t\t*/ }\n\t\t\t\t<Text as=\"div\" variant=\"muted\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Attributes connected to custom fields or other dynamic data.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t</Text>\n\t\t\t</ToolsPanel>\n\t\t</InspectorControls>\n\t);\n};\n\nexport default {\n\tedit: BlockBindingsPanel,\n\tattributeKeys: [ 'metadata' ],\n\thasSupport( name ) {\n\t\treturn ! [\n\t\t\t'core/post-date',\n\t\t\t'core/navigation-link',\n\t\t\t'core/navigation-submenu',\n\t\t].includes( name );\n\t},\n};\n"],
|
|
5
|
-
"mappings": ";AAGA,
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { store as blocksStore } from '@wordpress/blocks';\nimport {\n\t__experimentalItemGroup as ItemGroup,\n\t__experimentalText as Text,\n\t__experimentalToolsPanel as ToolsPanel,\n} from '@wordpress/components';\nimport { useSelect } from '@wordpress/data';\nimport { useContext } from '@wordpress/element';\nimport { useViewportMatch } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport {\n\tBlockBindingsAttributeControl,\n\tuseBlockBindingsUtils,\n} from '../components/block-bindings';\nimport { unlock } from '../lock-unlock';\nimport InspectorControls from '../components/inspector-controls';\nimport BlockContext from '../components/block-context';\nimport { store as blockEditorStore } from '../store';\n\nconst useToolsPanelDropdownMenuProps = () => {\n\tconst isMobile = useViewportMatch( 'medium', '<' );\n\treturn ! isMobile\n\t\t? {\n\t\t\t\tpopoverProps: {\n\t\t\t\t\tplacement: 'left-start',\n\t\t\t\t\t// For non-mobile, inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px)\n\t\t\t\t\toffset: 259,\n\t\t\t\t},\n\t\t }\n\t\t: {};\n};\n\nexport const BlockBindingsPanel = ( { name: blockName, metadata } ) => {\n\tconst blockContext = useContext( BlockContext );\n\tconst { removeAllBlockBindings } = useBlockBindingsUtils();\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\n\tconst { bindableAttributes, hasCompatibleFields } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { __experimentalBlockBindingsSupportedAttributes } =\n\t\t\t\tselect( blockEditorStore ).getSettings();\n\t\t\tconst {\n\t\t\t\tgetAllBlockBindingsSources,\n\t\t\t\tgetBlockBindingsSourceFieldsList,\n\t\t\t} = unlock( select( blocksStore ) );\n\n\t\t\treturn {\n\t\t\t\tbindableAttributes:\n\t\t\t\t\t__experimentalBlockBindingsSupportedAttributes?.[\n\t\t\t\t\t\tblockName\n\t\t\t\t\t],\n\t\t\t\thasCompatibleFields: Object.values(\n\t\t\t\t\tgetAllBlockBindingsSources()\n\t\t\t\t).some(\n\t\t\t\t\t( source ) =>\n\t\t\t\t\t\tgetBlockBindingsSourceFieldsList( source, blockContext )\n\t\t\t\t\t\t\t?.length > 0\n\t\t\t\t),\n\t\t\t};\n\t\t},\n\t\t[ blockName, blockContext ]\n\t);\n\n\t// Return early if there are no bindable attributes.\n\tif ( ! bindableAttributes || bindableAttributes.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst { bindings } = metadata || {};\n\n\tif ( bindings === undefined && ! hasCompatibleFields ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<InspectorControls group=\"bindings\">\n\t\t\t<ToolsPanel\n\t\t\t\tlabel={ __( 'Attributes' ) }\n\t\t\t\tresetAll={ () => {\n\t\t\t\t\tremoveAllBlockBindings();\n\t\t\t\t} }\n\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\tclassName=\"block-editor-bindings__panel\"\n\t\t\t>\n\t\t\t\t<ItemGroup isBordered isSeparated>\n\t\t\t\t\t{ bindableAttributes.map( ( attribute ) => (\n\t\t\t\t\t\t<BlockBindingsAttributeControl\n\t\t\t\t\t\t\tkey={ attribute }\n\t\t\t\t\t\t\tattribute={ attribute }\n\t\t\t\t\t\t\tblockName={ blockName }\n\t\t\t\t\t\t\tbinding={ bindings?.[ attribute ] }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) ) }\n\t\t\t\t</ItemGroup>\n\t\t\t\t{ /*\n\t\t\t\t\tUse a div element to make the ToolsPanelHiddenInnerWrapper\n\t\t\t\t\ttoggle the visibility of this help text automatically.\n\t\t\t\t*/ }\n\t\t\t\t<Text as=\"div\" variant=\"muted\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Attributes connected to custom fields or other dynamic data.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t</Text>\n\t\t\t</ToolsPanel>\n\t\t</InspectorControls>\n\t);\n};\n\nexport default {\n\tedit: BlockBindingsPanel,\n\tattributeKeys: [ 'metadata' ],\n\thasSupport( name ) {\n\t\treturn ! [\n\t\t\t'core/post-date',\n\t\t\t'core/navigation-link',\n\t\t\t'core/navigation-submenu',\n\t\t].includes( name );\n\t},\n};\n"],
|
|
5
|
+
"mappings": ";AAGA,SAAS,UAAU;AACnB,SAAS,SAAS,mBAAmB;AACrC;AAAA,EACC,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,OACtB;AACP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AAKjC;AAAA,EACC;AAAA,EACA;AAAA,OACM;AACP,SAAS,cAAc;AACvB,OAAO,uBAAuB;AAC9B,OAAO,kBAAkB;AACzB,SAAS,SAAS,wBAAwB;AA2DvC,SAUG,KAVH;AAzDH,IAAM,iCAAiC,MAAM;AAC5C,QAAM,WAAW,iBAAkB,UAAU,GAAI;AACjD,SAAO,CAAE,WACN;AAAA,IACA,cAAc;AAAA,MACb,WAAW;AAAA;AAAA,MAEX,QAAQ;AAAA,IACT;AAAA,EACA,IACA,CAAC;AACL;AAEO,IAAM,qBAAqB,CAAE,EAAE,MAAM,WAAW,SAAS,MAAO;AACtE,QAAM,eAAe,WAAY,YAAa;AAC9C,QAAM,EAAE,uBAAuB,IAAI,sBAAsB;AACzD,QAAM,oBAAoB,+BAA+B;AAEzD,QAAM,EAAE,oBAAoB,oBAAoB,IAAI;AAAA,IACnD,CAAE,WAAY;AACb,YAAM,EAAE,+CAA+C,IACtD,OAAQ,gBAAiB,EAAE,YAAY;AACxC,YAAM;AAAA,QACL;AAAA,QACA;AAAA,MACD,IAAI,OAAQ,OAAQ,WAAY,CAAE;AAElC,aAAO;AAAA,QACN,oBACC,iDACC,SACD;AAAA,QACD,qBAAqB,OAAO;AAAA,UAC3B,2BAA2B;AAAA,QAC5B,EAAE;AAAA,UACD,CAAE,WACD,iCAAkC,QAAQ,YAAa,GACpD,SAAS;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAE,WAAW,YAAa;AAAA,EAC3B;AAGA,MAAK,CAAE,sBAAsB,mBAAmB,WAAW,GAAI;AAC9D,WAAO;AAAA,EACR;AAEA,QAAM,EAAE,SAAS,IAAI,YAAY,CAAC;AAElC,MAAK,aAAa,UAAa,CAAE,qBAAsB;AACtD,WAAO;AAAA,EACR;AAEA,SACC,oBAAC,qBAAkB,OAAM,YACxB;AAAA,IAAC;AAAA;AAAA,MACA,OAAQ,GAAI,YAAa;AAAA,MACzB,UAAW,MAAM;AAChB,+BAAuB;AAAA,MACxB;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,4BAAC,aAAU,YAAU,MAAC,aAAW,MAC9B,6BAAmB,IAAK,CAAE,cAC3B;AAAA,UAAC;AAAA;AAAA,YAEA;AAAA,YACA;AAAA,YACA,SAAU,WAAY,SAAU;AAAA;AAAA,UAH1B;AAAA,QAIP,CACC,GACH;AAAA,QAKA,oBAAC,QAAK,IAAG,OAAM,SAAQ,SACtB,8BAAC,OACE;AAAA,UACD;AAAA,QACD,GACD,GACD;AAAA;AAAA;AAAA,EACD,GACD;AAEF;AAEA,IAAO,yBAAQ;AAAA,EACd,MAAM;AAAA,EACN,eAAe,CAAE,UAAW;AAAA,EAC5B,WAAY,MAAO;AAClB,WAAO,CAAE;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACD,EAAE,SAAU,IAAK;AAAA,EAClB;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|