@wordpress/block-editor 15.12.0 → 15.12.2-next.v.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/block-allowed-blocks/modal.cjs +1 -1
  3. package/build/components/block-allowed-blocks/modal.cjs.map +2 -2
  4. package/build/components/block-inspector/index.cjs +9 -9
  5. package/build/components/block-inspector/index.cjs.map +3 -3
  6. package/build/components/block-removal-warning-modal/index.cjs +30 -5
  7. package/build/components/block-removal-warning-modal/index.cjs.map +3 -3
  8. package/build/components/block-visibility/use-block-visibility.cjs +14 -29
  9. package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
  10. package/build/components/global-styles/hooks.cjs +7 -0
  11. package/build/components/global-styles/hooks.cjs.map +2 -2
  12. package/build/components/global-styles/typography-panel.cjs +71 -3
  13. package/build/components/global-styles/typography-panel.cjs.map +3 -3
  14. package/build/components/grid/grid-visualizer.cjs +49 -13
  15. package/build/components/grid/grid-visualizer.cjs.map +2 -2
  16. package/build/components/iframe/index.cjs +3 -1
  17. package/build/components/iframe/index.cjs.map +2 -2
  18. package/build/components/iframe/use-scale-canvas.cjs +1 -0
  19. package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
  20. package/build/components/inspector-controls/last-item.cjs +41 -0
  21. package/build/components/inspector-controls/last-item.cjs.map +7 -0
  22. package/build/components/inspector-controls-tabs/styles-tab.cjs +3 -3
  23. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  24. package/build/components/link-control/index.cjs +73 -2
  25. package/build/components/link-control/index.cjs.map +3 -3
  26. package/build/components/link-control/is-url-like.cjs +15 -3
  27. package/build/components/link-control/is-url-like.cjs.map +2 -2
  28. package/build/components/link-control/search-input.cjs +4 -1
  29. package/build/components/link-control/search-input.cjs.map +2 -2
  30. package/build/components/link-control/use-search-handler.cjs +1 -1
  31. package/build/components/link-control/use-search-handler.cjs.map +2 -2
  32. package/build/components/provider/use-block-sync.cjs +60 -8
  33. package/build/components/provider/use-block-sync.cjs.map +2 -2
  34. package/build/components/text-indent-control/index.cjs +121 -0
  35. package/build/components/text-indent-control/index.cjs.map +7 -0
  36. package/build/components/url-input/index.cjs +22 -2
  37. package/build/components/url-input/index.cjs.map +3 -3
  38. package/build/components/url-popover/image-url-input-ui.cjs +1 -1
  39. package/build/components/url-popover/image-url-input-ui.cjs.map +2 -2
  40. package/build/components/writing-flow/use-arrow-nav.cjs +0 -3
  41. package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
  42. package/build/hooks/anchor.cjs +1 -1
  43. package/build/hooks/anchor.cjs.map +1 -1
  44. package/build/hooks/aria-label.cjs +2 -1
  45. package/build/hooks/aria-label.cjs.map +2 -2
  46. package/build/hooks/grid-visualizer.cjs +59 -6
  47. package/build/hooks/grid-visualizer.cjs.map +3 -3
  48. package/build/hooks/layout-child.cjs +47 -6
  49. package/build/hooks/layout-child.cjs.map +3 -3
  50. package/build/hooks/typography.cjs +2 -0
  51. package/build/hooks/typography.cjs.map +2 -2
  52. package/build/hooks/utils.cjs +4 -0
  53. package/build/hooks/utils.cjs.map +2 -2
  54. package/build/private-apis.cjs +2 -0
  55. package/build/private-apis.cjs.map +3 -3
  56. package/build/store/actions.cjs +2 -2
  57. package/build/store/actions.cjs.map +2 -2
  58. package/build-module/components/block-allowed-blocks/modal.mjs +2 -2
  59. package/build-module/components/block-allowed-blocks/modal.mjs.map +2 -2
  60. package/build-module/components/block-inspector/index.mjs +10 -9
  61. package/build-module/components/block-inspector/index.mjs.map +2 -2
  62. package/build-module/components/block-removal-warning-modal/index.mjs +34 -7
  63. package/build-module/components/block-removal-warning-modal/index.mjs.map +2 -2
  64. package/build-module/components/block-visibility/use-block-visibility.mjs +14 -29
  65. package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
  66. package/build-module/components/global-styles/hooks.mjs +7 -0
  67. package/build-module/components/global-styles/hooks.mjs.map +2 -2
  68. package/build-module/components/global-styles/typography-panel.mjs +73 -4
  69. package/build-module/components/global-styles/typography-panel.mjs.map +2 -2
  70. package/build-module/components/grid/grid-visualizer.mjs +50 -14
  71. package/build-module/components/grid/grid-visualizer.mjs.map +2 -2
  72. package/build-module/components/iframe/index.mjs +9 -2
  73. package/build-module/components/iframe/index.mjs.map +2 -2
  74. package/build-module/components/iframe/use-scale-canvas.mjs +1 -0
  75. package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
  76. package/build-module/components/inspector-controls/last-item.mjs +23 -0
  77. package/build-module/components/inspector-controls/last-item.mjs.map +7 -0
  78. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +3 -3
  79. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  80. package/build-module/components/link-control/index.mjs +74 -3
  81. package/build-module/components/link-control/index.mjs.map +2 -2
  82. package/build-module/components/link-control/is-url-like.mjs +10 -3
  83. package/build-module/components/link-control/is-url-like.mjs.map +2 -2
  84. package/build-module/components/link-control/search-input.mjs +4 -1
  85. package/build-module/components/link-control/search-input.mjs.map +2 -2
  86. package/build-module/components/link-control/use-search-handler.mjs +2 -2
  87. package/build-module/components/link-control/use-search-handler.mjs.map +2 -2
  88. package/build-module/components/provider/use-block-sync.mjs +60 -8
  89. package/build-module/components/provider/use-block-sync.mjs.map +2 -2
  90. package/build-module/components/text-indent-control/index.mjs +110 -0
  91. package/build-module/components/text-indent-control/index.mjs.map +7 -0
  92. package/build-module/components/url-input/index.mjs +24 -4
  93. package/build-module/components/url-input/index.mjs.map +2 -2
  94. package/build-module/components/url-popover/image-url-input-ui.mjs +2 -2
  95. package/build-module/components/url-popover/image-url-input-ui.mjs.map +2 -2
  96. package/build-module/components/writing-flow/use-arrow-nav.mjs +0 -3
  97. package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
  98. package/build-module/hooks/anchor.mjs +1 -1
  99. package/build-module/hooks/anchor.mjs.map +1 -1
  100. package/build-module/hooks/aria-label.mjs +2 -1
  101. package/build-module/hooks/aria-label.mjs.map +2 -2
  102. package/build-module/hooks/grid-visualizer.mjs +37 -6
  103. package/build-module/hooks/grid-visualizer.mjs.map +2 -2
  104. package/build-module/hooks/layout-child.mjs +37 -6
  105. package/build-module/hooks/layout-child.mjs.map +2 -2
  106. package/build-module/hooks/typography.mjs +2 -0
  107. package/build-module/hooks/typography.mjs.map +2 -2
  108. package/build-module/hooks/utils.mjs +4 -0
  109. package/build-module/hooks/utils.mjs.map +2 -2
  110. package/build-module/private-apis.mjs +2 -0
  111. package/build-module/private-apis.mjs.map +2 -2
  112. package/build-module/store/actions.mjs +2 -2
  113. package/build-module/store/actions.mjs.map +2 -2
  114. package/package.json +39 -39
  115. package/src/components/block-allowed-blocks/modal.js +2 -2
  116. package/src/components/block-inspector/index.js +19 -17
  117. package/src/components/block-removal-warning-modal/index.js +55 -19
  118. package/src/components/block-switcher/block-transformations-menu.native.js +1 -0
  119. package/src/components/block-toolbar/test/__snapshots__/block-toolbar-menu.native.js.snap +4 -6
  120. package/src/components/block-toolbar/test/block-toolbar-menu.native.js +2 -2
  121. package/src/components/block-visibility/use-block-visibility.js +17 -32
  122. package/src/components/global-styles/hooks.js +10 -0
  123. package/src/components/global-styles/typography-panel.js +78 -1
  124. package/src/components/grid/grid-visualizer.js +58 -12
  125. package/src/components/iframe/index.js +12 -2
  126. package/src/components/iframe/use-scale-canvas.js +1 -0
  127. package/src/components/inserter/menu.native.js +1 -0
  128. package/src/components/inspector-controls/last-item.js +29 -0
  129. package/src/components/inspector-controls-tabs/styles-tab.js +3 -3
  130. package/src/components/link-control/index.js +160 -3
  131. package/src/components/link-control/is-url-like.js +43 -8
  132. package/src/components/link-control/search-input.js +7 -0
  133. package/src/components/link-control/test/index.js +260 -0
  134. package/src/components/link-control/test/is-url-like.js +49 -1
  135. package/src/components/link-control/use-search-handler.js +2 -2
  136. package/src/components/provider/test/use-block-sync.js +105 -0
  137. package/src/components/provider/use-block-sync.js +118 -9
  138. package/src/components/text-indent-control/index.js +138 -0
  139. package/src/components/url-input/index.js +21 -2
  140. package/src/components/url-popover/image-url-input-ui.js +2 -2
  141. package/src/components/writing-flow/use-arrow-nav.js +0 -4
  142. package/src/hooks/anchor.js +1 -1
  143. package/src/hooks/aria-label.js +9 -1
  144. package/src/hooks/grid-visualizer.js +63 -24
  145. package/src/hooks/layout-child.js +45 -3
  146. package/src/hooks/typography.js +2 -0
  147. package/src/hooks/utils.js +4 -0
  148. package/src/private-apis.js +2 -0
  149. package/src/store/actions.js +8 -6
@@ -66,7 +66,8 @@ var LinkControlSearchInput = (0, import_element.forwardRef)(
66
66
  createSuggestionButtonText,
67
67
  hideLabelFromVision = false,
68
68
  suffix,
69
- isEntity = false
69
+ isEntity = false,
70
+ customValidity: customValidityProp
70
71
  }, ref) => {
71
72
  const genericSearchHandler = (0, import_use_search_handler.default)(
72
73
  suggestionsQuery,
@@ -132,6 +133,8 @@ var LinkControlSearchInput = (0, import_element.forwardRef)(
132
133
  __experimentalFetchLinkSuggestions: searchHandler,
133
134
  __experimentalHandleURLSuggestions: true,
134
135
  __experimentalShowInitialSuggestions: showInitialSuggestions,
136
+ customValidity: customValidityProp,
137
+ markWhenOptional: true,
135
138
  onSubmit: (suggestion, event) => {
136
139
  const hasSuggestion = suggestion || focusedSuggestion;
137
140
  if (!hasSuggestion && !value?.trim()?.length) {
@@ -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';\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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",
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\tcustomValidity: customValidityProp,\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\tcustomValidity={ customValidityProp }\n\t\t\t\t\t// Suppress the \"(Required)\" indicator that appears when validation\n\t\t\t\t\t// is triggered. The field is still required for validation purposes,\n\t\t\t\t\t// but we don't want to show the indicator as it looks cluttered\n\t\t\t\t\t// in the link control UI.\n\t\t\t\t\tmarkWhenOptional\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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,qBAAqC;AACrC,kBAAmB;AACnB,wBAAuB;AAKvB,eAAyB;AACzB,4BAAqC;AACrC,uBAA4B;AAC5B,gCAA6B;AAuBzB;AAlBJ,IAAM,oBAAoB,MAAM,QAAQ,QAAS,CAAC,CAAE;AAEpD,IAAM,OAAO,MAAM;AAAC;AAEpB,IAAM,6BAAyB;AAAA,EAC9B,CACC;AAAA,IACC;AAAA,IACA;AAAA,IACA,cAAc,CAAC;AAAA,IACf,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,oBAAoB,CAAE,UACrB,4CAAC,sBAAAA,SAAA,EAA2B,GAAG,OAAQ;AAAA,IAExC,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,yBAAyB;AAAA,IACzB,mBAAmB,CAAC;AAAA,IACpB,oBAAoB;AAAA,IACpB;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,WAAW;AAAA,IACX,gBAAgB;AAAA,EACjB,GACA,QACI;AACJ,UAAM,2BAAuB,0BAAAC;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,UAAM,gBAAgB,kBACnB,oBAAoB,uBACpB;AAEH,UAAM,CAAE,mBAAmB,oBAAqB,QAAI,yBAAS;AAS7D,UAAM,gBAAgB,CAAE,WAAW,eAAgB;AAClD,eAAU,SAAU;AACpB,2BAAsB,UAAW;AAAA,IAClC;AAEA,UAAM,0BAA0B,CAAE,UACjC,kBAAmB;AAAA,MAClB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA,uBAAuB,CAAE,eAAgB;AACxC,YAAK,MAAM,uBAAwB;AAClC,gBAAM,sBAAuB,UAAW;AAAA,QACzC;AACA,6BAAsB,UAAW;AAAA,MAClC;AAAA,IACD,CAAE;AAEH,UAAM,uBAAuB,OAAQ,uBAAwB;AAC5D,UAAI,aAAa;AACjB,UAAK,iCAAgB,mBAAmB,MAAO;AAE9C,YAAI;AACH,uBAAa,MAAM;AAAA,YAClB,mBAAmB;AAAA,UACpB;AACA,cAAK,YAAY,KAAM;AACtB,qBAAU,UAAW;AAAA,UACtB;AAAA,QACD,SAAU,GAAI;AAAA,QAAC;AACf;AAAA,MACD;AAEA,UACC,oBACE,cAAc,OAAO,KAAM,UAAW,EAAE,UAAU,GACnD;AAMD,cAAM,EAAE,IAAI,KAAK,MAAM,MAAM,GAAG,cAAc,IAC7C,eAAe,CAAC;AACjB;AAAA;AAAA,UAEC,EAAE,GAAG,eAAe,GAAG,WAAW;AAAA,UAClC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,eAAe,mBAAe,gBAAI,oBAAqB;AAE7D,UAAM,QACL,uBAAuB,gBAAgB,KACpC,mBACA,gBAAI,MAAO;AAEf,WACC,6CAAC,SAAI,WAAU,qDACd;AAAA;AAAA,QAAC;AAAA;AAAA,UACA,oBAAqB,aAAa,QAAQ;AAAA,UAC1C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAW;AAAA,UACX,aAAc;AAAA,UACd,iCACC,kBAAkB,0BAA0B;AAAA,UAE7C,oCAAqC;AAAA,UACrC,oCAAkC;AAAA,UAClC,sCACC;AAAA,UAED,gBAAiB;AAAA,UAKjB,kBAAgB;AAAA,UAChB,UAAW,CAAE,YAAY,UAAW;AACnC,kBAAM,gBAAgB,cAAc;AAIpC,gBAAK,CAAE,iBAAiB,CAAE,OAAO,KAAK,GAAG,QAAS;AACjD,oBAAM,eAAe;AAAA,YACtB,OAAO;AACN;AAAA,gBACC,iBAAiB,EAAE,KAAK,MAAM;AAAA,cAC/B;AAAA,YACD;AAAA,UACD;AAAA,UACA,UAAW;AAAA,UACX;AAAA,UACA,UAAW;AAAA;AAAA,MACZ;AAAA,MACE;AAAA,OACH;AAAA,EAEF;AACD;AAEA,IAAO,uBAAQ;AAER,IAAM,uCAAuC,CAAE,UAAW;AAChE,wBAAAC,SAAY,uDAAuD;AAAA,IAClE,OAAO;AAAA,EACR,CAAE;AAEF,SAAO,4CAAC,0BAAyB,GAAG,OAAQ;AAC7C;",
6
6
  "names": ["LinkControlSearchResults", "useSearchHandler", "deprecated"]
7
7
  }
@@ -58,7 +58,7 @@ var handleDirectEntry = (val) => {
58
58
  {
59
59
  id: val,
60
60
  title: val,
61
- url: type === "URL" ? (0, import_url.prependHTTP)(val) : val,
61
+ url: type === "URL" ? (0, import_url.prependHTTPS)(val) : val,
62
62
  type
63
63
  }
64
64
  ]);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/link-control/use-search-handler.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { getProtocol, prependHTTP } from '@wordpress/url';\nimport { useCallback } from '@wordpress/element';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport isURLLike from './is-url-like';\nimport {\n\tCREATE_TYPE,\n\tTEL_TYPE,\n\tMAILTO_TYPE,\n\tINTERNAL_TYPE,\n\tURL_TYPE,\n} from './constants';\nimport { store as blockEditorStore } from '../../store';\n\nexport const handleNoop = () => Promise.resolve( [] );\n\nexport const handleDirectEntry = ( val ) => {\n\tlet type = URL_TYPE;\n\n\tconst protocol = getProtocol( val ) || '';\n\n\tif ( protocol.includes( 'mailto' ) ) {\n\t\ttype = MAILTO_TYPE;\n\t}\n\n\tif ( protocol.includes( 'tel' ) ) {\n\t\ttype = TEL_TYPE;\n\t}\n\n\tif ( val?.startsWith( '#' ) ) {\n\t\ttype = INTERNAL_TYPE;\n\t}\n\n\treturn Promise.resolve( [\n\t\t{\n\t\t\tid: val,\n\t\t\ttitle: val,\n\t\t\turl: type === 'URL' ? prependHTTP( val ) : val,\n\t\t\ttype,\n\t\t},\n\t] );\n};\n\nconst handleEntitySearch = async (\n\tval,\n\tsuggestionsQuery,\n\tfetchSearchSuggestions,\n\twithCreateSuggestion,\n\tpageOnFront,\n\tpageForPosts\n) => {\n\tconst { isInitialSuggestions } = suggestionsQuery;\n\n\tconst results = await fetchSearchSuggestions( val, suggestionsQuery );\n\n\t// Identify front page and update type to match.\n\tresults.map( ( result ) => {\n\t\tif ( Number( result.id ) === pageOnFront ) {\n\t\t\tresult.isFrontPage = true;\n\t\t\treturn result;\n\t\t} else if ( Number( result.id ) === pageForPosts ) {\n\t\t\tresult.isBlogHome = true;\n\t\t\treturn result;\n\t\t}\n\n\t\treturn result;\n\t} );\n\n\t// If displaying initial suggestions just return plain results.\n\tif ( isInitialSuggestions ) {\n\t\treturn results;\n\t}\n\n\t// Here we append a faux suggestion to represent a \"CREATE\" option. This\n\t// is detected in the rendering of the search results and handled as a\n\t// special case. This is currently necessary because the suggestions\n\t// dropdown will only appear if there are valid suggestions and\n\t// therefore unless the create option is a suggestion it will not\n\t// display in scenarios where there are no results returned from the\n\t// API. In addition promoting CREATE to a first class suggestion affords\n\t// the a11y benefits afforded by `URLInput` to all suggestions (eg:\n\t// keyboard handling, ARIA roles...etc).\n\t//\n\t// Note also that the value of the `title` and `url` properties must correspond\n\t// to the text value of the `<input>`. This is because `title` is used\n\t// when creating the suggestion. Similarly `url` is used when using keyboard to select\n\t// the suggestion (the <form> `onSubmit` handler falls-back to `url`).\n\treturn isURLLike( val ) || ! withCreateSuggestion\n\t\t? results\n\t\t: results.concat( {\n\t\t\t\t// the `id` prop is intentionally omitted here because it\n\t\t\t\t// is never exposed as part of the component's public API.\n\t\t\t\t// see: https://github.com/WordPress/gutenberg/pull/19775#discussion_r378931316.\n\t\t\t\ttitle: val, // Must match the existing `<input>`s text value.\n\t\t\t\turl: val, // Must match the existing `<input>`s text value.\n\t\t\t\ttype: CREATE_TYPE,\n\t\t } );\n};\n\nexport default function useSearchHandler(\n\tsuggestionsQuery,\n\tallowDirectEntry,\n\twithCreateSuggestion\n) {\n\tconst { fetchSearchSuggestions, pageOnFront, pageForPosts } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getSettings } = select( blockEditorStore );\n\n\t\t\treturn {\n\t\t\t\tpageOnFront: getSettings().pageOnFront,\n\t\t\t\tpageForPosts: getSettings().pageForPosts,\n\t\t\t\tfetchSearchSuggestions:\n\t\t\t\t\tgetSettings().__experimentalFetchLinkSuggestions,\n\t\t\t};\n\t\t},\n\t\t[]\n\t);\n\n\tconst directEntryHandler = allowDirectEntry\n\t\t? handleDirectEntry\n\t\t: handleNoop;\n\n\treturn useCallback(\n\t\t( val, { isInitialSuggestions } ) => {\n\t\t\treturn isURLLike( val )\n\t\t\t\t? directEntryHandler( val, { isInitialSuggestions } )\n\t\t\t\t: handleEntitySearch(\n\t\t\t\t\t\tval,\n\t\t\t\t\t\t{ ...suggestionsQuery, isInitialSuggestions },\n\t\t\t\t\t\tfetchSearchSuggestions,\n\t\t\t\t\t\twithCreateSuggestion,\n\t\t\t\t\t\tpageOnFront,\n\t\t\t\t\t\tpageForPosts\n\t\t\t\t );\n\t\t},\n\t\t[\n\t\t\tdirectEntryHandler,\n\t\t\tfetchSearchSuggestions,\n\t\t\tpageOnFront,\n\t\t\tpageForPosts,\n\t\t\tsuggestionsQuery,\n\t\t\twithCreateSuggestion,\n\t\t]\n\t);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAyC;AACzC,qBAA4B;AAC5B,kBAA0B;AAK1B,yBAAsB;AACtB,uBAMO;AACP,mBAA0C;AAEnC,IAAM,aAAa,MAAM,QAAQ,QAAS,CAAC,CAAE;AAE7C,IAAM,oBAAoB,CAAE,QAAS;AAC3C,MAAI,OAAO;AAEX,QAAM,eAAW,wBAAa,GAAI,KAAK;AAEvC,MAAK,SAAS,SAAU,QAAS,GAAI;AACpC,WAAO;AAAA,EACR;AAEA,MAAK,SAAS,SAAU,KAAM,GAAI;AACjC,WAAO;AAAA,EACR;AAEA,MAAK,KAAK,WAAY,GAAI,GAAI;AAC7B,WAAO;AAAA,EACR;AAEA,SAAO,QAAQ,QAAS;AAAA,IACvB;AAAA,MACC,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,KAAK,SAAS,YAAQ,wBAAa,GAAI,IAAI;AAAA,MAC3C;AAAA,IACD;AAAA,EACD,CAAE;AACH;AAEA,IAAM,qBAAqB,OAC1B,KACA,kBACA,wBACA,sBACA,aACA,iBACI;AACJ,QAAM,EAAE,qBAAqB,IAAI;AAEjC,QAAM,UAAU,MAAM,uBAAwB,KAAK,gBAAiB;AAGpE,UAAQ,IAAK,CAAE,WAAY;AAC1B,QAAK,OAAQ,OAAO,EAAG,MAAM,aAAc;AAC1C,aAAO,cAAc;AACrB,aAAO;AAAA,IACR,WAAY,OAAQ,OAAO,EAAG,MAAM,cAAe;AAClD,aAAO,aAAa;AACpB,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAE;AAGF,MAAK,sBAAuB;AAC3B,WAAO;AAAA,EACR;AAgBA,aAAO,mBAAAA,SAAW,GAAI,KAAK,CAAE,uBAC1B,UACA,QAAQ,OAAQ;AAAA;AAAA;AAAA;AAAA,IAIhB,OAAO;AAAA;AAAA,IACP,KAAK;AAAA;AAAA,IACL,MAAM;AAAA,EACN,CAAE;AACN;AAEe,SAAR,iBACN,kBACA,kBACA,sBACC;AACD,QAAM,EAAE,wBAAwB,aAAa,aAAa,QAAI;AAAA,IAC7D,CAAE,WAAY;AACb,YAAM,EAAE,YAAY,IAAI,OAAQ,aAAAC,KAAiB;AAEjD,aAAO;AAAA,QACN,aAAa,YAAY,EAAE;AAAA,QAC3B,cAAc,YAAY,EAAE;AAAA,QAC5B,wBACC,YAAY,EAAE;AAAA,MAChB;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AAEA,QAAM,qBAAqB,mBACxB,oBACA;AAEH,aAAO;AAAA,IACN,CAAE,KAAK,EAAE,qBAAqB,MAAO;AACpC,iBAAO,mBAAAD,SAAW,GAAI,IACnB,mBAAoB,KAAK,EAAE,qBAAqB,CAAE,IAClD;AAAA,QACA;AAAA,QACA,EAAE,GAAG,kBAAkB,qBAAqB;AAAA,QAC5C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACA;AAAA,IACJ;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { getProtocol, prependHTTPS } from '@wordpress/url';\nimport { useCallback } from '@wordpress/element';\nimport { useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport isURLLike from './is-url-like';\nimport {\n\tCREATE_TYPE,\n\tTEL_TYPE,\n\tMAILTO_TYPE,\n\tINTERNAL_TYPE,\n\tURL_TYPE,\n} from './constants';\nimport { store as blockEditorStore } from '../../store';\n\nexport const handleNoop = () => Promise.resolve( [] );\n\nexport const handleDirectEntry = ( val ) => {\n\tlet type = URL_TYPE;\n\n\tconst protocol = getProtocol( val ) || '';\n\n\tif ( protocol.includes( 'mailto' ) ) {\n\t\ttype = MAILTO_TYPE;\n\t}\n\n\tif ( protocol.includes( 'tel' ) ) {\n\t\ttype = TEL_TYPE;\n\t}\n\n\tif ( val?.startsWith( '#' ) ) {\n\t\ttype = INTERNAL_TYPE;\n\t}\n\n\treturn Promise.resolve( [\n\t\t{\n\t\t\tid: val,\n\t\t\ttitle: val,\n\t\t\turl: type === 'URL' ? prependHTTPS( val ) : val,\n\t\t\ttype,\n\t\t},\n\t] );\n};\n\nconst handleEntitySearch = async (\n\tval,\n\tsuggestionsQuery,\n\tfetchSearchSuggestions,\n\twithCreateSuggestion,\n\tpageOnFront,\n\tpageForPosts\n) => {\n\tconst { isInitialSuggestions } = suggestionsQuery;\n\n\tconst results = await fetchSearchSuggestions( val, suggestionsQuery );\n\n\t// Identify front page and update type to match.\n\tresults.map( ( result ) => {\n\t\tif ( Number( result.id ) === pageOnFront ) {\n\t\t\tresult.isFrontPage = true;\n\t\t\treturn result;\n\t\t} else if ( Number( result.id ) === pageForPosts ) {\n\t\t\tresult.isBlogHome = true;\n\t\t\treturn result;\n\t\t}\n\n\t\treturn result;\n\t} );\n\n\t// If displaying initial suggestions just return plain results.\n\tif ( isInitialSuggestions ) {\n\t\treturn results;\n\t}\n\n\t// Here we append a faux suggestion to represent a \"CREATE\" option. This\n\t// is detected in the rendering of the search results and handled as a\n\t// special case. This is currently necessary because the suggestions\n\t// dropdown will only appear if there are valid suggestions and\n\t// therefore unless the create option is a suggestion it will not\n\t// display in scenarios where there are no results returned from the\n\t// API. In addition promoting CREATE to a first class suggestion affords\n\t// the a11y benefits afforded by `URLInput` to all suggestions (eg:\n\t// keyboard handling, ARIA roles...etc).\n\t//\n\t// Note also that the value of the `title` and `url` properties must correspond\n\t// to the text value of the `<input>`. This is because `title` is used\n\t// when creating the suggestion. Similarly `url` is used when using keyboard to select\n\t// the suggestion (the <form> `onSubmit` handler falls-back to `url`).\n\treturn isURLLike( val ) || ! withCreateSuggestion\n\t\t? results\n\t\t: results.concat( {\n\t\t\t\t// the `id` prop is intentionally omitted here because it\n\t\t\t\t// is never exposed as part of the component's public API.\n\t\t\t\t// see: https://github.com/WordPress/gutenberg/pull/19775#discussion_r378931316.\n\t\t\t\ttitle: val, // Must match the existing `<input>`s text value.\n\t\t\t\turl: val, // Must match the existing `<input>`s text value.\n\t\t\t\ttype: CREATE_TYPE,\n\t\t } );\n};\n\nexport default function useSearchHandler(\n\tsuggestionsQuery,\n\tallowDirectEntry,\n\twithCreateSuggestion\n) {\n\tconst { fetchSearchSuggestions, pageOnFront, pageForPosts } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getSettings } = select( blockEditorStore );\n\n\t\t\treturn {\n\t\t\t\tpageOnFront: getSettings().pageOnFront,\n\t\t\t\tpageForPosts: getSettings().pageForPosts,\n\t\t\t\tfetchSearchSuggestions:\n\t\t\t\t\tgetSettings().__experimentalFetchLinkSuggestions,\n\t\t\t};\n\t\t},\n\t\t[]\n\t);\n\n\tconst directEntryHandler = allowDirectEntry\n\t\t? handleDirectEntry\n\t\t: handleNoop;\n\n\treturn useCallback(\n\t\t( val, { isInitialSuggestions } ) => {\n\t\t\treturn isURLLike( val )\n\t\t\t\t? directEntryHandler( val, { isInitialSuggestions } )\n\t\t\t\t: handleEntitySearch(\n\t\t\t\t\t\tval,\n\t\t\t\t\t\t{ ...suggestionsQuery, isInitialSuggestions },\n\t\t\t\t\t\tfetchSearchSuggestions,\n\t\t\t\t\t\twithCreateSuggestion,\n\t\t\t\t\t\tpageOnFront,\n\t\t\t\t\t\tpageForPosts\n\t\t\t\t );\n\t\t},\n\t\t[\n\t\t\tdirectEntryHandler,\n\t\t\tfetchSearchSuggestions,\n\t\t\tpageOnFront,\n\t\t\tpageForPosts,\n\t\t\tsuggestionsQuery,\n\t\t\twithCreateSuggestion,\n\t\t]\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA0C;AAC1C,qBAA4B;AAC5B,kBAA0B;AAK1B,yBAAsB;AACtB,uBAMO;AACP,mBAA0C;AAEnC,IAAM,aAAa,MAAM,QAAQ,QAAS,CAAC,CAAE;AAE7C,IAAM,oBAAoB,CAAE,QAAS;AAC3C,MAAI,OAAO;AAEX,QAAM,eAAW,wBAAa,GAAI,KAAK;AAEvC,MAAK,SAAS,SAAU,QAAS,GAAI;AACpC,WAAO;AAAA,EACR;AAEA,MAAK,SAAS,SAAU,KAAM,GAAI;AACjC,WAAO;AAAA,EACR;AAEA,MAAK,KAAK,WAAY,GAAI,GAAI;AAC7B,WAAO;AAAA,EACR;AAEA,SAAO,QAAQ,QAAS;AAAA,IACvB;AAAA,MACC,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,KAAK,SAAS,YAAQ,yBAAc,GAAI,IAAI;AAAA,MAC5C;AAAA,IACD;AAAA,EACD,CAAE;AACH;AAEA,IAAM,qBAAqB,OAC1B,KACA,kBACA,wBACA,sBACA,aACA,iBACI;AACJ,QAAM,EAAE,qBAAqB,IAAI;AAEjC,QAAM,UAAU,MAAM,uBAAwB,KAAK,gBAAiB;AAGpE,UAAQ,IAAK,CAAE,WAAY;AAC1B,QAAK,OAAQ,OAAO,EAAG,MAAM,aAAc;AAC1C,aAAO,cAAc;AACrB,aAAO;AAAA,IACR,WAAY,OAAQ,OAAO,EAAG,MAAM,cAAe;AAClD,aAAO,aAAa;AACpB,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAE;AAGF,MAAK,sBAAuB;AAC3B,WAAO;AAAA,EACR;AAgBA,aAAO,mBAAAA,SAAW,GAAI,KAAK,CAAE,uBAC1B,UACA,QAAQ,OAAQ;AAAA;AAAA;AAAA;AAAA,IAIhB,OAAO;AAAA;AAAA,IACP,KAAK;AAAA;AAAA,IACL,MAAM;AAAA,EACN,CAAE;AACN;AAEe,SAAR,iBACN,kBACA,kBACA,sBACC;AACD,QAAM,EAAE,wBAAwB,aAAa,aAAa,QAAI;AAAA,IAC7D,CAAE,WAAY;AACb,YAAM,EAAE,YAAY,IAAI,OAAQ,aAAAC,KAAiB;AAEjD,aAAO;AAAA,QACN,aAAa,YAAY,EAAE;AAAA,QAC3B,cAAc,YAAY,EAAE;AAAA,QAC5B,wBACC,YAAY,EAAE;AAAA,MAChB;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AAEA,QAAM,qBAAqB,mBACxB,oBACA;AAEH,aAAO;AAAA,IACN,CAAE,KAAK,EAAE,qBAAqB,MAAO;AACpC,iBAAO,mBAAAD,SAAW,GAAI,IACnB,mBAAoB,KAAK,EAAE,qBAAqB,CAAE,IAClD;AAAA,QACA;AAAA,QACA,EAAE,GAAG,kBAAkB,qBAAqB;AAAA,QAC5C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACA;AAAA,IACJ;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;",
6
6
  "names": ["isURLLike", "blockEditorStore"]
7
7
  }
@@ -29,6 +29,49 @@ var import_blocks = require("@wordpress/blocks");
29
29
  var import_store = require("../../store/index.cjs");
30
30
  var noop = () => {
31
31
  };
32
+ function cloneBlockWithMapping(block, mapping) {
33
+ const clonedBlock = (0, import_blocks.cloneBlock)(block);
34
+ mapping.externalToInternal.set(block.clientId, clonedBlock.clientId);
35
+ mapping.internalToExternal.set(clonedBlock.clientId, block.clientId);
36
+ if (block.innerBlocks?.length) {
37
+ clonedBlock.innerBlocks = block.innerBlocks.map((innerBlock) => {
38
+ const clonedInner = cloneBlockWithMapping(innerBlock, mapping);
39
+ return clonedInner;
40
+ });
41
+ }
42
+ return clonedBlock;
43
+ }
44
+ function restoreExternalIds(blocks, mapping) {
45
+ return blocks.map((block) => {
46
+ const externalId = mapping.internalToExternal.get(block.clientId);
47
+ return {
48
+ ...block,
49
+ // Use external ID if available, otherwise keep internal ID (for new blocks)
50
+ clientId: externalId ?? block.clientId,
51
+ innerBlocks: restoreExternalIds(block.innerBlocks, mapping)
52
+ };
53
+ });
54
+ }
55
+ function restoreSelectionIds(selection, mapping) {
56
+ const { selectionStart, selectionEnd, initialPosition } = selection;
57
+ const restoreClientId = (selectionState) => {
58
+ if (!selectionState?.clientId) {
59
+ return selectionState;
60
+ }
61
+ const externalId = mapping.internalToExternal.get(
62
+ selectionState.clientId
63
+ );
64
+ return {
65
+ ...selectionState,
66
+ clientId: externalId ?? selectionState.clientId
67
+ };
68
+ };
69
+ return {
70
+ selectionStart: restoreClientId(selectionStart),
71
+ selectionEnd: restoreClientId(selectionEnd),
72
+ initialPosition
73
+ };
74
+ }
32
75
  function useBlockSync({
33
76
  clientId = null,
34
77
  value: controlledBlocks,
@@ -53,6 +96,10 @@ function useBlockSync({
53
96
  );
54
97
  const pendingChangesRef = (0, import_element.useRef)({ incoming: null, outgoing: [] });
55
98
  const subscribedRef = (0, import_element.useRef)(false);
99
+ const idMappingRef = (0, import_element.useRef)({
100
+ externalToInternal: /* @__PURE__ */ new Map(),
101
+ internalToExternal: /* @__PURE__ */ new Map()
102
+ });
56
103
  const setControlledBlocks = () => {
57
104
  if (!controlledBlocks) {
58
105
  return;
@@ -61,8 +108,10 @@ function useBlockSync({
61
108
  if (clientId) {
62
109
  registry.batch(() => {
63
110
  setHasControlledInnerBlocks(clientId, true);
111
+ idMappingRef.current.externalToInternal.clear();
112
+ idMappingRef.current.internalToExternal.clear();
64
113
  const storeBlocks = controlledBlocks.map(
65
- (block) => (0, import_blocks.cloneBlock)(block)
114
+ (block) => cloneBlockWithMapping(block, idMappingRef.current)
66
115
  );
67
116
  if (subscribedRef.current) {
68
117
  pendingChangesRef.current.incoming = storeBlocks;
@@ -152,14 +201,17 @@ function useBlockSync({
152
201
  const didPersistenceChange = previousAreBlocksDifferent && !areBlocksDifferent && newIsPersistent && !isPersistent;
153
202
  if (areBlocksDifferent || didPersistenceChange) {
154
203
  isPersistent = newIsPersistent;
155
- pendingChangesRef.current.outgoing.push(blocks);
204
+ const blocksForParent = clientId ? restoreExternalIds(blocks, idMappingRef.current) : blocks;
205
+ const selection = {
206
+ selectionStart: getSelectionStart(),
207
+ selectionEnd: getSelectionEnd(),
208
+ initialPosition: getSelectedBlocksInitialCaretPosition()
209
+ };
210
+ const selectionForParent = clientId ? restoreSelectionIds(selection, idMappingRef.current) : selection;
211
+ pendingChangesRef.current.outgoing.push(blocksForParent);
156
212
  const updateParent = isPersistent ? onChangeRef.current : onInputRef.current;
157
- updateParent(blocks, {
158
- selection: {
159
- selectionStart: getSelectionStart(),
160
- selectionEnd: getSelectionEnd(),
161
- initialPosition: getSelectedBlocksInitialCaretPosition()
162
- }
213
+ updateParent(blocksForParent, {
214
+ selection: selectionForParent
163
215
  });
164
216
  }
165
217
  previousAreBlocksDifferent = areBlocksDifferent;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/provider/use-block-sync.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useEffect, useRef } from '@wordpress/element';\nimport { useRegistry, useSelect } from '@wordpress/data';\nimport { cloneBlock } from '@wordpress/blocks';\n\n/**\n * Internal dependencies\n */\nimport { store as blockEditorStore } from '../../store';\n\nconst noop = () => {};\n\n/**\n * A function to call when the block value has been updated in the block-editor\n * store.\n *\n * @callback onBlockUpdate\n * @param {Object[]} blocks The updated blocks.\n * @param {Object} options The updated block options, such as selectionStart\n * and selectionEnd.\n */\n\n/**\n * useBlockSync is a side effect which handles bidirectional sync between the\n * block-editor store and a controlling data source which provides blocks. This\n * is most commonly used by the BlockEditorProvider to synchronize the contents\n * of the block-editor store with the root entity, like a post.\n *\n * Another example would be the template part block, which provides blocks from\n * a separate entity data source than a root entity. This hook syncs edits to\n * the template part in the block editor back to the entity and vice-versa.\n *\n * Here are some of its basic functions:\n * - Initializes the block-editor store for the given clientID to the blocks\n * given via props.\n * - Adds incoming changes (like undo) to the block-editor store.\n * - Adds outgoing changes (like editing content) to the controlling entity,\n * determining if a change should be considered persistent or not.\n * - Handles edge cases and race conditions which occur in those operations.\n * - Ignores changes which happen to other entities (like nested inner block\n * controllers.\n * - Passes selection state from the block-editor store to the controlling entity.\n *\n * @param {Object} props Props for the block sync hook\n * @param {string} props.clientId The client ID of the inner block controller.\n * If none is passed, then it is assumed to be a\n * root controller rather than an inner block\n * controller.\n * @param {Object[]} props.value The control value for the blocks. This value\n * is used to initialize the block-editor store\n * and for resetting the blocks to incoming\n * changes like undo.\n * @param {Object} props.selection The selection state responsible to restore the selection on undo/redo.\n * @param {onBlockUpdate} props.onChange Function to call when a persistent\n * change has been made in the block-editor blocks\n * for the given clientId. For example, after\n * this function is called, an entity is marked\n * dirty because it has changes to save.\n * @param {onBlockUpdate} props.onInput Function to call when a non-persistent\n * change has been made in the block-editor blocks\n * for the given clientId. When this is called,\n * controlling sources do not become dirty.\n */\nexport default function useBlockSync( {\n\tclientId = null,\n\tvalue: controlledBlocks,\n\tselection: controlledSelection,\n\tonChange = noop,\n\tonInput = noop,\n} ) {\n\tconst registry = useRegistry();\n\n\tconst {\n\t\tresetBlocks,\n\t\tresetSelection,\n\t\treplaceInnerBlocks,\n\t\tsetHasControlledInnerBlocks,\n\t\t__unstableMarkNextChangeAsNotPersistent,\n\t} = registry.dispatch( blockEditorStore );\n\tconst { getBlockName, getBlocks, getSelectionStart, getSelectionEnd } =\n\t\tregistry.select( blockEditorStore );\n\tconst isControlled = useSelect(\n\t\t( select ) => {\n\t\t\treturn (\n\t\t\t\t! clientId ||\n\t\t\t\tselect( blockEditorStore ).areInnerBlocksControlled( clientId )\n\t\t\t);\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\tconst pendingChangesRef = useRef( { incoming: null, outgoing: [] } );\n\tconst subscribedRef = useRef( false );\n\n\tconst setControlledBlocks = () => {\n\t\tif ( ! controlledBlocks ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't need to persist this change because we only replace\n\t\t// controlled inner blocks when the change was caused by an entity,\n\t\t// and so it would already be persisted.\n\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\tif ( clientId ) {\n\t\t\t// It is important to batch here because otherwise,\n\t\t\t// as soon as `setHasControlledInnerBlocks` is called\n\t\t\t// the effect to restore might be triggered\n\t\t\t// before the actual blocks get set properly in state.\n\t\t\tregistry.batch( () => {\n\t\t\t\tsetHasControlledInnerBlocks( clientId, true );\n\t\t\t\tconst storeBlocks = controlledBlocks.map( ( block ) =>\n\t\t\t\t\tcloneBlock( block )\n\t\t\t\t);\n\t\t\t\tif ( subscribedRef.current ) {\n\t\t\t\t\tpendingChangesRef.current.incoming = storeBlocks;\n\t\t\t\t}\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\treplaceInnerBlocks( clientId, storeBlocks );\n\t\t\t} );\n\t\t} else {\n\t\t\tif ( subscribedRef.current ) {\n\t\t\t\tpendingChangesRef.current.incoming = controlledBlocks;\n\t\t\t}\n\t\t\tresetBlocks( controlledBlocks );\n\t\t}\n\t};\n\n\t// Clean up the changes made by setControlledBlocks() when the component\n\t// containing useBlockSync() unmounts.\n\tconst unsetControlledBlocks = () => {\n\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\tif ( clientId ) {\n\t\t\tsetHasControlledInnerBlocks( clientId, false );\n\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\treplaceInnerBlocks( clientId, [] );\n\t\t} else {\n\t\t\tresetBlocks( [] );\n\t\t}\n\t};\n\n\t// Add a subscription to the block-editor registry to detect when changes\n\t// have been made. This lets us inform the data source of changes. This\n\t// is an effect so that the subscriber can run synchronously without\n\t// waiting for React renders for changes.\n\tconst onInputRef = useRef( onInput );\n\tconst onChangeRef = useRef( onChange );\n\tuseEffect( () => {\n\t\tonInputRef.current = onInput;\n\t\tonChangeRef.current = onChange;\n\t}, [ onInput, onChange ] );\n\n\t// Determine if blocks need to be reset when they change.\n\tuseEffect( () => {\n\t\tif ( pendingChangesRef.current.outgoing.includes( controlledBlocks ) ) {\n\t\t\t// Skip block reset if the value matches expected outbound sync\n\t\t\t// triggered by this component by a preceding change detection.\n\t\t\t// Only skip if the value matches expectation, since a reset should\n\t\t\t// still occur if the value is modified (not equal by reference),\n\t\t\t// to allow that the consumer may apply modifications to reflect\n\t\t\t// back on the editor.\n\t\t\tif (\n\t\t\t\tpendingChangesRef.current.outgoing[\n\t\t\t\t\tpendingChangesRef.current.outgoing.length - 1\n\t\t\t\t] === controlledBlocks\n\t\t\t) {\n\t\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\t}\n\t\t} else if ( getBlocks( clientId ) !== controlledBlocks ) {\n\t\t\t// Reset changing value in all other cases than the sync described\n\t\t\t// above. Since this can be reached in an update following an out-\n\t\t\t// bound sync, unset the outbound value to avoid considering it in\n\t\t\t// subsequent renders.\n\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\tsetControlledBlocks();\n\n\t\t\tif ( controlledSelection ) {\n\t\t\t\tresetSelection(\n\t\t\t\t\tcontrolledSelection.selectionStart,\n\t\t\t\t\tcontrolledSelection.selectionEnd,\n\t\t\t\t\tcontrolledSelection.initialPosition\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}, [ controlledBlocks, clientId ] );\n\n\tconst isMountedRef = useRef( false );\n\n\tuseEffect( () => {\n\t\t// On mount, controlled blocks are already set in the effect above.\n\t\tif ( ! isMountedRef.current ) {\n\t\t\tisMountedRef.current = true;\n\t\t\treturn;\n\t\t}\n\n\t\t// When the block becomes uncontrolled, it means its inner state has been reset\n\t\t// we need to take the blocks again from the external value property.\n\t\tif ( ! isControlled ) {\n\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\tsetControlledBlocks();\n\t\t}\n\t}, [ isControlled ] );\n\n\tuseEffect( () => {\n\t\tconst {\n\t\t\tgetSelectedBlocksInitialCaretPosition,\n\t\t\tisLastBlockChangePersistent,\n\t\t\t__unstableIsLastBlockChangeIgnored,\n\t\t\tareInnerBlocksControlled,\n\t\t} = registry.select( blockEditorStore );\n\n\t\tlet blocks = getBlocks( clientId );\n\t\tlet isPersistent = isLastBlockChangePersistent();\n\t\tlet previousAreBlocksDifferent = false;\n\n\t\tsubscribedRef.current = true;\n\t\tconst unsubscribe = registry.subscribe( () => {\n\t\t\t// Sometimes, when changing block lists, lingering subscriptions\n\t\t\t// might trigger before they are cleaned up. If the block for which\n\t\t\t// the subscription runs is no longer in the store, this would clear\n\t\t\t// its parent entity's block list. To avoid this, we bail out if\n\t\t\t// the subscription is triggering for a block (`clientId !== null`)\n\t\t\t// and its block name can't be found because it's not on the list.\n\t\t\t// (`getBlockName( clientId ) === null`).\n\t\t\tif ( clientId !== null && getBlockName( clientId ) === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// When RESET_BLOCKS on parent blocks get called, the controlled blocks\n\t\t\t// can reset to uncontrolled, in these situations, it means we need to populate\n\t\t\t// the blocks again from the external blocks (the value property here)\n\t\t\t// and we should stop triggering onChange\n\t\t\tconst isStillControlled =\n\t\t\t\t! clientId || areInnerBlocksControlled( clientId );\n\t\t\tif ( ! isStillControlled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst newIsPersistent = isLastBlockChangePersistent();\n\t\t\tconst newBlocks = getBlocks( clientId );\n\t\t\tconst areBlocksDifferent = newBlocks !== blocks;\n\t\t\tblocks = newBlocks;\n\t\t\tif (\n\t\t\t\tareBlocksDifferent &&\n\t\t\t\t( pendingChangesRef.current.incoming ||\n\t\t\t\t\t__unstableIsLastBlockChangeIgnored() )\n\t\t\t) {\n\t\t\t\tpendingChangesRef.current.incoming = null;\n\t\t\t\tisPersistent = newIsPersistent;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Since we often dispatch an action to mark the previous action as\n\t\t\t// persistent, we need to make sure that the blocks changed on the\n\t\t\t// previous action before committing the change.\n\t\t\tconst didPersistenceChange =\n\t\t\t\tpreviousAreBlocksDifferent &&\n\t\t\t\t! areBlocksDifferent &&\n\t\t\t\tnewIsPersistent &&\n\t\t\t\t! isPersistent;\n\n\t\t\tif ( areBlocksDifferent || didPersistenceChange ) {\n\t\t\t\tisPersistent = newIsPersistent;\n\t\t\t\t// We know that onChange/onInput will update controlledBlocks.\n\t\t\t\t// We need to be aware that it was caused by an outgoing change\n\t\t\t\t// so that we do not treat it as an incoming change later on,\n\t\t\t\t// which would cause a block reset.\n\t\t\t\tpendingChangesRef.current.outgoing.push( blocks );\n\n\t\t\t\t// Inform the controlling entity that changes have been made to\n\t\t\t\t// the block-editor store they should be aware about.\n\t\t\t\tconst updateParent = isPersistent\n\t\t\t\t\t? onChangeRef.current\n\t\t\t\t\t: onInputRef.current;\n\t\t\t\tupdateParent( blocks, {\n\t\t\t\t\tselection: {\n\t\t\t\t\t\tselectionStart: getSelectionStart(),\n\t\t\t\t\t\tselectionEnd: getSelectionEnd(),\n\t\t\t\t\t\tinitialPosition:\n\t\t\t\t\t\t\tgetSelectedBlocksInitialCaretPosition(),\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t\tpreviousAreBlocksDifferent = areBlocksDifferent;\n\t\t}, blockEditorStore );\n\n\t\treturn () => {\n\t\t\tsubscribedRef.current = false;\n\t\t\tunsubscribe();\n\t\t};\n\t}, [ registry, clientId ] );\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tunsetControlledBlocks();\n\t\t};\n\t}, [] );\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,qBAAkC;AAClC,kBAAuC;AACvC,oBAA2B;AAK3B,mBAA0C;AAE1C,IAAM,OAAO,MAAM;AAAC;AAqDL,SAAR,aAA+B;AAAA,EACrC,WAAW;AAAA,EACX,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AACX,GAAI;AACH,QAAM,eAAW,yBAAY;AAE7B,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,SAAS,SAAU,aAAAA,KAAiB;AACxC,QAAM,EAAE,cAAc,WAAW,mBAAmB,gBAAgB,IACnE,SAAS,OAAQ,aAAAA,KAAiB;AACnC,QAAM,mBAAe;AAAA,IACpB,CAAE,WAAY;AACb,aACC,CAAE,YACF,OAAQ,aAAAA,KAAiB,EAAE,yBAA0B,QAAS;AAAA,IAEhE;AAAA,IACA,CAAE,QAAS;AAAA,EACZ;AAEA,QAAM,wBAAoB,uBAAQ,EAAE,UAAU,MAAM,UAAU,CAAC,EAAE,CAAE;AACnE,QAAM,oBAAgB,uBAAQ,KAAM;AAEpC,QAAM,sBAAsB,MAAM;AACjC,QAAK,CAAE,kBAAmB;AACzB;AAAA,IACD;AAKA,4CAAwC;AACxC,QAAK,UAAW;AAKf,eAAS,MAAO,MAAM;AACrB,oCAA6B,UAAU,IAAK;AAC5C,cAAM,cAAc,iBAAiB;AAAA,UAAK,CAAE,cAC3C,0BAAY,KAAM;AAAA,QACnB;AACA,YAAK,cAAc,SAAU;AAC5B,4BAAkB,QAAQ,WAAW;AAAA,QACtC;AACA,gDAAwC;AACxC,2BAAoB,UAAU,WAAY;AAAA,MAC3C,CAAE;AAAA,IACH,OAAO;AACN,UAAK,cAAc,SAAU;AAC5B,0BAAkB,QAAQ,WAAW;AAAA,MACtC;AACA,kBAAa,gBAAiB;AAAA,IAC/B;AAAA,EACD;AAIA,QAAM,wBAAwB,MAAM;AACnC,4CAAwC;AACxC,QAAK,UAAW;AACf,kCAA6B,UAAU,KAAM;AAC7C,8CAAwC;AACxC,yBAAoB,UAAU,CAAC,CAAE;AAAA,IAClC,OAAO;AACN,kBAAa,CAAC,CAAE;AAAA,IACjB;AAAA,EACD;AAMA,QAAM,iBAAa,uBAAQ,OAAQ;AACnC,QAAM,kBAAc,uBAAQ,QAAS;AACrC,gCAAW,MAAM;AAChB,eAAW,UAAU;AACrB,gBAAY,UAAU;AAAA,EACvB,GAAG,CAAE,SAAS,QAAS,CAAE;AAGzB,gCAAW,MAAM;AAChB,QAAK,kBAAkB,QAAQ,SAAS,SAAU,gBAAiB,GAAI;AAOtE,UACC,kBAAkB,QAAQ,SACzB,kBAAkB,QAAQ,SAAS,SAAS,CAC7C,MAAM,kBACL;AACD,0BAAkB,QAAQ,WAAW,CAAC;AAAA,MACvC;AAAA,IACD,WAAY,UAAW,QAAS,MAAM,kBAAmB;AAKxD,wBAAkB,QAAQ,WAAW,CAAC;AACtC,0BAAoB;AAEpB,UAAK,qBAAsB;AAC1B;AAAA,UACC,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,QACrB;AAAA,MACD;AAAA,IACD;AAAA,EACD,GAAG,CAAE,kBAAkB,QAAS,CAAE;AAElC,QAAM,mBAAe,uBAAQ,KAAM;AAEnC,gCAAW,MAAM;AAEhB,QAAK,CAAE,aAAa,SAAU;AAC7B,mBAAa,UAAU;AACvB;AAAA,IACD;AAIA,QAAK,CAAE,cAAe;AACrB,wBAAkB,QAAQ,WAAW,CAAC;AACtC,0BAAoB;AAAA,IACrB;AAAA,EACD,GAAG,CAAE,YAAa,CAAE;AAEpB,gCAAW,MAAM;AAChB,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,IAAI,SAAS,OAAQ,aAAAA,KAAiB;AAEtC,QAAI,SAAS,UAAW,QAAS;AACjC,QAAI,eAAe,4BAA4B;AAC/C,QAAI,6BAA6B;AAEjC,kBAAc,UAAU;AACxB,UAAM,cAAc,SAAS,UAAW,MAAM;AAQ7C,UAAK,aAAa,QAAQ,aAAc,QAAS,MAAM,MAAO;AAC7D;AAAA,MACD;AAMA,YAAM,oBACL,CAAE,YAAY,yBAA0B,QAAS;AAClD,UAAK,CAAE,mBAAoB;AAC1B;AAAA,MACD;AAEA,YAAM,kBAAkB,4BAA4B;AACpD,YAAM,YAAY,UAAW,QAAS;AACtC,YAAM,qBAAqB,cAAc;AACzC,eAAS;AACT,UACC,uBACE,kBAAkB,QAAQ,YAC3B,mCAAmC,IACnC;AACD,0BAAkB,QAAQ,WAAW;AACrC,uBAAe;AACf;AAAA,MACD;AAKA,YAAM,uBACL,8BACA,CAAE,sBACF,mBACA,CAAE;AAEH,UAAK,sBAAsB,sBAAuB;AACjD,uBAAe;AAKf,0BAAkB,QAAQ,SAAS,KAAM,MAAO;AAIhD,cAAM,eAAe,eAClB,YAAY,UACZ,WAAW;AACd,qBAAc,QAAQ;AAAA,UACrB,WAAW;AAAA,YACV,gBAAgB,kBAAkB;AAAA,YAClC,cAAc,gBAAgB;AAAA,YAC9B,iBACC,sCAAsC;AAAA,UACxC;AAAA,QACD,CAAE;AAAA,MACH;AACA,mCAA6B;AAAA,IAC9B,GAAG,aAAAA,KAAiB;AAEpB,WAAO,MAAM;AACZ,oBAAc,UAAU;AACxB,kBAAY;AAAA,IACb;AAAA,EACD,GAAG,CAAE,UAAU,QAAS,CAAE;AAE1B,gCAAW,MAAM;AAChB,WAAO,MAAM;AACZ,4BAAsB;AAAA,IACvB;AAAA,EACD,GAAG,CAAC,CAAE;AACP;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useEffect, useRef } from '@wordpress/element';\nimport { useRegistry, useSelect } from '@wordpress/data';\nimport { cloneBlock } from '@wordpress/blocks';\n\n/**\n * Internal dependencies\n */\nimport { store as blockEditorStore } from '../../store';\n\nconst noop = () => {};\n\n/**\n * Clones a block and its inner blocks, building a bidirectional mapping\n * between external (original) and internal (cloned) client IDs.\n *\n * This allows the block editor to use unique internal IDs while preserving\n * stable external IDs for features like real-time collaboration.\n *\n * @param {Object} block The block to clone.\n * @param {Object} mapping The mapping object with externalToInternal and internalToExternal Maps.\n * @return {Object} The cloned block with a new clientId.\n */\nfunction cloneBlockWithMapping( block, mapping ) {\n\tconst clonedBlock = cloneBlock( block );\n\n\t// Build bidirectional mapping\n\tmapping.externalToInternal.set( block.clientId, clonedBlock.clientId );\n\tmapping.internalToExternal.set( clonedBlock.clientId, block.clientId );\n\n\t// Recursively map inner blocks\n\tif ( block.innerBlocks?.length ) {\n\t\tclonedBlock.innerBlocks = block.innerBlocks.map( ( innerBlock ) => {\n\t\t\tconst clonedInner = cloneBlockWithMapping( innerBlock, mapping );\n\t\t\t// The clonedBlock already has cloned inner blocks from cloneBlock(),\n\t\t\t// but we need to use our mapped versions to maintain the mapping.\n\t\t\treturn clonedInner;\n\t\t} );\n\t}\n\n\treturn clonedBlock;\n}\n\n/**\n * Restores external (original) client IDs on blocks before passing them\n * to onChange/onInput callbacks.\n *\n * @param {Object[]} blocks The blocks with internal client IDs.\n * @param {Object} mapping The mapping object with internalToExternal Map.\n * @return {Object[]} Blocks with external client IDs restored.\n */\nfunction restoreExternalIds( blocks, mapping ) {\n\treturn blocks.map( ( block ) => {\n\t\tconst externalId = mapping.internalToExternal.get( block.clientId );\n\t\treturn {\n\t\t\t...block,\n\t\t\t// Use external ID if available, otherwise keep internal ID (for new blocks)\n\t\t\tclientId: externalId ?? block.clientId,\n\t\t\tinnerBlocks: restoreExternalIds( block.innerBlocks, mapping ),\n\t\t};\n\t} );\n}\n\n/**\n * Restores external client IDs in selection state.\n *\n * @param {Object} selection The selection state with internal client IDs.\n * @param {Object} mapping The mapping object with internalToExternal Map.\n * @return {Object} Selection state with external client IDs.\n */\nfunction restoreSelectionIds( selection, mapping ) {\n\tconst { selectionStart, selectionEnd, initialPosition } = selection;\n\n\tconst restoreClientId = ( selectionState ) => {\n\t\tif ( ! selectionState?.clientId ) {\n\t\t\treturn selectionState;\n\t\t}\n\t\tconst externalId = mapping.internalToExternal.get(\n\t\t\tselectionState.clientId\n\t\t);\n\t\treturn {\n\t\t\t...selectionState,\n\t\t\tclientId: externalId ?? selectionState.clientId,\n\t\t};\n\t};\n\n\treturn {\n\t\tselectionStart: restoreClientId( selectionStart ),\n\t\tselectionEnd: restoreClientId( selectionEnd ),\n\t\tinitialPosition,\n\t};\n}\n\n/**\n * A function to call when the block value has been updated in the block-editor\n * store.\n *\n * @callback onBlockUpdate\n * @param {Object[]} blocks The updated blocks.\n * @param {Object} options The updated block options, such as selectionStart\n * and selectionEnd.\n */\n\n/**\n * useBlockSync is a side effect which handles bidirectional sync between the\n * block-editor store and a controlling data source which provides blocks. This\n * is most commonly used by the BlockEditorProvider to synchronize the contents\n * of the block-editor store with the root entity, like a post.\n *\n * Another example would be the template part block, which provides blocks from\n * a separate entity data source than a root entity. This hook syncs edits to\n * the template part in the block editor back to the entity and vice-versa.\n *\n * Here are some of its basic functions:\n * - Initializes the block-editor store for the given clientID to the blocks\n * given via props.\n * - Adds incoming changes (like undo) to the block-editor store.\n * - Adds outgoing changes (like editing content) to the controlling entity,\n * determining if a change should be considered persistent or not.\n * - Handles edge cases and race conditions which occur in those operations.\n * - Ignores changes which happen to other entities (like nested inner block\n * controllers.\n * - Passes selection state from the block-editor store to the controlling entity.\n *\n * @param {Object} props Props for the block sync hook\n * @param {string} props.clientId The client ID of the inner block controller.\n * If none is passed, then it is assumed to be a\n * root controller rather than an inner block\n * controller.\n * @param {Object[]} props.value The control value for the blocks. This value\n * is used to initialize the block-editor store\n * and for resetting the blocks to incoming\n * changes like undo.\n * @param {Object} props.selection The selection state responsible to restore the selection on undo/redo.\n * @param {onBlockUpdate} props.onChange Function to call when a persistent\n * change has been made in the block-editor blocks\n * for the given clientId. For example, after\n * this function is called, an entity is marked\n * dirty because it has changes to save.\n * @param {onBlockUpdate} props.onInput Function to call when a non-persistent\n * change has been made in the block-editor blocks\n * for the given clientId. When this is called,\n * controlling sources do not become dirty.\n */\nexport default function useBlockSync( {\n\tclientId = null,\n\tvalue: controlledBlocks,\n\tselection: controlledSelection,\n\tonChange = noop,\n\tonInput = noop,\n} ) {\n\tconst registry = useRegistry();\n\n\tconst {\n\t\tresetBlocks,\n\t\tresetSelection,\n\t\treplaceInnerBlocks,\n\t\tsetHasControlledInnerBlocks,\n\t\t__unstableMarkNextChangeAsNotPersistent,\n\t} = registry.dispatch( blockEditorStore );\n\tconst { getBlockName, getBlocks, getSelectionStart, getSelectionEnd } =\n\t\tregistry.select( blockEditorStore );\n\tconst isControlled = useSelect(\n\t\t( select ) => {\n\t\t\treturn (\n\t\t\t\t! clientId ||\n\t\t\t\tselect( blockEditorStore ).areInnerBlocksControlled( clientId )\n\t\t\t);\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\tconst pendingChangesRef = useRef( { incoming: null, outgoing: [] } );\n\tconst subscribedRef = useRef( false );\n\n\t// Mapping between external (original) and internal (cloned) client IDs.\n\t// This allows stable external IDs while using unique internal IDs.\n\tconst idMappingRef = useRef( {\n\t\texternalToInternal: new Map(),\n\t\tinternalToExternal: new Map(),\n\t} );\n\n\tconst setControlledBlocks = () => {\n\t\tif ( ! controlledBlocks ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't need to persist this change because we only replace\n\t\t// controlled inner blocks when the change was caused by an entity,\n\t\t// and so it would already be persisted.\n\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\tif ( clientId ) {\n\t\t\t// It is important to batch here because otherwise,\n\t\t\t// as soon as `setHasControlledInnerBlocks` is called\n\t\t\t// the effect to restore might be triggered\n\t\t\t// before the actual blocks get set properly in state.\n\t\t\tregistry.batch( () => {\n\t\t\t\tsetHasControlledInnerBlocks( clientId, true );\n\n\t\t\t\t// Clear previous mappings and build new ones during cloning.\n\t\t\t\t// This ensures the mapping stays in sync with the current blocks.\n\t\t\t\tidMappingRef.current.externalToInternal.clear();\n\t\t\t\tidMappingRef.current.internalToExternal.clear();\n\n\t\t\t\tconst storeBlocks = controlledBlocks.map( ( block ) =>\n\t\t\t\t\tcloneBlockWithMapping( block, idMappingRef.current )\n\t\t\t\t);\n\t\t\t\tif ( subscribedRef.current ) {\n\t\t\t\t\tpendingChangesRef.current.incoming = storeBlocks;\n\t\t\t\t}\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\treplaceInnerBlocks( clientId, storeBlocks );\n\t\t\t} );\n\t\t} else {\n\t\t\tif ( subscribedRef.current ) {\n\t\t\t\tpendingChangesRef.current.incoming = controlledBlocks;\n\t\t\t}\n\t\t\tresetBlocks( controlledBlocks );\n\t\t}\n\t};\n\n\t// Clean up the changes made by setControlledBlocks() when the component\n\t// containing useBlockSync() unmounts.\n\tconst unsetControlledBlocks = () => {\n\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\tif ( clientId ) {\n\t\t\tsetHasControlledInnerBlocks( clientId, false );\n\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\treplaceInnerBlocks( clientId, [] );\n\t\t} else {\n\t\t\tresetBlocks( [] );\n\t\t}\n\t};\n\n\t// Add a subscription to the block-editor registry to detect when changes\n\t// have been made. This lets us inform the data source of changes. This\n\t// is an effect so that the subscriber can run synchronously without\n\t// waiting for React renders for changes.\n\tconst onInputRef = useRef( onInput );\n\tconst onChangeRef = useRef( onChange );\n\tuseEffect( () => {\n\t\tonInputRef.current = onInput;\n\t\tonChangeRef.current = onChange;\n\t}, [ onInput, onChange ] );\n\n\t// Determine if blocks need to be reset when they change.\n\tuseEffect( () => {\n\t\tif ( pendingChangesRef.current.outgoing.includes( controlledBlocks ) ) {\n\t\t\t// Skip block reset if the value matches expected outbound sync\n\t\t\t// triggered by this component by a preceding change detection.\n\t\t\t// Only skip if the value matches expectation, since a reset should\n\t\t\t// still occur if the value is modified (not equal by reference),\n\t\t\t// to allow that the consumer may apply modifications to reflect\n\t\t\t// back on the editor.\n\t\t\tif (\n\t\t\t\tpendingChangesRef.current.outgoing[\n\t\t\t\t\tpendingChangesRef.current.outgoing.length - 1\n\t\t\t\t] === controlledBlocks\n\t\t\t) {\n\t\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\t}\n\t\t} else if ( getBlocks( clientId ) !== controlledBlocks ) {\n\t\t\t// Reset changing value in all other cases than the sync described\n\t\t\t// above. Since this can be reached in an update following an out-\n\t\t\t// bound sync, unset the outbound value to avoid considering it in\n\t\t\t// subsequent renders.\n\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\tsetControlledBlocks();\n\n\t\t\tif ( controlledSelection ) {\n\t\t\t\tresetSelection(\n\t\t\t\t\tcontrolledSelection.selectionStart,\n\t\t\t\t\tcontrolledSelection.selectionEnd,\n\t\t\t\t\tcontrolledSelection.initialPosition\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}, [ controlledBlocks, clientId ] );\n\n\tconst isMountedRef = useRef( false );\n\n\tuseEffect( () => {\n\t\t// On mount, controlled blocks are already set in the effect above.\n\t\tif ( ! isMountedRef.current ) {\n\t\t\tisMountedRef.current = true;\n\t\t\treturn;\n\t\t}\n\n\t\t// When the block becomes uncontrolled, it means its inner state has been reset\n\t\t// we need to take the blocks again from the external value property.\n\t\tif ( ! isControlled ) {\n\t\t\tpendingChangesRef.current.outgoing = [];\n\t\t\tsetControlledBlocks();\n\t\t}\n\t}, [ isControlled ] );\n\n\tuseEffect( () => {\n\t\tconst {\n\t\t\tgetSelectedBlocksInitialCaretPosition,\n\t\t\tisLastBlockChangePersistent,\n\t\t\t__unstableIsLastBlockChangeIgnored,\n\t\t\tareInnerBlocksControlled,\n\t\t} = registry.select( blockEditorStore );\n\n\t\tlet blocks = getBlocks( clientId );\n\t\tlet isPersistent = isLastBlockChangePersistent();\n\t\tlet previousAreBlocksDifferent = false;\n\n\t\tsubscribedRef.current = true;\n\t\tconst unsubscribe = registry.subscribe( () => {\n\t\t\t// Sometimes, when changing block lists, lingering subscriptions\n\t\t\t// might trigger before they are cleaned up. If the block for which\n\t\t\t// the subscription runs is no longer in the store, this would clear\n\t\t\t// its parent entity's block list. To avoid this, we bail out if\n\t\t\t// the subscription is triggering for a block (`clientId !== null`)\n\t\t\t// and its block name can't be found because it's not on the list.\n\t\t\t// (`getBlockName( clientId ) === null`).\n\t\t\tif ( clientId !== null && getBlockName( clientId ) === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// When RESET_BLOCKS on parent blocks get called, the controlled blocks\n\t\t\t// can reset to uncontrolled, in these situations, it means we need to populate\n\t\t\t// the blocks again from the external blocks (the value property here)\n\t\t\t// and we should stop triggering onChange\n\t\t\tconst isStillControlled =\n\t\t\t\t! clientId || areInnerBlocksControlled( clientId );\n\t\t\tif ( ! isStillControlled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst newIsPersistent = isLastBlockChangePersistent();\n\t\t\tconst newBlocks = getBlocks( clientId );\n\t\t\tconst areBlocksDifferent = newBlocks !== blocks;\n\t\t\tblocks = newBlocks;\n\t\t\tif (\n\t\t\t\tareBlocksDifferent &&\n\t\t\t\t( pendingChangesRef.current.incoming ||\n\t\t\t\t\t__unstableIsLastBlockChangeIgnored() )\n\t\t\t) {\n\t\t\t\tpendingChangesRef.current.incoming = null;\n\t\t\t\tisPersistent = newIsPersistent;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Since we often dispatch an action to mark the previous action as\n\t\t\t// persistent, we need to make sure that the blocks changed on the\n\t\t\t// previous action before committing the change.\n\t\t\tconst didPersistenceChange =\n\t\t\t\tpreviousAreBlocksDifferent &&\n\t\t\t\t! areBlocksDifferent &&\n\t\t\t\tnewIsPersistent &&\n\t\t\t\t! isPersistent;\n\n\t\t\tif ( areBlocksDifferent || didPersistenceChange ) {\n\t\t\t\tisPersistent = newIsPersistent;\n\n\t\t\t\t// For inner block controllers (clientId is set), restore external IDs\n\t\t\t\t// before passing blocks to the parent. This maintains stable external\n\t\t\t\t// IDs for features like real-time collaboration while using unique\n\t\t\t\t// internal IDs in the block-editor store.\n\t\t\t\tconst blocksForParent = clientId\n\t\t\t\t\t? restoreExternalIds( blocks, idMappingRef.current )\n\t\t\t\t\t: blocks;\n\n\t\t\t\tconst selection = {\n\t\t\t\t\tselectionStart: getSelectionStart(),\n\t\t\t\t\tselectionEnd: getSelectionEnd(),\n\t\t\t\t\tinitialPosition: getSelectedBlocksInitialCaretPosition(),\n\t\t\t\t};\n\n\t\t\t\t// Also restore external IDs in selection state for inner block controllers.\n\t\t\t\tconst selectionForParent = clientId\n\t\t\t\t\t? restoreSelectionIds( selection, idMappingRef.current )\n\t\t\t\t\t: selection;\n\n\t\t\t\t// We know that onChange/onInput will update controlledBlocks.\n\t\t\t\t// We need to be aware that it was caused by an outgoing change\n\t\t\t\t// so that we do not treat it as an incoming change later on,\n\t\t\t\t// which would cause a block reset.\n\t\t\t\tpendingChangesRef.current.outgoing.push( blocksForParent );\n\n\t\t\t\t// Inform the controlling entity that changes have been made to\n\t\t\t\t// the block-editor store they should be aware about.\n\t\t\t\tconst updateParent = isPersistent\n\t\t\t\t\t? onChangeRef.current\n\t\t\t\t\t: onInputRef.current;\n\t\t\t\tupdateParent( blocksForParent, {\n\t\t\t\t\tselection: selectionForParent,\n\t\t\t\t} );\n\t\t\t}\n\t\t\tpreviousAreBlocksDifferent = areBlocksDifferent;\n\t\t}, blockEditorStore );\n\n\t\treturn () => {\n\t\t\tsubscribedRef.current = false;\n\t\t\tunsubscribe();\n\t\t};\n\t}, [ registry, clientId ] );\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tunsetControlledBlocks();\n\t\t};\n\t}, [] );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["blockEditorStore"]
7
7
  }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/block-editor/src/components/text-indent-control/index.js
21
+ var text_indent_control_exports = {};
22
+ __export(text_indent_control_exports, {
23
+ default: () => TextIndentControl
24
+ });
25
+ module.exports = __toCommonJS(text_indent_control_exports);
26
+ var import_components = require("@wordpress/components");
27
+ var import_i18n = require("@wordpress/i18n");
28
+ var import_use_settings = require("../use-settings/index.cjs");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ function TextIndentControl({
31
+ __next40pxDefaultSize = false,
32
+ value,
33
+ onChange,
34
+ __unstableInputWidth = "60px",
35
+ withSlider = false,
36
+ hasBottomMargin = false,
37
+ help,
38
+ ...otherProps
39
+ }) {
40
+ const [availableUnits] = (0, import_use_settings.useSettings)("spacing.units");
41
+ const units = (0, import_components.__experimentalUseCustomUnits)({
42
+ availableUnits: availableUnits || [
43
+ "px",
44
+ "em",
45
+ "rem",
46
+ "ch",
47
+ "%",
48
+ "vw",
49
+ "vh"
50
+ ],
51
+ defaultValues: { px: 16, em: 2, rem: 2, ch: 2 }
52
+ });
53
+ const [valueQuantity, valueUnit] = (0, import_components.__experimentalParseQuantityAndUnitFromRawValue)(
54
+ value,
55
+ units
56
+ );
57
+ const isValueUnitRelative = !!valueUnit && ["em", "rem", "%", "ch", "vw", "vh"].includes(valueUnit);
58
+ if (!withSlider) {
59
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
60
+ import_components.__experimentalUnitControl,
61
+ {
62
+ __next40pxDefaultSize,
63
+ __shouldNotWarnDeprecated36pxSize: true,
64
+ ...otherProps,
65
+ label: (0, import_i18n.__)("Line indent"),
66
+ value,
67
+ __unstableInputWidth,
68
+ units,
69
+ onChange,
70
+ help
71
+ }
72
+ );
73
+ }
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalView, { style: hasBottomMargin ? { marginBottom: 12 } : void 0, children: [
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.BaseControl.VisualLabel, { children: (0, import_i18n.__)("Line indent") }),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.Flex, { children: [
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.FlexItem, { isBlock: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ import_components.__experimentalUnitControl,
79
+ {
80
+ __next40pxDefaultSize,
81
+ __shouldNotWarnDeprecated36pxSize: true,
82
+ label: (0, import_i18n.__)("Line indent"),
83
+ labelPosition: "top",
84
+ hideLabelFromVision: true,
85
+ value,
86
+ onChange,
87
+ size: otherProps.size,
88
+ units,
89
+ __unstableInputWidth,
90
+ min: 0
91
+ }
92
+ ) }),
93
+ withSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.FlexItem, { isBlock: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalSpacer, { marginX: 2, marginBottom: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
94
+ import_components.RangeControl,
95
+ {
96
+ __next40pxDefaultSize,
97
+ __shouldNotWarnDeprecated36pxSize: true,
98
+ label: (0, import_i18n.__)("Line indent"),
99
+ hideLabelFromVision: true,
100
+ value: valueQuantity,
101
+ withInputField: false,
102
+ onChange: (newValue) => {
103
+ if (newValue === void 0) {
104
+ onChange?.(void 0);
105
+ } else {
106
+ onChange?.(
107
+ newValue + (valueUnit ?? "px")
108
+ );
109
+ }
110
+ },
111
+ min: 0,
112
+ max: isValueUnitRelative ? 10 : 100,
113
+ step: isValueUnitRelative ? 0.1 : 1,
114
+ initialPosition: 0
115
+ }
116
+ ) }) })
117
+ ] }),
118
+ help && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "components-base-control__help", children: help })
119
+ ] });
120
+ }
121
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/text-indent-control/index.js"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\t__experimentalUnitControl as UnitControl,\n\t__experimentalUseCustomUnits as useCustomUnits,\n\t__experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue,\n\t__experimentalView as View,\n\tRangeControl,\n\t__experimentalSpacer as Spacer,\n\tFlex,\n\tFlexItem,\n\tBaseControl,\n} from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { useSettings } from '../../components/use-settings';\n\n/**\n * Control for line text indent.\n *\n * @param {Object} props Component props.\n * @param {boolean} props.__next40pxDefaultSize Start opting into the larger default height that will become the default size in a future version.\n * @param {string} props.value Currently selected text indent.\n * @param {Function} props.onChange Handles change in text indent selection.\n * @param {string|number|undefined} props.__unstableInputWidth Input width to pass through to inner UnitControl. Should be a valid CSS value.\n * @param {boolean} props.withSlider Whether to show the slider control.\n * @param {boolean} props.hasBottomMargin Whether to add bottom margin below the control.\n * @param {string} props.help Help text to display below the control.\n *\n * @return {Element} Text indent control.\n */\nexport default function TextIndentControl( {\n\t__next40pxDefaultSize = false,\n\tvalue,\n\tonChange,\n\t__unstableInputWidth = '60px',\n\twithSlider = false,\n\thasBottomMargin = false,\n\thelp,\n\t...otherProps\n} ) {\n\tconst [ availableUnits ] = useSettings( 'spacing.units' );\n\tconst units = useCustomUnits( {\n\t\tavailableUnits: availableUnits || [\n\t\t\t'px',\n\t\t\t'em',\n\t\t\t'rem',\n\t\t\t'ch',\n\t\t\t'%',\n\t\t\t'vw',\n\t\t\t'vh',\n\t\t],\n\t\tdefaultValues: { px: 16, em: 2, rem: 2, ch: 2 },\n\t} );\n\n\tconst [ valueQuantity, valueUnit ] = parseQuantityAndUnitFromRawValue(\n\t\tvalue,\n\t\tunits\n\t);\n\tconst isValueUnitRelative =\n\t\t!! valueUnit &&\n\t\t[ 'em', 'rem', '%', 'ch', 'vw', 'vh' ].includes( valueUnit );\n\n\tif ( ! withSlider ) {\n\t\treturn (\n\t\t\t<UnitControl\n\t\t\t\t__next40pxDefaultSize={ __next40pxDefaultSize }\n\t\t\t\t__shouldNotWarnDeprecated36pxSize\n\t\t\t\t{ ...otherProps }\n\t\t\t\tlabel={ __( 'Line indent' ) }\n\t\t\t\tvalue={ value }\n\t\t\t\t__unstableInputWidth={ __unstableInputWidth }\n\t\t\t\tunits={ units }\n\t\t\t\tonChange={ onChange }\n\t\t\t\thelp={ help }\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<View style={ hasBottomMargin ? { marginBottom: 12 } : undefined }>\n\t\t\t<BaseControl.VisualLabel>\n\t\t\t\t{ __( 'Line indent' ) }\n\t\t\t</BaseControl.VisualLabel>\n\t\t\t<Flex>\n\t\t\t\t<FlexItem isBlock>\n\t\t\t\t\t<UnitControl\n\t\t\t\t\t\t__next40pxDefaultSize={ __next40pxDefaultSize }\n\t\t\t\t\t\t__shouldNotWarnDeprecated36pxSize\n\t\t\t\t\t\tlabel={ __( 'Line indent' ) }\n\t\t\t\t\t\tlabelPosition=\"top\"\n\t\t\t\t\t\thideLabelFromVision\n\t\t\t\t\t\tvalue={ value }\n\t\t\t\t\t\tonChange={ onChange }\n\t\t\t\t\t\tsize={ otherProps.size }\n\t\t\t\t\t\tunits={ units }\n\t\t\t\t\t\t__unstableInputWidth={ __unstableInputWidth }\n\t\t\t\t\t\tmin={ 0 }\n\t\t\t\t\t/>\n\t\t\t\t</FlexItem>\n\t\t\t\t{ withSlider && (\n\t\t\t\t\t<FlexItem isBlock>\n\t\t\t\t\t\t<Spacer marginX={ 2 } marginBottom={ 0 }>\n\t\t\t\t\t\t\t<RangeControl\n\t\t\t\t\t\t\t\t__next40pxDefaultSize={ __next40pxDefaultSize }\n\t\t\t\t\t\t\t\t__shouldNotWarnDeprecated36pxSize\n\t\t\t\t\t\t\t\tlabel={ __( 'Line indent' ) }\n\t\t\t\t\t\t\t\thideLabelFromVision\n\t\t\t\t\t\t\t\tvalue={ valueQuantity }\n\t\t\t\t\t\t\t\twithInputField={ false }\n\t\t\t\t\t\t\t\tonChange={ ( newValue ) => {\n\t\t\t\t\t\t\t\t\tif ( newValue === undefined ) {\n\t\t\t\t\t\t\t\t\t\tonChange?.( undefined );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tonChange?.(\n\t\t\t\t\t\t\t\t\t\t\tnewValue + ( valueUnit ?? 'px' )\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} }\n\t\t\t\t\t\t\t\tmin={ 0 }\n\t\t\t\t\t\t\t\tmax={ isValueUnitRelative ? 10 : 100 }\n\t\t\t\t\t\t\t\tstep={ isValueUnitRelative ? 0.1 : 1 }\n\t\t\t\t\t\t\t\tinitialPosition={ 0 }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Spacer>\n\t\t\t\t\t</FlexItem>\n\t\t\t\t) }\n\t\t\t</Flex>\n\t\t\t{ help && (\n\t\t\t\t<p className=\"components-base-control__help\">{ help }</p>\n\t\t\t) }\n\t\t</View>\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,wBAUO;AACP,kBAAmB;AAKnB,0BAA4B;AAkDzB;AAlCY,SAAR,kBAAoC;AAAA,EAC1C,wBAAwB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,uBAAuB;AAAA,EACvB,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB;AAAA,EACA,GAAG;AACJ,GAAI;AACH,QAAM,CAAE,cAAe,QAAI,iCAAa,eAAgB;AACxD,QAAM,YAAQ,kBAAAA,8BAAgB;AAAA,IAC7B,gBAAgB,kBAAkB;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA,eAAe,EAAE,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,IAAI,EAAE;AAAA,EAC/C,CAAE;AAEF,QAAM,CAAE,eAAe,SAAU,QAAI,kBAAAC;AAAA,IACpC;AAAA,IACA;AAAA,EACD;AACA,QAAM,sBACL,CAAC,CAAE,aACH,CAAE,MAAM,OAAO,KAAK,MAAM,MAAM,IAAK,EAAE,SAAU,SAAU;AAE5D,MAAK,CAAE,YAAa;AACnB,WACC;AAAA,MAAC,kBAAAC;AAAA,MAAA;AAAA,QACA;AAAA,QACA,mCAAiC;AAAA,QAC/B,GAAG;AAAA,QACL,WAAQ,gBAAI,aAAc;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACD;AAAA,EAEF;AAEA,SACC,6CAAC,kBAAAC,oBAAA,EAAK,OAAQ,kBAAkB,EAAE,cAAc,GAAG,IAAI,QACtD;AAAA,gDAAC,8BAAY,aAAZ,EACE,8BAAI,aAAc,GACrB;AAAA,IACA,6CAAC,0BACA;AAAA,kDAAC,8BAAS,SAAO,MAChB;AAAA,QAAC,kBAAAD;AAAA,QAAA;AAAA,UACA;AAAA,UACA,mCAAiC;AAAA,UACjC,WAAQ,gBAAI,aAAc;AAAA,UAC1B,eAAc;AAAA,UACd,qBAAmB;AAAA,UACnB;AAAA,UACA;AAAA,UACA,MAAO,WAAW;AAAA,UAClB;AAAA,UACA;AAAA,UACA,KAAM;AAAA;AAAA,MACP,GACD;AAAA,MACE,cACD,4CAAC,8BAAS,SAAO,MAChB,sDAAC,kBAAAE,sBAAA,EAAO,SAAU,GAAI,cAAe,GACpC;AAAA,QAAC;AAAA;AAAA,UACA;AAAA,UACA,mCAAiC;AAAA,UACjC,WAAQ,gBAAI,aAAc;AAAA,UAC1B,qBAAmB;AAAA,UACnB,OAAQ;AAAA,UACR,gBAAiB;AAAA,UACjB,UAAW,CAAE,aAAc;AAC1B,gBAAK,aAAa,QAAY;AAC7B,yBAAY,MAAU;AAAA,YACvB,OAAO;AACN;AAAA,gBACC,YAAa,aAAa;AAAA,cAC3B;AAAA,YACD;AAAA,UACD;AAAA,UACA,KAAM;AAAA,UACN,KAAM,sBAAsB,KAAK;AAAA,UACjC,MAAO,sBAAsB,MAAM;AAAA,UACnC,iBAAkB;AAAA;AAAA,MACnB,GACD,GACD;AAAA,OAEF;AAAA,IACE,QACD,4CAAC,OAAE,WAAU,iCAAkC,gBAAM;AAAA,KAEvD;AAEF;",
6
+ "names": ["useCustomUnits", "parseQuantityAndUnitFromRawValue", "UnitControl", "View", "Spacer"]
7
+ }
@@ -42,8 +42,10 @@ var import_compose = require("@wordpress/compose");
42
42
  var import_data = require("@wordpress/data");
43
43
  var import_url = require("@wordpress/url");
44
44
  var import_store = require("../../store/index.cjs");
45
+ var import_lock_unlock = require("../../lock-unlock.cjs");
45
46
  var import_jsx_runtime = require("react/jsx-runtime");
46
47
  var import_react = require("react");
48
+ var { ValidatedInputControl } = (0, import_lock_unlock.unlock)(import_components.privateApis);
47
49
  function isFunction(maybeFunc) {
48
50
  return typeof maybeFunc === "function";
49
51
  }
@@ -315,7 +317,9 @@ var URLInput = class extends import_element.Component {
315
317
  value = "",
316
318
  hideLabelFromVision = false,
317
319
  help = null,
318
- disabled = false
320
+ disabled = false,
321
+ customValidity,
322
+ markWhenOptional
319
323
  } = this.props;
320
324
  const {
321
325
  loading,
@@ -363,11 +367,27 @@ var URLInput = class extends import_element.Component {
363
367
  suffix: this.props.suffix,
364
368
  help
365
369
  };
370
+ const validationProps = {
371
+ customValidity,
372
+ // Suppress the "(Required)" indicator in the label.
373
+ // The field is still required for validation, but the indicator
374
+ // can be hidden when markWhenOptional is set to true.
375
+ ...markWhenOptional !== void 0 && {
376
+ markWhenOptional
377
+ }
378
+ };
366
379
  if (renderControl) {
367
380
  return renderControl(controlProps, inputProps, loading);
368
381
  }
369
382
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.BaseControl, { ...controlProps, children: [
370
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalInputControl, { ...inputProps, __next40pxDefaultSize: true }),
383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
384
+ ValidatedInputControl,
385
+ {
386
+ ...inputProps,
387
+ ...validationProps,
388
+ __next40pxDefaultSize: true
389
+ }
390
+ ),
371
391
  loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {})
372
392
  ] });
373
393
  }