@strapi/content-manager 5.53.0 → 5.55.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 (138) hide show
  1. package/dist/admin/components/ActionsDrawer.js +17 -6
  2. package/dist/admin/components/ActionsDrawer.js.map +1 -1
  3. package/dist/admin/components/ActionsDrawer.mjs +19 -8
  4. package/dist/admin/components/ActionsDrawer.mjs.map +1 -1
  5. package/dist/admin/components/LeftMenu.js +131 -52
  6. package/dist/admin/components/LeftMenu.js.map +1 -1
  7. package/dist/admin/components/LeftMenu.mjs +133 -54
  8. package/dist/admin/components/LeftMenu.mjs.map +1 -1
  9. package/dist/admin/history/components/VersionsList.js +37 -43
  10. package/dist/admin/history/components/VersionsList.js.map +1 -1
  11. package/dist/admin/history/components/VersionsList.mjs +37 -43
  12. package/dist/admin/history/components/VersionsList.mjs.map +1 -1
  13. package/dist/admin/hooks/useContentManagerInitData.js +3 -2
  14. package/dist/admin/hooks/useContentManagerInitData.js.map +1 -1
  15. package/dist/admin/hooks/useContentManagerInitData.mjs +3 -2
  16. package/dist/admin/hooks/useContentManagerInitData.mjs.map +1 -1
  17. package/dist/admin/hooks/useDocumentActions.js +3 -1
  18. package/dist/admin/hooks/useDocumentActions.js.map +1 -1
  19. package/dist/admin/hooks/useDocumentActions.mjs +4 -2
  20. package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
  21. package/dist/admin/layout.js +2 -4
  22. package/dist/admin/layout.js.map +1 -1
  23. package/dist/admin/layout.mjs +2 -4
  24. package/dist/admin/layout.mjs.map +1 -1
  25. package/dist/admin/modules/app.js +3 -1
  26. package/dist/admin/modules/app.js.map +1 -1
  27. package/dist/admin/modules/app.mjs +3 -1
  28. package/dist/admin/modules/app.mjs.map +1 -1
  29. package/dist/admin/pages/EditView/EditViewPage.js +15 -20
  30. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  31. package/dist/admin/pages/EditView/EditViewPage.mjs +15 -20
  32. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  33. package/dist/admin/pages/EditView/components/DocumentActions.js +2 -0
  34. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  35. package/dist/admin/pages/EditView/components/DocumentActions.mjs +2 -0
  36. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  37. package/dist/admin/pages/EditView/components/EditorToolbarObserver.js +74 -7
  38. package/dist/admin/pages/EditView/components/EditorToolbarObserver.js.map +1 -1
  39. package/dist/admin/pages/EditView/components/EditorToolbarObserver.mjs +74 -7
  40. package/dist/admin/pages/EditView/components/EditorToolbarObserver.mjs.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +7 -2
  42. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
  43. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +7 -2
  44. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +59 -2
  46. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs +60 -3
  48. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js +4 -1
  50. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js.map +1 -1
  51. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs +4 -1
  52. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs.map +1 -1
  53. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +4 -1
  54. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
  55. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs +4 -1
  56. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
  57. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js +2 -1
  58. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js.map +1 -1
  59. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs +2 -1
  60. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs.map +1 -1
  61. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +58 -1
  62. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  63. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +58 -2
  64. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  65. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js +25 -2
  66. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js.map +1 -1
  67. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs +5 -2
  68. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs.map +1 -1
  69. package/dist/admin/pages/EditView/components/InputRenderer.js +5 -1
  70. package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
  71. package/dist/admin/pages/EditView/components/InputRenderer.mjs +6 -2
  72. package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
  73. package/dist/admin/pages/ListView/ListViewPage.js +1 -0
  74. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  75. package/dist/admin/pages/ListView/ListViewPage.mjs +1 -0
  76. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  77. package/dist/admin/preview/components/InputPopover.js +64 -46
  78. package/dist/admin/preview/components/InputPopover.js.map +1 -1
  79. package/dist/admin/preview/components/InputPopover.mjs +66 -49
  80. package/dist/admin/preview/components/InputPopover.mjs.map +1 -1
  81. package/dist/admin/preview/hooks/usePreviewInputManager.js +23 -7
  82. package/dist/admin/preview/hooks/usePreviewInputManager.js.map +1 -1
  83. package/dist/admin/preview/hooks/usePreviewInputManager.mjs +25 -9
  84. package/dist/admin/preview/hooks/usePreviewInputManager.mjs.map +1 -1
  85. package/dist/admin/preview/pages/Preview.js +19 -0
  86. package/dist/admin/preview/pages/Preview.js.map +1 -1
  87. package/dist/admin/preview/pages/Preview.mjs +20 -1
  88. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  89. package/dist/admin/preview/utils/constants.js +9 -3
  90. package/dist/admin/preview/utils/constants.js.map +1 -1
  91. package/dist/admin/preview/utils/constants.mjs +9 -3
  92. package/dist/admin/preview/utils/constants.mjs.map +1 -1
  93. package/dist/admin/src/components/ActionsDrawer.d.ts +1 -0
  94. package/dist/admin/src/modules/app.d.ts +2 -0
  95. package/dist/admin/src/pages/EditView/components/EditorToolbarObserver.d.ts +2 -1
  96. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.d.ts +5 -1
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.d.ts +5 -0
  98. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +5 -0
  99. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.d.ts +2 -1
  100. package/dist/admin/src/pages/EditView/components/FormInputs/Relations/RelationModal.d.ts +14 -1
  101. package/dist/admin/src/preview/components/InputPopover.d.ts +2 -1
  102. package/dist/admin/src/preview/pages/Preview.d.ts +1 -0
  103. package/dist/admin/src/preview/utils/constants.d.ts +8 -1
  104. package/dist/admin/src/services/init.d.ts +1 -0
  105. package/dist/admin/src/utils/contentStructure.d.ts +59 -0
  106. package/dist/admin/utils/contentStructure.js +136 -0
  107. package/dist/admin/utils/contentStructure.js.map +1 -0
  108. package/dist/admin/utils/contentStructure.mjs +130 -0
  109. package/dist/admin/utils/contentStructure.mjs.map +1 -0
  110. package/dist/server/controllers/init.js +7 -2
  111. package/dist/server/controllers/init.js.map +1 -1
  112. package/dist/server/controllers/init.mjs +7 -2
  113. package/dist/server/controllers/init.mjs.map +1 -1
  114. package/dist/server/preview/controllers/previewScript.js +548 -22
  115. package/dist/server/services/content-structure.js +53 -0
  116. package/dist/server/services/content-structure.js.map +1 -0
  117. package/dist/server/services/content-structure.mjs +51 -0
  118. package/dist/server/services/content-structure.mjs.map +1 -0
  119. package/dist/server/services/index.js +2 -0
  120. package/dist/server/services/index.js.map +1 -1
  121. package/dist/server/services/index.mjs +2 -0
  122. package/dist/server/services/index.mjs.map +1 -1
  123. package/dist/server/src/controllers/index.d.ts +1 -1
  124. package/dist/server/src/controllers/init.d.ts +1 -1
  125. package/dist/server/src/controllers/init.d.ts.map +1 -1
  126. package/dist/server/src/index.d.ts +6 -1
  127. package/dist/server/src/index.d.ts.map +1 -1
  128. package/dist/server/src/services/content-structure.d.ts +8 -0
  129. package/dist/server/src/services/content-structure.d.ts.map +1 -0
  130. package/dist/server/src/services/index.d.ts +5 -0
  131. package/dist/server/src/services/index.d.ts.map +1 -1
  132. package/dist/server/src/utils/index.d.ts +2 -0
  133. package/dist/server/src/utils/index.d.ts.map +1 -1
  134. package/dist/server/utils/index.js.map +1 -1
  135. package/dist/server/utils/index.mjs.map +1 -1
  136. package/dist/shared/contracts/init.d.ts +2 -0
  137. package/dist/shared/contracts/init.d.ts.map +1 -1
  138. package/package.json +5 -5
@@ -37,12 +37,17 @@ const ObservedToolbarComponent = ({ index, lastVisibleIndex, setLastVisibleIndex
37
37
  */ if (isVisible) {
38
38
  setLastVisibleIndex((prev)=>Math.max(prev, index));
39
39
  }
40
- }, {
40
+ }, // Use a getter so root is read inside useElementOnScreen's useEffect (after refs are
41
+ // committed) rather than at render time (when containerRef.current is still null).
42
+ {
41
43
  threshold: 1,
42
- root: rootRef.current
44
+ get root () {
45
+ return rootRef.current;
46
+ }
43
47
  });
44
48
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
45
49
  ref: containerRef,
50
+ "data-toolbar-item": "true",
46
51
  style: {
47
52
  /**
48
53
  * Use visibility so that the element occupies the space if requires even when there's not
@@ -83,12 +88,70 @@ const ObservedToolbarComponent = ({ index, lastVisibleIndex, setLastVisibleIndex
83
88
  display: none;
84
89
  }
85
90
  `;
86
- const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost' })=>{
91
+ const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost', containerRef })=>{
87
92
  const { formatMessage } = reactIntl.useIntl();
88
- const toolbarRef = React__namespace.useRef(null);
89
93
  const [lastVisibleIndex, setLastVisibleIndex] = React__namespace.useState(observedComponents.length - 1);
90
94
  const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;
91
95
  const menuIndex = lastVisibleIndex + 1;
96
+ /**
97
+ * Measure whether toolbar items overflow the container using clientWidth/offsetWidth.
98
+ * These layout-box dimensions are unaffected by CSS transforms (including the Radix
99
+ * popover positioning transform), so the result is always correct.
100
+ *
101
+ * We run this both synchronously on mount (useLayoutEffect) and on every container
102
+ * resize (ResizeObserver) so that label changes in BlocksDropdown, which narrow the
103
+ * toolbar container, are caught and the More menu appears as needed.
104
+ */ const measureOverflow = React__namespace.useCallback(()=>{
105
+ const container = containerRef.current;
106
+ if (!container) return;
107
+ // Items are in DOM order 0..N-1 regardless of where the trigger sits.
108
+ // data-toolbar-trigger is skipped by the [data-toolbar-item] selector.
109
+ const triggerEl = container.querySelector('[data-toolbar-trigger="true"]');
110
+ const itemEls = Array.from(container.querySelectorAll('[data-toolbar-item="true"]'));
111
+ if (!triggerEl || itemEls.length === 0) return;
112
+ const containerWidth = container.clientWidth;
113
+ const triggerWidth = triggerEl.offsetWidth;
114
+ const gap = parseFloat(getComputedStyle(container).columnGap) || 0;
115
+ const itemWidths = itemEls.map((el)=>el.offsetWidth);
116
+ const totalItemsWidth = itemWidths.reduce((sum, w)=>sum + w, 0);
117
+ // Check if all items fit without the trigger
118
+ if (totalItemsWidth + Math.max(0, itemEls.length - 1) * gap <= containerWidth) {
119
+ setLastVisibleIndex(itemEls.length - 1);
120
+ return;
121
+ }
122
+ // Items overflow: find the last item that fits alongside the trigger
123
+ let cumWidth = 0;
124
+ let lastFitting = -1;
125
+ for(let i = 0; i < itemWidths.length; i++){
126
+ const widthWithItem = cumWidth + (i > 0 ? gap : 0) + itemWidths[i];
127
+ if (widthWithItem + gap + triggerWidth <= containerWidth) {
128
+ cumWidth = widthWithItem;
129
+ lastFitting = i;
130
+ } else {
131
+ break;
132
+ }
133
+ }
134
+ setLastVisibleIndex(lastFitting);
135
+ }, [
136
+ containerRef
137
+ ]);
138
+ // Synchronous initial measurement before the first paint
139
+ React__namespace.useLayoutEffect(()=>{
140
+ measureOverflow();
141
+ }, [
142
+ measureOverflow
143
+ ]);
144
+ // Re-measure whenever the container resizes (e.g. BlocksDropdown label changes width)
145
+ React__namespace.useEffect(()=>{
146
+ const container = containerRef.current;
147
+ if (!container) return;
148
+ const ro = new ResizeObserver(measureOverflow);
149
+ ro.observe(container);
150
+ return ()=>ro.disconnect();
151
+ }, [
152
+ containerRef,
153
+ measureOverflow
154
+ ]);
92
155
  const [open, setOpen] = React__namespace.useState(false);
93
156
  const isMenuOpenWithContent = open && hasHiddenItems;
94
157
  const menuTriggerRef = strapiAdmin.useElementOnScreen((isVisible)=>{
@@ -101,19 +164,23 @@ const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost
101
164
  // Maintain the menu state if it has content
102
165
  setOpen(isMenuOpenWithContent);
103
166
  }
104
- }, {
167
+ }, // Same getter pattern — root is read at effect time, not render time.
168
+ {
105
169
  threshold: 1,
106
- root: toolbarRef.current
170
+ get root () {
171
+ return containerRef.current;
172
+ }
107
173
  });
108
174
  return observedComponents.map((component, index)=>{
109
175
  return /*#__PURE__*/ jsxRuntime.jsx(ObservedToolbarComponent, {
110
176
  index: index,
111
177
  lastVisibleIndex: lastVisibleIndex,
112
178
  setLastVisibleIndex: setLastVisibleIndex,
113
- rootRef: toolbarRef,
179
+ rootRef: containerRef,
114
180
  children: component.toolbar
115
181
  }, component.key);
116
182
  }).toSpliced(menuIndex, 0, /*#__PURE__*/ jsxRuntime.jsx(MenuTriggerWrapper, {
183
+ "data-toolbar-trigger": "true",
117
184
  style: {
118
185
  visibility: hasHiddenItems ? 'visible' : 'hidden'
119
186
  },
@@ -1 +1 @@
1
- {"version":3,"file":"EditorToolbarObserver.js","sources":["../../../../../admin/src/pages/EditView/components/EditorToolbarObserver.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useElementOnScreen } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Menu } from '@strapi/design-system';\nimport { More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ObservedToolbarComponent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ObservedToolbarComponentProps {\n index: number;\n lastVisibleIndex: number;\n setLastVisibleIndex: React.Dispatch<React.SetStateAction<number>>;\n rootRef: React.RefObject<HTMLElement>;\n children: React.ReactNode;\n}\n\nconst ObservedToolbarComponent = ({\n index,\n lastVisibleIndex,\n setLastVisibleIndex,\n rootRef,\n children,\n}: ObservedToolbarComponentProps) => {\n const isVisible = index <= lastVisibleIndex;\n\n const containerRef = useElementOnScreen<HTMLDivElement>(\n (isVisible) => {\n /**\n * It's the MoreMenu's job to make an item not visible when there's not room for it.\n * But we need to react here to the element becoming visible again.\n */\n if (isVisible) {\n setLastVisibleIndex((prev) => Math.max(prev, index));\n }\n },\n { threshold: 1, root: rootRef.current }\n );\n\n return (\n <div\n ref={containerRef}\n style={{\n /**\n * Use visibility so that the element occupies the space if requires even when there's not\n * enough room for it to be visible. The empty reserved space will be clipped by the\n * overflow:hidden rule on the parent, so it doesn't affect the UI.\n * This way we can keep observing its visiblity and react to browser resize events.\n */\n visibility: isVisible ? 'visible' : 'hidden',\n }}\n >\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditorToolbarObserver\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface ObservedComponent {\n toolbar: React.ReactNode;\n menu: React.ReactNode;\n key: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * MenuTriggerWrapper\n * -----------------------------------------------------------------------------------------------*/\n/**\n * The menu trigger is rendered by the observer, after the last visible toolbar item.\n * We use a wrapper with a ::before pseudo-element to render a vertical separator that\n * always appears immediately before the \"More\" menu button, regardless of which items\n * are visible or moved into the overflow menu.\n */\nconst MenuTriggerWrapper = styled(Box)`\n display: flex;\n align-items: center;\n\n &::before {\n content: '';\n background: ${({ theme }) => theme.colors.neutral150};\n width: 1px;\n height: 2.4rem;\n margin-left: ${({ theme }) => theme.spaces[1]};\n margin-right: ${({ theme }) => theme.spaces[1]};\n\n ${({ theme }) => theme.breakpoints.medium} {\n margin-left: ${({ theme }) => theme.spaces[2]};\n margin-right: ${({ theme }) => theme.spaces[2]};\n }\n }\n\n [data-hide-toolbar-separator='true'] &::before {\n display: none;\n }\n`;\n\nexport const EditorToolbarObserver = ({\n observedComponents,\n menuTriggerVariant = 'ghost',\n}: {\n observedComponents: ObservedComponent[];\n menuTriggerVariant?: Menu.TriggerProps['variant'];\n}) => {\n const { formatMessage } = useIntl();\n const toolbarRef = React.useRef<HTMLElement>(null);\n\n const [lastVisibleIndex, setLastVisibleIndex] = React.useState<number>(\n observedComponents.length - 1\n );\n const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;\n const menuIndex = lastVisibleIndex + 1;\n\n const [open, setOpen] = React.useState(false);\n const isMenuOpenWithContent = open && hasHiddenItems;\n const menuTriggerRef = useElementOnScreen<HTMLButtonElement>(\n (isVisible) => {\n // We only react to the menu becoming invisible. When that happens, we hide the last item.\n if (!isVisible) {\n /**\n * If there's no room for any item, the index can be -1.\n * This is intentional, in that case only the more menu will be visible.\n **/\n setLastVisibleIndex((prev) => prev - 1);\n // Maintain the menu state if it has content\n setOpen(isMenuOpenWithContent);\n }\n },\n { threshold: 1, root: toolbarRef.current }\n );\n\n return observedComponents\n .map((component, index) => {\n return (\n <ObservedToolbarComponent\n key={component.key}\n index={index}\n lastVisibleIndex={lastVisibleIndex}\n setLastVisibleIndex={setLastVisibleIndex}\n rootRef={toolbarRef}\n >\n {component.toolbar}\n </ObservedToolbarComponent>\n );\n })\n .toSpliced(\n menuIndex,\n 0,\n <MenuTriggerWrapper\n key=\"more-menu-wrapper\"\n style={{ visibility: hasHiddenItems ? 'visible' : 'hidden' }}\n >\n <Menu.Root defaultOpen={false} open={isMenuOpenWithContent} onOpenChange={setOpen}>\n <Menu.Trigger\n paddingLeft={0}\n paddingRight={0}\n ref={menuTriggerRef}\n variant={menuTriggerVariant}\n label={formatMessage({ id: 'global.more', defaultMessage: 'More' })}\n tag={IconButton}\n icon={<More />}\n />\n <Menu.Content\n onCloseAutoFocus={(e) => e.preventDefault()}\n maxHeight=\"100%\"\n minWidth=\"256px\"\n popoverPlacement=\"bottom-end\"\n zIndex={2}\n >\n {observedComponents.slice(menuIndex).map((component) => (\n <React.Fragment key={component.key}>{component.menu}</React.Fragment>\n ))}\n </Menu.Content>\n </Menu.Root>\n </MenuTriggerWrapper>\n );\n};\n"],"names":["ObservedToolbarComponent","index","lastVisibleIndex","setLastVisibleIndex","rootRef","children","isVisible","containerRef","useElementOnScreen","prev","Math","max","threshold","root","current","_jsx","div","ref","style","visibility","MenuTriggerWrapper","styled","Box","theme","colors","neutral150","spaces","breakpoints","medium","EditorToolbarObserver","observedComponents","menuTriggerVariant","formatMessage","useIntl","toolbarRef","React","useRef","useState","length","hasHiddenItems","menuIndex","open","setOpen","isMenuOpenWithContent","menuTriggerRef","map","component","toolbar","key","toSpliced","_jsxs","Menu","Root","defaultOpen","onOpenChange","Trigger","paddingLeft","paddingRight","variant","label","id","defaultMessage","tag","IconButton","icon","More","Content","onCloseAutoFocus","e","preventDefault","maxHeight","minWidth","popoverPlacement","zIndex","slice","Fragment","menu"],"mappings":"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"}
1
+ {"version":3,"file":"EditorToolbarObserver.js","sources":["../../../../../admin/src/pages/EditView/components/EditorToolbarObserver.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useElementOnScreen } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Menu } from '@strapi/design-system';\nimport { More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ObservedToolbarComponent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ObservedToolbarComponentProps {\n index: number;\n lastVisibleIndex: number;\n setLastVisibleIndex: React.Dispatch<React.SetStateAction<number>>;\n rootRef: React.RefObject<HTMLElement | null>;\n children: React.ReactNode;\n}\n\nconst ObservedToolbarComponent = ({\n index,\n lastVisibleIndex,\n setLastVisibleIndex,\n rootRef,\n children,\n}: ObservedToolbarComponentProps) => {\n const isVisible = index <= lastVisibleIndex;\n\n const containerRef = useElementOnScreen<HTMLDivElement>(\n (isVisible) => {\n /**\n * It's the MoreMenu's job to make an item not visible when there's not room for it.\n * But we need to react here to the element becoming visible again.\n */\n if (isVisible) {\n setLastVisibleIndex((prev) => Math.max(prev, index));\n }\n },\n // Use a getter so root is read inside useElementOnScreen's useEffect (after refs are\n // committed) rather than at render time (when containerRef.current is still null).\n {\n threshold: 1,\n get root() {\n return rootRef.current;\n },\n }\n );\n\n return (\n <div\n ref={containerRef}\n data-toolbar-item=\"true\"\n style={{\n /**\n * Use visibility so that the element occupies the space if requires even when there's not\n * enough room for it to be visible. The empty reserved space will be clipped by the\n * overflow:hidden rule on the parent, so it doesn't affect the UI.\n * This way we can keep observing its visiblity and react to browser resize events.\n */\n visibility: isVisible ? 'visible' : 'hidden',\n }}\n >\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditorToolbarObserver\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface ObservedComponent {\n toolbar: React.ReactNode;\n menu: React.ReactNode;\n key: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * MenuTriggerWrapper\n * -----------------------------------------------------------------------------------------------*/\n/**\n * The menu trigger is rendered by the observer, after the last visible toolbar item.\n * We use a wrapper with a ::before pseudo-element to render a vertical separator that\n * always appears immediately before the \"More\" menu button, regardless of which items\n * are visible or moved into the overflow menu.\n */\nconst MenuTriggerWrapper = styled(Box)`\n display: flex;\n align-items: center;\n\n &::before {\n content: '';\n background: ${({ theme }) => theme.colors.neutral150};\n width: 1px;\n height: 2.4rem;\n margin-left: ${({ theme }) => theme.spaces[1]};\n margin-right: ${({ theme }) => theme.spaces[1]};\n\n ${({ theme }) => theme.breakpoints.medium} {\n margin-left: ${({ theme }) => theme.spaces[2]};\n margin-right: ${({ theme }) => theme.spaces[2]};\n }\n }\n\n [data-hide-toolbar-separator='true'] &::before {\n display: none;\n }\n`;\n\nexport const EditorToolbarObserver = ({\n observedComponents,\n menuTriggerVariant = 'ghost',\n containerRef,\n}: {\n observedComponents: ObservedComponent[];\n menuTriggerVariant?: Menu.TriggerProps['variant'];\n containerRef: React.RefObject<HTMLElement | null>;\n}) => {\n const { formatMessage } = useIntl();\n\n const [lastVisibleIndex, setLastVisibleIndex] = React.useState<number>(\n observedComponents.length - 1\n );\n const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;\n const menuIndex = lastVisibleIndex + 1;\n\n /**\n * Measure whether toolbar items overflow the container using clientWidth/offsetWidth.\n * These layout-box dimensions are unaffected by CSS transforms (including the Radix\n * popover positioning transform), so the result is always correct.\n *\n * We run this both synchronously on mount (useLayoutEffect) and on every container\n * resize (ResizeObserver) so that label changes in BlocksDropdown, which narrow the\n * toolbar container, are caught and the More menu appears as needed.\n */\n const measureOverflow = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Items are in DOM order 0..N-1 regardless of where the trigger sits.\n // data-toolbar-trigger is skipped by the [data-toolbar-item] selector.\n const triggerEl = container.querySelector(\n '[data-toolbar-trigger=\"true\"]'\n ) as HTMLElement | null;\n const itemEls = Array.from(\n container.querySelectorAll('[data-toolbar-item=\"true\"]')\n ) as HTMLElement[];\n\n if (!triggerEl || itemEls.length === 0) return;\n\n const containerWidth = container.clientWidth;\n const triggerWidth = triggerEl.offsetWidth;\n const gap = parseFloat(getComputedStyle(container).columnGap) || 0;\n\n const itemWidths = itemEls.map((el) => el.offsetWidth);\n const totalItemsWidth = itemWidths.reduce((sum, w) => sum + w, 0);\n\n // Check if all items fit without the trigger\n if (totalItemsWidth + Math.max(0, itemEls.length - 1) * gap <= containerWidth) {\n setLastVisibleIndex(itemEls.length - 1);\n return;\n }\n\n // Items overflow: find the last item that fits alongside the trigger\n let cumWidth = 0;\n let lastFitting = -1;\n for (let i = 0; i < itemWidths.length; i++) {\n const widthWithItem = cumWidth + (i > 0 ? gap : 0) + itemWidths[i];\n if (widthWithItem + gap + triggerWidth <= containerWidth) {\n cumWidth = widthWithItem;\n lastFitting = i;\n } else {\n break;\n }\n }\n\n setLastVisibleIndex(lastFitting);\n }, [containerRef]);\n\n // Synchronous initial measurement before the first paint\n React.useLayoutEffect(() => {\n measureOverflow();\n }, [measureOverflow]);\n\n // Re-measure whenever the container resizes (e.g. BlocksDropdown label changes width)\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const ro = new ResizeObserver(measureOverflow);\n ro.observe(container);\n return () => ro.disconnect();\n }, [containerRef, measureOverflow]);\n\n const [open, setOpen] = React.useState(false);\n const isMenuOpenWithContent = open && hasHiddenItems;\n const menuTriggerRef = useElementOnScreen<HTMLButtonElement>(\n (isVisible) => {\n // We only react to the menu becoming invisible. When that happens, we hide the last item.\n if (!isVisible) {\n /**\n * If there's no room for any item, the index can be -1.\n * This is intentional, in that case only the more menu will be visible.\n **/\n setLastVisibleIndex((prev) => prev - 1);\n // Maintain the menu state if it has content\n setOpen(isMenuOpenWithContent);\n }\n },\n // Same getter pattern — root is read at effect time, not render time.\n {\n threshold: 1,\n get root() {\n return containerRef.current;\n },\n }\n );\n\n return observedComponents\n .map((component, index) => {\n return (\n <ObservedToolbarComponent\n key={component.key}\n index={index}\n lastVisibleIndex={lastVisibleIndex}\n setLastVisibleIndex={setLastVisibleIndex}\n rootRef={containerRef}\n >\n {component.toolbar}\n </ObservedToolbarComponent>\n );\n })\n .toSpliced(\n menuIndex,\n 0,\n <MenuTriggerWrapper\n key=\"more-menu-wrapper\"\n data-toolbar-trigger=\"true\"\n style={{ visibility: hasHiddenItems ? 'visible' : 'hidden' }}\n >\n <Menu.Root defaultOpen={false} open={isMenuOpenWithContent} onOpenChange={setOpen}>\n <Menu.Trigger\n paddingLeft={0}\n paddingRight={0}\n ref={menuTriggerRef}\n variant={menuTriggerVariant}\n label={formatMessage({ id: 'global.more', defaultMessage: 'More' })}\n tag={IconButton}\n icon={<More />}\n />\n <Menu.Content\n onCloseAutoFocus={(e) => e.preventDefault()}\n maxHeight=\"100%\"\n minWidth=\"256px\"\n popoverPlacement=\"bottom-end\"\n zIndex={2}\n >\n {observedComponents.slice(menuIndex).map((component) => (\n <React.Fragment key={component.key}>{component.menu}</React.Fragment>\n ))}\n </Menu.Content>\n </Menu.Root>\n </MenuTriggerWrapper>\n );\n};\n"],"names":["ObservedToolbarComponent","index","lastVisibleIndex","setLastVisibleIndex","rootRef","children","isVisible","containerRef","useElementOnScreen","prev","Math","max","threshold","root","current","_jsx","div","ref","data-toolbar-item","style","visibility","MenuTriggerWrapper","styled","Box","theme","colors","neutral150","spaces","breakpoints","medium","EditorToolbarObserver","observedComponents","menuTriggerVariant","formatMessage","useIntl","React","useState","length","hasHiddenItems","menuIndex","measureOverflow","useCallback","container","triggerEl","querySelector","itemEls","Array","from","querySelectorAll","containerWidth","clientWidth","triggerWidth","offsetWidth","gap","parseFloat","getComputedStyle","columnGap","itemWidths","map","el","totalItemsWidth","reduce","sum","w","cumWidth","lastFitting","i","widthWithItem","useLayoutEffect","useEffect","ro","ResizeObserver","observe","disconnect","open","setOpen","isMenuOpenWithContent","menuTriggerRef","component","toolbar","key","toSpliced","data-toolbar-trigger","_jsxs","Menu","Root","defaultOpen","onOpenChange","Trigger","paddingLeft","paddingRight","variant","label","id","defaultMessage","tag","IconButton","icon","More","Content","onCloseAutoFocus","e","preventDefault","maxHeight","minWidth","popoverPlacement","zIndex","slice","Fragment","menu"],"mappings":"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"}
@@ -15,12 +15,17 @@ const ObservedToolbarComponent = ({ index, lastVisibleIndex, setLastVisibleIndex
15
15
  */ if (isVisible) {
16
16
  setLastVisibleIndex((prev)=>Math.max(prev, index));
17
17
  }
18
- }, {
18
+ }, // Use a getter so root is read inside useElementOnScreen's useEffect (after refs are
19
+ // committed) rather than at render time (when containerRef.current is still null).
20
+ {
19
21
  threshold: 1,
20
- root: rootRef.current
22
+ get root () {
23
+ return rootRef.current;
24
+ }
21
25
  });
22
26
  return /*#__PURE__*/ jsx("div", {
23
27
  ref: containerRef,
28
+ "data-toolbar-item": "true",
24
29
  style: {
25
30
  /**
26
31
  * Use visibility so that the element occupies the space if requires even when there's not
@@ -61,12 +66,70 @@ const ObservedToolbarComponent = ({ index, lastVisibleIndex, setLastVisibleIndex
61
66
  display: none;
62
67
  }
63
68
  `;
64
- const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost' })=>{
69
+ const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost', containerRef })=>{
65
70
  const { formatMessage } = useIntl();
66
- const toolbarRef = React.useRef(null);
67
71
  const [lastVisibleIndex, setLastVisibleIndex] = React.useState(observedComponents.length - 1);
68
72
  const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;
69
73
  const menuIndex = lastVisibleIndex + 1;
74
+ /**
75
+ * Measure whether toolbar items overflow the container using clientWidth/offsetWidth.
76
+ * These layout-box dimensions are unaffected by CSS transforms (including the Radix
77
+ * popover positioning transform), so the result is always correct.
78
+ *
79
+ * We run this both synchronously on mount (useLayoutEffect) and on every container
80
+ * resize (ResizeObserver) so that label changes in BlocksDropdown, which narrow the
81
+ * toolbar container, are caught and the More menu appears as needed.
82
+ */ const measureOverflow = React.useCallback(()=>{
83
+ const container = containerRef.current;
84
+ if (!container) return;
85
+ // Items are in DOM order 0..N-1 regardless of where the trigger sits.
86
+ // data-toolbar-trigger is skipped by the [data-toolbar-item] selector.
87
+ const triggerEl = container.querySelector('[data-toolbar-trigger="true"]');
88
+ const itemEls = Array.from(container.querySelectorAll('[data-toolbar-item="true"]'));
89
+ if (!triggerEl || itemEls.length === 0) return;
90
+ const containerWidth = container.clientWidth;
91
+ const triggerWidth = triggerEl.offsetWidth;
92
+ const gap = parseFloat(getComputedStyle(container).columnGap) || 0;
93
+ const itemWidths = itemEls.map((el)=>el.offsetWidth);
94
+ const totalItemsWidth = itemWidths.reduce((sum, w)=>sum + w, 0);
95
+ // Check if all items fit without the trigger
96
+ if (totalItemsWidth + Math.max(0, itemEls.length - 1) * gap <= containerWidth) {
97
+ setLastVisibleIndex(itemEls.length - 1);
98
+ return;
99
+ }
100
+ // Items overflow: find the last item that fits alongside the trigger
101
+ let cumWidth = 0;
102
+ let lastFitting = -1;
103
+ for(let i = 0; i < itemWidths.length; i++){
104
+ const widthWithItem = cumWidth + (i > 0 ? gap : 0) + itemWidths[i];
105
+ if (widthWithItem + gap + triggerWidth <= containerWidth) {
106
+ cumWidth = widthWithItem;
107
+ lastFitting = i;
108
+ } else {
109
+ break;
110
+ }
111
+ }
112
+ setLastVisibleIndex(lastFitting);
113
+ }, [
114
+ containerRef
115
+ ]);
116
+ // Synchronous initial measurement before the first paint
117
+ React.useLayoutEffect(()=>{
118
+ measureOverflow();
119
+ }, [
120
+ measureOverflow
121
+ ]);
122
+ // Re-measure whenever the container resizes (e.g. BlocksDropdown label changes width)
123
+ React.useEffect(()=>{
124
+ const container = containerRef.current;
125
+ if (!container) return;
126
+ const ro = new ResizeObserver(measureOverflow);
127
+ ro.observe(container);
128
+ return ()=>ro.disconnect();
129
+ }, [
130
+ containerRef,
131
+ measureOverflow
132
+ ]);
70
133
  const [open, setOpen] = React.useState(false);
71
134
  const isMenuOpenWithContent = open && hasHiddenItems;
72
135
  const menuTriggerRef = useElementOnScreen((isVisible)=>{
@@ -79,19 +142,23 @@ const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost
79
142
  // Maintain the menu state if it has content
80
143
  setOpen(isMenuOpenWithContent);
81
144
  }
82
- }, {
145
+ }, // Same getter pattern — root is read at effect time, not render time.
146
+ {
83
147
  threshold: 1,
84
- root: toolbarRef.current
148
+ get root () {
149
+ return containerRef.current;
150
+ }
85
151
  });
86
152
  return observedComponents.map((component, index)=>{
87
153
  return /*#__PURE__*/ jsx(ObservedToolbarComponent, {
88
154
  index: index,
89
155
  lastVisibleIndex: lastVisibleIndex,
90
156
  setLastVisibleIndex: setLastVisibleIndex,
91
- rootRef: toolbarRef,
157
+ rootRef: containerRef,
92
158
  children: component.toolbar
93
159
  }, component.key);
94
160
  }).toSpliced(menuIndex, 0, /*#__PURE__*/ jsx(MenuTriggerWrapper, {
161
+ "data-toolbar-trigger": "true",
95
162
  style: {
96
163
  visibility: hasHiddenItems ? 'visible' : 'hidden'
97
164
  },
@@ -1 +1 @@
1
- {"version":3,"file":"EditorToolbarObserver.mjs","sources":["../../../../../admin/src/pages/EditView/components/EditorToolbarObserver.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useElementOnScreen } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Menu } from '@strapi/design-system';\nimport { More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ObservedToolbarComponent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ObservedToolbarComponentProps {\n index: number;\n lastVisibleIndex: number;\n setLastVisibleIndex: React.Dispatch<React.SetStateAction<number>>;\n rootRef: React.RefObject<HTMLElement>;\n children: React.ReactNode;\n}\n\nconst ObservedToolbarComponent = ({\n index,\n lastVisibleIndex,\n setLastVisibleIndex,\n rootRef,\n children,\n}: ObservedToolbarComponentProps) => {\n const isVisible = index <= lastVisibleIndex;\n\n const containerRef = useElementOnScreen<HTMLDivElement>(\n (isVisible) => {\n /**\n * It's the MoreMenu's job to make an item not visible when there's not room for it.\n * But we need to react here to the element becoming visible again.\n */\n if (isVisible) {\n setLastVisibleIndex((prev) => Math.max(prev, index));\n }\n },\n { threshold: 1, root: rootRef.current }\n );\n\n return (\n <div\n ref={containerRef}\n style={{\n /**\n * Use visibility so that the element occupies the space if requires even when there's not\n * enough room for it to be visible. The empty reserved space will be clipped by the\n * overflow:hidden rule on the parent, so it doesn't affect the UI.\n * This way we can keep observing its visiblity and react to browser resize events.\n */\n visibility: isVisible ? 'visible' : 'hidden',\n }}\n >\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditorToolbarObserver\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface ObservedComponent {\n toolbar: React.ReactNode;\n menu: React.ReactNode;\n key: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * MenuTriggerWrapper\n * -----------------------------------------------------------------------------------------------*/\n/**\n * The menu trigger is rendered by the observer, after the last visible toolbar item.\n * We use a wrapper with a ::before pseudo-element to render a vertical separator that\n * always appears immediately before the \"More\" menu button, regardless of which items\n * are visible or moved into the overflow menu.\n */\nconst MenuTriggerWrapper = styled(Box)`\n display: flex;\n align-items: center;\n\n &::before {\n content: '';\n background: ${({ theme }) => theme.colors.neutral150};\n width: 1px;\n height: 2.4rem;\n margin-left: ${({ theme }) => theme.spaces[1]};\n margin-right: ${({ theme }) => theme.spaces[1]};\n\n ${({ theme }) => theme.breakpoints.medium} {\n margin-left: ${({ theme }) => theme.spaces[2]};\n margin-right: ${({ theme }) => theme.spaces[2]};\n }\n }\n\n [data-hide-toolbar-separator='true'] &::before {\n display: none;\n }\n`;\n\nexport const EditorToolbarObserver = ({\n observedComponents,\n menuTriggerVariant = 'ghost',\n}: {\n observedComponents: ObservedComponent[];\n menuTriggerVariant?: Menu.TriggerProps['variant'];\n}) => {\n const { formatMessage } = useIntl();\n const toolbarRef = React.useRef<HTMLElement>(null);\n\n const [lastVisibleIndex, setLastVisibleIndex] = React.useState<number>(\n observedComponents.length - 1\n );\n const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;\n const menuIndex = lastVisibleIndex + 1;\n\n const [open, setOpen] = React.useState(false);\n const isMenuOpenWithContent = open && hasHiddenItems;\n const menuTriggerRef = useElementOnScreen<HTMLButtonElement>(\n (isVisible) => {\n // We only react to the menu becoming invisible. When that happens, we hide the last item.\n if (!isVisible) {\n /**\n * If there's no room for any item, the index can be -1.\n * This is intentional, in that case only the more menu will be visible.\n **/\n setLastVisibleIndex((prev) => prev - 1);\n // Maintain the menu state if it has content\n setOpen(isMenuOpenWithContent);\n }\n },\n { threshold: 1, root: toolbarRef.current }\n );\n\n return observedComponents\n .map((component, index) => {\n return (\n <ObservedToolbarComponent\n key={component.key}\n index={index}\n lastVisibleIndex={lastVisibleIndex}\n setLastVisibleIndex={setLastVisibleIndex}\n rootRef={toolbarRef}\n >\n {component.toolbar}\n </ObservedToolbarComponent>\n );\n })\n .toSpliced(\n menuIndex,\n 0,\n <MenuTriggerWrapper\n key=\"more-menu-wrapper\"\n style={{ visibility: hasHiddenItems ? 'visible' : 'hidden' }}\n >\n <Menu.Root defaultOpen={false} open={isMenuOpenWithContent} onOpenChange={setOpen}>\n <Menu.Trigger\n paddingLeft={0}\n paddingRight={0}\n ref={menuTriggerRef}\n variant={menuTriggerVariant}\n label={formatMessage({ id: 'global.more', defaultMessage: 'More' })}\n tag={IconButton}\n icon={<More />}\n />\n <Menu.Content\n onCloseAutoFocus={(e) => e.preventDefault()}\n maxHeight=\"100%\"\n minWidth=\"256px\"\n popoverPlacement=\"bottom-end\"\n zIndex={2}\n >\n {observedComponents.slice(menuIndex).map((component) => (\n <React.Fragment key={component.key}>{component.menu}</React.Fragment>\n ))}\n </Menu.Content>\n </Menu.Root>\n </MenuTriggerWrapper>\n );\n};\n"],"names":["ObservedToolbarComponent","index","lastVisibleIndex","setLastVisibleIndex","rootRef","children","isVisible","containerRef","useElementOnScreen","prev","Math","max","threshold","root","current","_jsx","div","ref","style","visibility","MenuTriggerWrapper","styled","Box","theme","colors","neutral150","spaces","breakpoints","medium","EditorToolbarObserver","observedComponents","menuTriggerVariant","formatMessage","useIntl","toolbarRef","React","useRef","useState","length","hasHiddenItems","menuIndex","open","setOpen","isMenuOpenWithContent","menuTriggerRef","map","component","toolbar","key","toSpliced","_jsxs","Menu","Root","defaultOpen","onOpenChange","Trigger","paddingLeft","paddingRight","variant","label","id","defaultMessage","tag","IconButton","icon","More","Content","onCloseAutoFocus","e","preventDefault","maxHeight","minWidth","popoverPlacement","zIndex","slice","Fragment","menu"],"mappings":"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"}
1
+ {"version":3,"file":"EditorToolbarObserver.mjs","sources":["../../../../../admin/src/pages/EditView/components/EditorToolbarObserver.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useElementOnScreen } from '@strapi/admin/strapi-admin';\nimport { Box, IconButton, Menu } from '@strapi/design-system';\nimport { More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ObservedToolbarComponent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ObservedToolbarComponentProps {\n index: number;\n lastVisibleIndex: number;\n setLastVisibleIndex: React.Dispatch<React.SetStateAction<number>>;\n rootRef: React.RefObject<HTMLElement | null>;\n children: React.ReactNode;\n}\n\nconst ObservedToolbarComponent = ({\n index,\n lastVisibleIndex,\n setLastVisibleIndex,\n rootRef,\n children,\n}: ObservedToolbarComponentProps) => {\n const isVisible = index <= lastVisibleIndex;\n\n const containerRef = useElementOnScreen<HTMLDivElement>(\n (isVisible) => {\n /**\n * It's the MoreMenu's job to make an item not visible when there's not room for it.\n * But we need to react here to the element becoming visible again.\n */\n if (isVisible) {\n setLastVisibleIndex((prev) => Math.max(prev, index));\n }\n },\n // Use a getter so root is read inside useElementOnScreen's useEffect (after refs are\n // committed) rather than at render time (when containerRef.current is still null).\n {\n threshold: 1,\n get root() {\n return rootRef.current;\n },\n }\n );\n\n return (\n <div\n ref={containerRef}\n data-toolbar-item=\"true\"\n style={{\n /**\n * Use visibility so that the element occupies the space if requires even when there's not\n * enough room for it to be visible. The empty reserved space will be clipped by the\n * overflow:hidden rule on the parent, so it doesn't affect the UI.\n * This way we can keep observing its visiblity and react to browser resize events.\n */\n visibility: isVisible ? 'visible' : 'hidden',\n }}\n >\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditorToolbarObserver\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface ObservedComponent {\n toolbar: React.ReactNode;\n menu: React.ReactNode;\n key: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * MenuTriggerWrapper\n * -----------------------------------------------------------------------------------------------*/\n/**\n * The menu trigger is rendered by the observer, after the last visible toolbar item.\n * We use a wrapper with a ::before pseudo-element to render a vertical separator that\n * always appears immediately before the \"More\" menu button, regardless of which items\n * are visible or moved into the overflow menu.\n */\nconst MenuTriggerWrapper = styled(Box)`\n display: flex;\n align-items: center;\n\n &::before {\n content: '';\n background: ${({ theme }) => theme.colors.neutral150};\n width: 1px;\n height: 2.4rem;\n margin-left: ${({ theme }) => theme.spaces[1]};\n margin-right: ${({ theme }) => theme.spaces[1]};\n\n ${({ theme }) => theme.breakpoints.medium} {\n margin-left: ${({ theme }) => theme.spaces[2]};\n margin-right: ${({ theme }) => theme.spaces[2]};\n }\n }\n\n [data-hide-toolbar-separator='true'] &::before {\n display: none;\n }\n`;\n\nexport const EditorToolbarObserver = ({\n observedComponents,\n menuTriggerVariant = 'ghost',\n containerRef,\n}: {\n observedComponents: ObservedComponent[];\n menuTriggerVariant?: Menu.TriggerProps['variant'];\n containerRef: React.RefObject<HTMLElement | null>;\n}) => {\n const { formatMessage } = useIntl();\n\n const [lastVisibleIndex, setLastVisibleIndex] = React.useState<number>(\n observedComponents.length - 1\n );\n const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;\n const menuIndex = lastVisibleIndex + 1;\n\n /**\n * Measure whether toolbar items overflow the container using clientWidth/offsetWidth.\n * These layout-box dimensions are unaffected by CSS transforms (including the Radix\n * popover positioning transform), so the result is always correct.\n *\n * We run this both synchronously on mount (useLayoutEffect) and on every container\n * resize (ResizeObserver) so that label changes in BlocksDropdown, which narrow the\n * toolbar container, are caught and the More menu appears as needed.\n */\n const measureOverflow = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Items are in DOM order 0..N-1 regardless of where the trigger sits.\n // data-toolbar-trigger is skipped by the [data-toolbar-item] selector.\n const triggerEl = container.querySelector(\n '[data-toolbar-trigger=\"true\"]'\n ) as HTMLElement | null;\n const itemEls = Array.from(\n container.querySelectorAll('[data-toolbar-item=\"true\"]')\n ) as HTMLElement[];\n\n if (!triggerEl || itemEls.length === 0) return;\n\n const containerWidth = container.clientWidth;\n const triggerWidth = triggerEl.offsetWidth;\n const gap = parseFloat(getComputedStyle(container).columnGap) || 0;\n\n const itemWidths = itemEls.map((el) => el.offsetWidth);\n const totalItemsWidth = itemWidths.reduce((sum, w) => sum + w, 0);\n\n // Check if all items fit without the trigger\n if (totalItemsWidth + Math.max(0, itemEls.length - 1) * gap <= containerWidth) {\n setLastVisibleIndex(itemEls.length - 1);\n return;\n }\n\n // Items overflow: find the last item that fits alongside the trigger\n let cumWidth = 0;\n let lastFitting = -1;\n for (let i = 0; i < itemWidths.length; i++) {\n const widthWithItem = cumWidth + (i > 0 ? gap : 0) + itemWidths[i];\n if (widthWithItem + gap + triggerWidth <= containerWidth) {\n cumWidth = widthWithItem;\n lastFitting = i;\n } else {\n break;\n }\n }\n\n setLastVisibleIndex(lastFitting);\n }, [containerRef]);\n\n // Synchronous initial measurement before the first paint\n React.useLayoutEffect(() => {\n measureOverflow();\n }, [measureOverflow]);\n\n // Re-measure whenever the container resizes (e.g. BlocksDropdown label changes width)\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const ro = new ResizeObserver(measureOverflow);\n ro.observe(container);\n return () => ro.disconnect();\n }, [containerRef, measureOverflow]);\n\n const [open, setOpen] = React.useState(false);\n const isMenuOpenWithContent = open && hasHiddenItems;\n const menuTriggerRef = useElementOnScreen<HTMLButtonElement>(\n (isVisible) => {\n // We only react to the menu becoming invisible. When that happens, we hide the last item.\n if (!isVisible) {\n /**\n * If there's no room for any item, the index can be -1.\n * This is intentional, in that case only the more menu will be visible.\n **/\n setLastVisibleIndex((prev) => prev - 1);\n // Maintain the menu state if it has content\n setOpen(isMenuOpenWithContent);\n }\n },\n // Same getter pattern — root is read at effect time, not render time.\n {\n threshold: 1,\n get root() {\n return containerRef.current;\n },\n }\n );\n\n return observedComponents\n .map((component, index) => {\n return (\n <ObservedToolbarComponent\n key={component.key}\n index={index}\n lastVisibleIndex={lastVisibleIndex}\n setLastVisibleIndex={setLastVisibleIndex}\n rootRef={containerRef}\n >\n {component.toolbar}\n </ObservedToolbarComponent>\n );\n })\n .toSpliced(\n menuIndex,\n 0,\n <MenuTriggerWrapper\n key=\"more-menu-wrapper\"\n data-toolbar-trigger=\"true\"\n style={{ visibility: hasHiddenItems ? 'visible' : 'hidden' }}\n >\n <Menu.Root defaultOpen={false} open={isMenuOpenWithContent} onOpenChange={setOpen}>\n <Menu.Trigger\n paddingLeft={0}\n paddingRight={0}\n ref={menuTriggerRef}\n variant={menuTriggerVariant}\n label={formatMessage({ id: 'global.more', defaultMessage: 'More' })}\n tag={IconButton}\n icon={<More />}\n />\n <Menu.Content\n onCloseAutoFocus={(e) => e.preventDefault()}\n maxHeight=\"100%\"\n minWidth=\"256px\"\n popoverPlacement=\"bottom-end\"\n zIndex={2}\n >\n {observedComponents.slice(menuIndex).map((component) => (\n <React.Fragment key={component.key}>{component.menu}</React.Fragment>\n ))}\n </Menu.Content>\n </Menu.Root>\n </MenuTriggerWrapper>\n );\n};\n"],"names":["ObservedToolbarComponent","index","lastVisibleIndex","setLastVisibleIndex","rootRef","children","isVisible","containerRef","useElementOnScreen","prev","Math","max","threshold","root","current","_jsx","div","ref","data-toolbar-item","style","visibility","MenuTriggerWrapper","styled","Box","theme","colors","neutral150","spaces","breakpoints","medium","EditorToolbarObserver","observedComponents","menuTriggerVariant","formatMessage","useIntl","React","useState","length","hasHiddenItems","menuIndex","measureOverflow","useCallback","container","triggerEl","querySelector","itemEls","Array","from","querySelectorAll","containerWidth","clientWidth","triggerWidth","offsetWidth","gap","parseFloat","getComputedStyle","columnGap","itemWidths","map","el","totalItemsWidth","reduce","sum","w","cumWidth","lastFitting","i","widthWithItem","useLayoutEffect","useEffect","ro","ResizeObserver","observe","disconnect","open","setOpen","isMenuOpenWithContent","menuTriggerRef","component","toolbar","key","toSpliced","data-toolbar-trigger","_jsxs","Menu","Root","defaultOpen","onOpenChange","Trigger","paddingLeft","paddingRight","variant","label","id","defaultMessage","tag","IconButton","icon","More","Content","onCloseAutoFocus","e","preventDefault","maxHeight","minWidth","popoverPlacement","zIndex","slice","Fragment","menu"],"mappings":"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"}
@@ -311,7 +311,7 @@ const baseRenderElement = ({ props, blocks, editor, dragDirection, setDragDirect
311
311
  });
312
312
  };
313
313
  const dragNoop = ()=>true;
314
- const BlocksContent = ({ placeholder, ariaLabelId })=>{
314
+ const BlocksContent = ({ placeholder, ariaLabelId, autoFocus, onFocus, onBlur })=>{
315
315
  const { editor, disabled, blocks, modifiers, setLiveText, isExpandedMode, flushPendingFormSync } = BlocksEditor.useBlocksEditorContext('BlocksContent');
316
316
  const isMobile = strapiAdmin.useIsMobile();
317
317
  const blocksRef = React__namespace.useRef(null);
@@ -541,7 +541,12 @@ const BlocksContent = ({ placeholder, ariaLabelId })=>{
541
541
  renderLeaf: renderLeaf,
542
542
  onKeyDown: handleKeyDown,
543
543
  scrollSelectionIntoView: handleScrollSelectionIntoView,
544
- onBlur: flushPendingFormSync,
544
+ autoFocus: autoFocus,
545
+ onFocus: onFocus,
546
+ onBlur: (event)=>{
547
+ flushPendingFormSync();
548
+ onBlur?.(event);
549
+ },
545
550
  // As we have our own handler to drag and drop the elements returing true will skip slate's own event handler
546
551
  onDrop: dragNoop,
547
552
  onDragStart: dragNoop
@@ -1 +1 @@
1
- {"version":3,"file":"BlocksContent.js","sources":["../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIsMobile } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n BoxComponent,\n Flex,\n FlexComponent,\n IconButton,\n IconButtonComponent,\n useComposedRefs,\n} from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { Editor, Range, Transforms } from 'slate';\nimport { ReactEditor, type RenderElementProps, type RenderLeafProps, Editable } from 'slate-react';\nimport { styled, CSSProperties, css } from 'styled-components';\n\nimport { ItemTypes } from '../../../../../constants/dragAndDrop';\nimport { useDragAndDrop, DIRECTIONS } from '../../../../../hooks/useDragAndDrop';\nimport { getTranslation } from '../../../../../utils/translations';\n\nimport { decorateCode } from './Blocks/Code';\nimport { type BlocksStore, useBlocksEditorContext } from './BlocksEditor';\nimport { useConversionModal } from './BlocksToolbar';\nimport { type ModifiersStore } from './Modifiers';\nimport { getEntries } from './utils/types';\n\nconst StyledEditable = styled(Editable)<{ $isExpandedMode: boolean }>`\n // The outline style is set on the wrapper with :focus-within\n outline: none;\n display: flex;\n flex-direction: column;\n gap: ${({ theme }) => theme.spaces[3]};\n height: 100%;\n // For fullscreen align input in the center with fixed width\n width: ${(props) => (props.$isExpandedMode ? '512px' : '100%')};\n margin: auto;\n font-size: 1.6rem;\n\n ${({ theme }) => theme.breakpoints.medium} {\n font-size: 1.4rem;\n }\n > *:last-child {\n padding-bottom: ${({ theme }) => theme.spaces[3]};\n }\n`;\n\nconst Wrapper = styled<BoxComponent>(Box)<{ $isOverDropTarget: boolean }>`\n position: ${({ $isOverDropTarget }) => $isOverDropTarget && 'relative'};\n`;\n\ntype DragDirection = (typeof DIRECTIONS)[keyof typeof DIRECTIONS];\n\nconst DropPlaceholder = styled<BoxComponent>(Box)<{\n dragDirection: DragDirection | null;\n placeholderMargin: 1 | 2;\n}>`\n position: absolute;\n right: 0;\n\n // Show drop placeholder 8px above or below the drop target\n ${({ dragDirection, theme, placeholderMargin }) => css`\n top: ${dragDirection === DIRECTIONS.UPWARD && `-${theme.spaces[placeholderMargin]}`};\n bottom: ${dragDirection === DIRECTIONS.DOWNWARD && `-${theme.spaces[placeholderMargin]}`};\n `}\n`;\n\nconst DragItem = styled<FlexComponent>(Flex)<{ $dragVisibility: CSSProperties['visibility'] }>`\n // Style each block rendered using renderElement()\n & > [data-slate-node='element'] {\n width: 100%;\n opacity: inherit;\n }\n\n // Set the visibility of drag button\n [role='button'] {\n visibility: ${(props) => props.$dragVisibility};\n opacity: inherit;\n }\n &[aria-disabled='true'] {\n user-drag: none;\n }\n`;\n\nconst DragIconButton = styled<IconButtonComponent<'div'>>(IconButton)<{\n $dragHandleTopMargin?: CSSProperties['marginTop'];\n}>`\n user-select: none;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n padding-left: ${({ theme }) => theme.spaces[0]};\n padding-right: ${({ theme }) => theme.spaces[0]};\n padding-top: ${({ theme }) => theme.spaces[1]};\n padding-bottom: ${({ theme }) => theme.spaces[1]};\n visibility: hidden;\n cursor: grab;\n opacity: inherit;\n margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};\n\n &:hover {\n background: ${({ theme }) => theme.colors.neutral100};\n }\n &:active {\n cursor: grabbing;\n background: ${({ theme }) => theme.colors.neutral150};\n }\n &[aria-disabled='true'] {\n visibility: hidden;\n }\n svg {\n min-width: ${({ theme }) => theme.spaces[3]};\n\n path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n }\n`;\n\ntype Direction = {\n setDragDirection: (direction: DragDirection) => void;\n dragDirection: DragDirection | null;\n};\n\ntype DragAndDropElementProps = Direction & {\n children: RenderElementProps['children'];\n index: Array<number>;\n dragHandleTopMargin?: CSSProperties['marginTop'];\n};\n\nconst DragAndDropElement = ({\n children,\n index,\n setDragDirection,\n dragDirection,\n dragHandleTopMargin,\n}: DragAndDropElementProps) => {\n const { editor, disabled, name, setLiveText } = useBlocksEditorContext('DragAndDropElement');\n const { formatMessage } = useIntl();\n const [dragVisibility, setDragVisibility] = React.useState<CSSProperties['visibility']>('hidden');\n const isDragAndDropEnabled = !disabled;\n\n const handleMoveBlock = React.useCallback(\n (newIndex: Array<number>, currentIndex: Array<number>) => {\n Transforms.moveNodes(editor, {\n at: currentIndex,\n to: newIndex,\n });\n\n // Add 1 to the index for the live text message\n const currentIndexPosition = [currentIndex[0] + 1, ...currentIndex.slice(1)];\n const newIndexPosition = [newIndex[0] + 1, ...newIndex.slice(1)];\n\n setLiveText(\n formatMessage(\n {\n id: getTranslation('components.Blocks.dnd.reorder'),\n defaultMessage: '{item}, moved. New position in the editor: {position}.',\n },\n {\n item: `${name}.${currentIndexPosition.join(',')}`,\n position: `${newIndexPosition.join(',')} of ${editor.children.length}`,\n }\n )\n );\n },\n [editor, formatMessage, name, setLiveText]\n );\n\n const [{ handlerId, isDragging, isOverDropTarget, direction }, blockRef, dropRef, dragRef] =\n useDragAndDrop(isDragAndDropEnabled, {\n type: `${ItemTypes.BLOCKS}_${name}`,\n index,\n item: {\n index,\n displayedValue: children,\n },\n onDropItem(currentIndex, newIndex) {\n if (newIndex) handleMoveBlock(newIndex, currentIndex);\n },\n });\n\n const composedBoxRefs = useComposedRefs(blockRef, dropRef);\n\n // Set Drag direction before loosing state while dragging\n React.useEffect(() => {\n if (direction) {\n setDragDirection(direction);\n }\n }, [direction, setDragDirection]);\n\n // On selection change hide drag handle\n React.useEffect(() => {\n setDragVisibility('hidden');\n }, [editor.selection]);\n\n return (\n <Wrapper ref={composedBoxRefs} $isOverDropTarget={isOverDropTarget}>\n {isOverDropTarget && (\n <DropPlaceholder\n borderStyle=\"solid\"\n borderColor=\"secondary200\"\n borderWidth=\"2px\"\n width=\"calc(100% - 24px)\"\n marginLeft=\"auto\"\n dragDirection={dragDirection}\n // For list items placeholder reduce the margin around\n placeholderMargin={children.props.as && children.props.as === 'li' ? 1 : 2}\n />\n )}\n {isDragging ? (\n <CloneDragItem dragHandleTopMargin={dragHandleTopMargin}>{children}</CloneDragItem>\n ) : (\n <DragItem\n ref={dragRef}\n data-handler-id={handlerId}\n gap={2}\n paddingLeft={2}\n alignItems=\"start\"\n onDragStart={\n isDragAndDropEnabled\n ? (event) => {\n const target = event.target as HTMLElement;\n const currentTarget = event.currentTarget as HTMLElement;\n\n // Dragging action should only trigger drag event when button is dragged, however update styles on the whole dragItem.\n if (target.getAttribute('role') !== 'button') {\n event.preventDefault();\n } else {\n // Setting styles using dragging state is not working, so set it on current target element as nodes get dragged\n currentTarget.style.opacity = '0.5';\n }\n }\n : undefined\n }\n onDragEnd={\n isDragAndDropEnabled\n ? (event) => {\n const currentTarget = event.currentTarget as HTMLElement;\n currentTarget.style.opacity = '1';\n }\n : undefined\n }\n onMouseEnter={() => setDragVisibility('visible')}\n onFocusCapture={() => setDragVisibility('visible')}\n onBlurCapture={() => setDragVisibility('hidden')}\n onMouseLeave={() => setDragVisibility('hidden')}\n aria-disabled={disabled}\n $dragVisibility={dragVisibility}\n >\n <DragIconButton\n tag=\"div\"\n contentEditable={false}\n role=\"button\"\n tabIndex={0}\n withTooltip={false}\n label={formatMessage({\n id: getTranslation('components.DragHandle-label'),\n defaultMessage: 'Drag',\n })}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n aria-disabled={disabled}\n disabled={disabled}\n draggable={isDragAndDropEnabled}\n // For some blocks top margin added to drag handle to align at the text level\n $dragHandleTopMargin={dragHandleTopMargin}\n >\n <Drag color=\"primary500\" />\n </DragIconButton>\n {children}\n </DragItem>\n )}\n </Wrapper>\n );\n};\n\ninterface CloneDragItemProps {\n children: RenderElementProps['children'];\n dragHandleTopMargin?: CSSProperties['marginTop'];\n}\n\n// To prevent applying opacity to the original item being dragged, display a cloned element without opacity.\nconst CloneDragItem = ({ children, dragHandleTopMargin }: CloneDragItemProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <DragItem gap={2} paddingLeft={2} alignItems=\"start\" $dragVisibility=\"visible\">\n <DragIconButton\n tag=\"div\"\n role=\"button\"\n withTooltip={false}\n label={formatMessage({\n id: getTranslation('components.DragHandle-label'),\n defaultMessage: 'Drag',\n })}\n $dragHandleTopMargin={dragHandleTopMargin}\n >\n <Drag color=\"neutral600\" />\n </DragIconButton>\n {children}\n </DragItem>\n );\n};\n\ninterface ExtendedRenderLeafProps extends RenderLeafProps {\n leaf: RenderLeafProps['leaf'] & { className?: string };\n}\n\nconst baseRenderLeaf = (props: ExtendedRenderLeafProps, modifiers: ModifiersStore) => {\n // Recursively wrap the children for each active modifier\n const wrappedChildren = getEntries(modifiers).reduce((currentChildren, modifierEntry) => {\n const [name, modifier] = modifierEntry;\n\n if (props.leaf[name]) {\n return modifier.renderLeaf(currentChildren);\n }\n\n return currentChildren;\n }, props.children);\n\n return (\n <span {...props.attributes} className={props.leaf.className}>\n {wrappedChildren}\n </span>\n );\n};\n\ntype BaseRenderElementProps = Direction & {\n props: RenderElementProps['children'];\n blocks: Partial<BlocksStore>;\n editor: Editor;\n isMobile: boolean;\n};\n\nconst baseRenderElement = ({\n props,\n blocks,\n editor,\n dragDirection,\n setDragDirection,\n isMobile,\n}: BaseRenderElementProps) => {\n const { element } = props;\n\n const blockMatch = Object.values(blocks).find((block) => block?.matchNode(element));\n const block = blockMatch || blocks.paragraph;\n\n if (!block) {\n return <></>;\n }\n\n const nodePath = ReactEditor.findPath(editor, element);\n\n const isDraggable = block.isDraggable?.(element) ?? true;\n\n if (!isDraggable || isMobile) {\n return block.renderElement(props);\n }\n\n return (\n <DragAndDropElement\n index={nodePath}\n setDragDirection={setDragDirection}\n dragDirection={dragDirection}\n dragHandleTopMargin={block.dragHandleTopMargin}\n >\n {block.renderElement(props)}\n </DragAndDropElement>\n );\n};\n\nconst dragNoop = () => true;\n\ninterface BlocksContentProps {\n placeholder?: string;\n ariaLabelId: string;\n}\n\nconst BlocksContent = ({ placeholder, ariaLabelId }: BlocksContentProps) => {\n const { editor, disabled, blocks, modifiers, setLiveText, isExpandedMode, flushPendingFormSync } =\n useBlocksEditorContext('BlocksContent');\n const isMobile = useIsMobile();\n const blocksRef = React.useRef<HTMLDivElement>(null);\n const { formatMessage } = useIntl();\n const [dragDirection, setDragDirection] = React.useState<DragDirection | null>(null);\n const { modalElement, handleConversionResult } = useConversionModal();\n\n // Create renderLeaf function based on the modifiers store\n const renderLeaf = React.useCallback(\n (props: ExtendedRenderLeafProps) => baseRenderLeaf(props, modifiers),\n [modifiers]\n );\n\n const handleMoveBlocks = (editor: Editor, event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) return;\n\n const start = Range.start(editor.selection);\n const currentIndex = [start.path[0]];\n let newIndexPosition = 0;\n\n if (event.key === 'ArrowUp') {\n newIndexPosition = currentIndex[0] > 0 ? currentIndex[0] - 1 : currentIndex[0];\n } else {\n newIndexPosition =\n currentIndex[0] < editor.children.length - 1 ? currentIndex[0] + 1 : currentIndex[0];\n }\n\n const newIndex = [newIndexPosition];\n\n if (newIndexPosition !== currentIndex[0]) {\n Transforms.moveNodes(editor, {\n at: currentIndex,\n to: newIndex,\n });\n\n setLiveText(\n formatMessage(\n {\n id: getTranslation('components.Blocks.dnd.reorder'),\n defaultMessage: '{item}, moved. New position in the editor: {position}.',\n },\n {\n item: `${name}.${currentIndex[0] + 1}`,\n position: `${newIndex[0] + 1} of ${editor.children.length}`,\n }\n )\n );\n\n event.preventDefault();\n }\n };\n\n // Create renderElement function base on the blocks store\n const renderElement = React.useCallback(\n (props: RenderElementProps) =>\n baseRenderElement({ props, blocks, editor, dragDirection, setDragDirection, isMobile }),\n [blocks, editor, dragDirection, isMobile, setDragDirection]\n );\n\n const checkSnippet = (event: React.KeyboardEvent<HTMLElement>) => {\n // Get current text block\n if (!editor.selection) {\n return;\n }\n\n const [textNode, textNodePath] = Editor.node(editor, editor.selection.anchor.path);\n\n // Narrow the type to a text node\n if (Editor.isEditor(textNode) || textNode.type !== 'text') {\n return;\n }\n\n // Don't check for snippets if we're not at the start of a block\n if (textNodePath.at(-1) !== 0) {\n return;\n }\n\n // Check if the text node starts with a known snippet\n const blockMatchingSnippet = Object.values(blocks).find((block) => {\n return block?.snippets?.includes(textNode.text);\n });\n\n if (blockMatchingSnippet?.handleConvert) {\n // Prevent the space from being created and delete the snippet\n event.preventDefault();\n Transforms.delete(editor, {\n distance: textNode.text.length,\n unit: 'character',\n reverse: true,\n });\n\n // Convert the selected block\n const maybeRenderModal = blockMatchingSnippet.handleConvert(editor);\n handleConversionResult(maybeRenderModal);\n }\n };\n\n const handleEnter = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n if (!selectedBlock) {\n return;\n }\n\n // Allow forced line breaks when shift is pressed\n if (event.shiftKey && selectedNode.type !== 'image') {\n Transforms.insertText(editor, '\\n');\n return;\n }\n\n // Check if there's an enter handler for the selected block\n if (selectedBlock.handleEnterKey) {\n selectedBlock.handleEnterKey(editor);\n } else {\n blocks.paragraph?.handleEnterKey!(editor);\n }\n };\n\n const handleBackspaceEvent = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n\n if (!selectedBlock) {\n return;\n }\n\n if (selectedBlock.handleBackspaceKey) {\n selectedBlock.handleBackspaceKey(editor, event);\n }\n };\n\n const handleTab = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n if (!selectedBlock) {\n return;\n }\n\n event.preventDefault();\n\n if (event.shiftKey && selectedBlock.handleShiftTab) {\n // Handle Shift+Tab (unindent)\n selectedBlock.handleShiftTab(editor);\n } else if (!event.shiftKey && selectedBlock.handleTab) {\n // Handle Tab (indent)\n selectedBlock.handleTab(editor);\n }\n };\n\n const handleKeyboardShortcuts = (event: React.KeyboardEvent<HTMLElement>) => {\n const isCtrlOrCmd = event.metaKey || event.ctrlKey;\n\n if (isCtrlOrCmd) {\n // Check if there's a modifier to toggle\n Object.values(modifiers).forEach((value) => {\n if (value.isValidEventKey(event)) {\n event.preventDefault();\n value.handleToggle(editor);\n return;\n }\n });\n if (event.shiftKey && ['ArrowUp', 'ArrowDown'].includes(event.key)) {\n handleMoveBlocks(editor, event);\n }\n }\n };\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLElement> = (event) => {\n // Find the right block-specific handlers for enter and backspace key presses\n switch (event.key) {\n case 'Enter':\n if (!event.nativeEvent.isComposing) {\n event.preventDefault();\n return handleEnter(event);\n }\n break;\n case 'Backspace':\n return handleBackspaceEvent(event);\n case 'Tab':\n return handleTab(event);\n case 'Escape':\n return ReactEditor.blur(editor);\n }\n handleKeyboardShortcuts(event);\n // Check if a snippet was triggered\n if (event.key === ' ') {\n checkSnippet(event);\n }\n };\n\n /**\n * scrollSelectionIntoView : Slate's default method to scroll a DOM selection into the view,\n * thats shifting layout for us when there is a overflowY:scroll on the viewport.\n * We are overriding it to check if the selection is not fully within the visible area of the editor,\n * we use scrollBy one line to the bottom\n */\n\n const handleScrollSelectionIntoView = React.useCallback(() => {\n if (!editor.selection || !blocksRef.current) {\n return;\n }\n\n const domRange = ReactEditor.toDOMRange(editor, editor.selection);\n const domRect = domRange.getBoundingClientRect();\n\n const editorRect = blocksRef.current.getBoundingClientRect();\n\n // Check if the selection is not fully within the visible area of the editor\n if (domRect.top < editorRect.top || domRect.bottom > editorRect.bottom) {\n // Scroll by one line to the bottom\n blocksRef.current.scrollBy({\n top: 28, // 20px is the line-height + 8px line gap\n behavior: 'smooth',\n });\n }\n }, [editor]);\n\n return (\n <Box\n ref={blocksRef}\n grow={1}\n width=\"100%\"\n overflow=\"auto\"\n fontSize={2}\n background=\"neutral0\"\n color=\"neutral800\"\n lineHeight={6}\n paddingLeft={{ initial: 4, medium: 0 }}\n paddingRight={7}\n paddingTop={6}\n paddingBottom={3}\n >\n <StyledEditable\n aria-labelledby={ariaLabelId}\n readOnly={disabled}\n placeholder={placeholder}\n $isExpandedMode={isExpandedMode}\n decorate={decorateCode}\n renderElement={renderElement}\n renderLeaf={renderLeaf}\n onKeyDown={handleKeyDown}\n scrollSelectionIntoView={handleScrollSelectionIntoView}\n onBlur={flushPendingFormSync}\n // As we have our own handler to drag and drop the elements returing true will skip slate's own event handler\n onDrop={dragNoop}\n onDragStart={dragNoop}\n />\n {modalElement}\n </Box>\n );\n};\n\nexport { BlocksContent, BlocksContentProps };\n"],"names":["StyledEditable","styled","Editable","theme","spaces","props","$isExpandedMode","breakpoints","medium","Wrapper","Box","$isOverDropTarget","DropPlaceholder","dragDirection","placeholderMargin","css","DIRECTIONS","UPWARD","DOWNWARD","DragItem","Flex","$dragVisibility","DragIconButton","IconButton","borderRadius","$dragHandleTopMargin","colors","neutral100","neutral150","neutral500","DragAndDropElement","children","index","setDragDirection","dragHandleTopMargin","editor","disabled","name","setLiveText","useBlocksEditorContext","formatMessage","useIntl","dragVisibility","setDragVisibility","React","useState","isDragAndDropEnabled","handleMoveBlock","useCallback","newIndex","currentIndex","Transforms","moveNodes","at","to","currentIndexPosition","slice","newIndexPosition","id","getTranslation","defaultMessage","item","join","position","length","handlerId","isDragging","isOverDropTarget","direction","blockRef","dropRef","dragRef","useDragAndDrop","type","ItemTypes","BLOCKS","displayedValue","onDropItem","composedBoxRefs","useComposedRefs","useEffect","selection","_jsxs","ref","_jsx","borderStyle","borderColor","borderWidth","width","marginLeft","as","CloneDragItem","data-handler-id","gap","paddingLeft","alignItems","onDragStart","event","target","currentTarget","getAttribute","preventDefault","style","opacity","undefined","onDragEnd","onMouseEnter","onFocusCapture","onBlurCapture","onMouseLeave","aria-disabled","tag","contentEditable","role","tabIndex","withTooltip","label","onClick","e","stopPropagation","draggable","Drag","color","baseRenderLeaf","modifiers","wrappedChildren","getEntries","reduce","currentChildren","modifierEntry","modifier","leaf","renderLeaf","span","attributes","className","baseRenderElement","blocks","isMobile","element","blockMatch","Object","values","find","block","matchNode","paragraph","_Fragment","nodePath","ReactEditor","findPath","isDraggable","renderElement","dragNoop","BlocksContent","placeholder","ariaLabelId","isExpandedMode","flushPendingFormSync","useIsMobile","blocksRef","useRef","modalElement","handleConversionResult","useConversionModal","handleMoveBlocks","start","Range","path","key","checkSnippet","textNode","textNodePath","Editor","node","anchor","isEditor","blockMatchingSnippet","snippets","includes","text","handleConvert","delete","distance","unit","reverse","maybeRenderModal","handleEnter","selectedNode","selectedBlock","shiftKey","insertText","handleEnterKey","handleBackspaceEvent","handleBackspaceKey","handleTab","handleShiftTab","handleKeyboardShortcuts","isCtrlOrCmd","metaKey","ctrlKey","forEach","value","isValidEventKey","handleToggle","handleKeyDown","nativeEvent","isComposing","blur","handleScrollSelectionIntoView","current","domRange","toDOMRange","domRect","getBoundingClientRect","editorRect","top","bottom","scrollBy","behavior","grow","overflow","fontSize","background","lineHeight","initial","paddingRight","paddingTop","paddingBottom","aria-labelledby","readOnly","decorate","decorateCode","onKeyDown","scrollSelectionIntoView","onBlur","onDrop"],"mappings":"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"}
1
+ {"version":3,"file":"BlocksContent.js","sources":["../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIsMobile } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n BoxComponent,\n Flex,\n FlexComponent,\n IconButton,\n IconButtonComponent,\n useComposedRefs,\n} from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { Editor, Range, Transforms } from 'slate';\nimport { ReactEditor, type RenderElementProps, type RenderLeafProps, Editable } from 'slate-react';\nimport { styled, CSSProperties, css } from 'styled-components';\n\nimport { ItemTypes } from '../../../../../constants/dragAndDrop';\nimport { useDragAndDrop, DIRECTIONS } from '../../../../../hooks/useDragAndDrop';\nimport { getTranslation } from '../../../../../utils/translations';\n\nimport { decorateCode } from './Blocks/Code';\nimport { type BlocksStore, useBlocksEditorContext } from './BlocksEditor';\nimport { useConversionModal } from './BlocksToolbar';\nimport { type ModifiersStore } from './Modifiers';\nimport { getEntries } from './utils/types';\n\nconst StyledEditable = styled(Editable)<{ $isExpandedMode: boolean }>`\n // The outline style is set on the wrapper with :focus-within\n outline: none;\n display: flex;\n flex-direction: column;\n gap: ${({ theme }) => theme.spaces[3]};\n height: 100%;\n // For fullscreen align input in the center with fixed width\n width: ${(props) => (props.$isExpandedMode ? '512px' : '100%')};\n margin: auto;\n font-size: 1.6rem;\n\n ${({ theme }) => theme.breakpoints.medium} {\n font-size: 1.4rem;\n }\n > *:last-child {\n padding-bottom: ${({ theme }) => theme.spaces[3]};\n }\n`;\n\nconst Wrapper = styled<BoxComponent>(Box)<{ $isOverDropTarget: boolean }>`\n position: ${({ $isOverDropTarget }) => $isOverDropTarget && 'relative'};\n`;\n\ntype DragDirection = (typeof DIRECTIONS)[keyof typeof DIRECTIONS];\n\nconst DropPlaceholder = styled<BoxComponent>(Box)<{\n dragDirection: DragDirection | null;\n placeholderMargin: 1 | 2;\n}>`\n position: absolute;\n right: 0;\n\n // Show drop placeholder 8px above or below the drop target\n ${({ dragDirection, theme, placeholderMargin }) => css`\n top: ${dragDirection === DIRECTIONS.UPWARD && `-${theme.spaces[placeholderMargin]}`};\n bottom: ${dragDirection === DIRECTIONS.DOWNWARD && `-${theme.spaces[placeholderMargin]}`};\n `}\n`;\n\nconst DragItem = styled<FlexComponent>(Flex)<{ $dragVisibility: CSSProperties['visibility'] }>`\n // Style each block rendered using renderElement()\n & > [data-slate-node='element'] {\n width: 100%;\n opacity: inherit;\n }\n\n // Set the visibility of drag button\n [role='button'] {\n visibility: ${(props) => props.$dragVisibility};\n opacity: inherit;\n }\n &[aria-disabled='true'] {\n user-drag: none;\n }\n`;\n\nconst DragIconButton = styled<IconButtonComponent<'div'>>(IconButton)<{\n $dragHandleTopMargin?: CSSProperties['marginTop'];\n}>`\n user-select: none;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n padding-left: ${({ theme }) => theme.spaces[0]};\n padding-right: ${({ theme }) => theme.spaces[0]};\n padding-top: ${({ theme }) => theme.spaces[1]};\n padding-bottom: ${({ theme }) => theme.spaces[1]};\n visibility: hidden;\n cursor: grab;\n opacity: inherit;\n margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};\n\n &:hover {\n background: ${({ theme }) => theme.colors.neutral100};\n }\n &:active {\n cursor: grabbing;\n background: ${({ theme }) => theme.colors.neutral150};\n }\n &[aria-disabled='true'] {\n visibility: hidden;\n }\n svg {\n min-width: ${({ theme }) => theme.spaces[3]};\n\n path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n }\n`;\n\ntype Direction = {\n setDragDirection: (direction: DragDirection) => void;\n dragDirection: DragDirection | null;\n};\n\ntype DragAndDropElementProps = Direction & {\n children: RenderElementProps['children'];\n index: Array<number>;\n dragHandleTopMargin?: CSSProperties['marginTop'];\n};\n\nconst DragAndDropElement = ({\n children,\n index,\n setDragDirection,\n dragDirection,\n dragHandleTopMargin,\n}: DragAndDropElementProps) => {\n const { editor, disabled, name, setLiveText } = useBlocksEditorContext('DragAndDropElement');\n const { formatMessage } = useIntl();\n const [dragVisibility, setDragVisibility] = React.useState<CSSProperties['visibility']>('hidden');\n const isDragAndDropEnabled = !disabled;\n\n const handleMoveBlock = React.useCallback(\n (newIndex: Array<number>, currentIndex: Array<number>) => {\n Transforms.moveNodes(editor, {\n at: currentIndex,\n to: newIndex,\n });\n\n // Add 1 to the index for the live text message\n const currentIndexPosition = [currentIndex[0] + 1, ...currentIndex.slice(1)];\n const newIndexPosition = [newIndex[0] + 1, ...newIndex.slice(1)];\n\n setLiveText(\n formatMessage(\n {\n id: getTranslation('components.Blocks.dnd.reorder'),\n defaultMessage: '{item}, moved. New position in the editor: {position}.',\n },\n {\n item: `${name}.${currentIndexPosition.join(',')}`,\n position: `${newIndexPosition.join(',')} of ${editor.children.length}`,\n }\n )\n );\n },\n [editor, formatMessage, name, setLiveText]\n );\n\n const [{ handlerId, isDragging, isOverDropTarget, direction }, blockRef, dropRef, dragRef] =\n useDragAndDrop(isDragAndDropEnabled, {\n type: `${ItemTypes.BLOCKS}_${name}`,\n index,\n item: {\n index,\n displayedValue: children,\n },\n onDropItem(currentIndex, newIndex) {\n if (newIndex) handleMoveBlock(newIndex, currentIndex);\n },\n });\n\n const composedBoxRefs = useComposedRefs(blockRef, dropRef);\n\n // Set Drag direction before loosing state while dragging\n React.useEffect(() => {\n if (direction) {\n setDragDirection(direction);\n }\n }, [direction, setDragDirection]);\n\n // On selection change hide drag handle\n React.useEffect(() => {\n setDragVisibility('hidden');\n }, [editor.selection]);\n\n return (\n <Wrapper ref={composedBoxRefs} $isOverDropTarget={isOverDropTarget}>\n {isOverDropTarget && (\n <DropPlaceholder\n borderStyle=\"solid\"\n borderColor=\"secondary200\"\n borderWidth=\"2px\"\n width=\"calc(100% - 24px)\"\n marginLeft=\"auto\"\n dragDirection={dragDirection}\n // For list items placeholder reduce the margin around\n placeholderMargin={children.props.as && children.props.as === 'li' ? 1 : 2}\n />\n )}\n {isDragging ? (\n <CloneDragItem dragHandleTopMargin={dragHandleTopMargin}>{children}</CloneDragItem>\n ) : (\n <DragItem\n ref={dragRef}\n data-handler-id={handlerId}\n gap={2}\n paddingLeft={2}\n alignItems=\"start\"\n onDragStart={\n isDragAndDropEnabled\n ? (event) => {\n const target = event.target as HTMLElement;\n const currentTarget = event.currentTarget as HTMLElement;\n\n // Dragging action should only trigger drag event when button is dragged, however update styles on the whole dragItem.\n if (target.getAttribute('role') !== 'button') {\n event.preventDefault();\n } else {\n // Setting styles using dragging state is not working, so set it on current target element as nodes get dragged\n currentTarget.style.opacity = '0.5';\n }\n }\n : undefined\n }\n onDragEnd={\n isDragAndDropEnabled\n ? (event) => {\n const currentTarget = event.currentTarget as HTMLElement;\n currentTarget.style.opacity = '1';\n }\n : undefined\n }\n onMouseEnter={() => setDragVisibility('visible')}\n onFocusCapture={() => setDragVisibility('visible')}\n onBlurCapture={() => setDragVisibility('hidden')}\n onMouseLeave={() => setDragVisibility('hidden')}\n aria-disabled={disabled}\n $dragVisibility={dragVisibility}\n >\n <DragIconButton\n tag=\"div\"\n contentEditable={false}\n role=\"button\"\n tabIndex={0}\n withTooltip={false}\n label={formatMessage({\n id: getTranslation('components.DragHandle-label'),\n defaultMessage: 'Drag',\n })}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n aria-disabled={disabled}\n disabled={disabled}\n draggable={isDragAndDropEnabled}\n // For some blocks top margin added to drag handle to align at the text level\n $dragHandleTopMargin={dragHandleTopMargin}\n >\n <Drag color=\"primary500\" />\n </DragIconButton>\n {children}\n </DragItem>\n )}\n </Wrapper>\n );\n};\n\ninterface CloneDragItemProps {\n children: RenderElementProps['children'];\n dragHandleTopMargin?: CSSProperties['marginTop'];\n}\n\n// To prevent applying opacity to the original item being dragged, display a cloned element without opacity.\nconst CloneDragItem = ({ children, dragHandleTopMargin }: CloneDragItemProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <DragItem gap={2} paddingLeft={2} alignItems=\"start\" $dragVisibility=\"visible\">\n <DragIconButton\n tag=\"div\"\n role=\"button\"\n withTooltip={false}\n label={formatMessage({\n id: getTranslation('components.DragHandle-label'),\n defaultMessage: 'Drag',\n })}\n $dragHandleTopMargin={dragHandleTopMargin}\n >\n <Drag color=\"neutral600\" />\n </DragIconButton>\n {children}\n </DragItem>\n );\n};\n\ninterface ExtendedRenderLeafProps extends RenderLeafProps {\n leaf: RenderLeafProps['leaf'] & { className?: string };\n}\n\nconst baseRenderLeaf = (props: ExtendedRenderLeafProps, modifiers: ModifiersStore) => {\n // Recursively wrap the children for each active modifier\n const wrappedChildren = getEntries(modifiers).reduce((currentChildren, modifierEntry) => {\n const [name, modifier] = modifierEntry;\n\n if (props.leaf[name]) {\n return modifier.renderLeaf(currentChildren);\n }\n\n return currentChildren;\n }, props.children);\n\n return (\n <span {...props.attributes} className={props.leaf.className}>\n {wrappedChildren}\n </span>\n );\n};\n\ntype BaseRenderElementProps = Direction & {\n props: RenderElementProps['children'];\n blocks: Partial<BlocksStore>;\n editor: Editor;\n isMobile: boolean;\n};\n\nconst baseRenderElement = ({\n props,\n blocks,\n editor,\n dragDirection,\n setDragDirection,\n isMobile,\n}: BaseRenderElementProps) => {\n const { element } = props;\n\n const blockMatch = Object.values(blocks).find((block) => block?.matchNode(element));\n const block = blockMatch || blocks.paragraph;\n\n if (!block) {\n return <></>;\n }\n\n const nodePath = ReactEditor.findPath(editor, element);\n\n const isDraggable = block.isDraggable?.(element) ?? true;\n\n if (!isDraggable || isMobile) {\n return block.renderElement(props);\n }\n\n return (\n <DragAndDropElement\n index={nodePath}\n setDragDirection={setDragDirection}\n dragDirection={dragDirection}\n dragHandleTopMargin={block.dragHandleTopMargin}\n >\n {block.renderElement(props)}\n </DragAndDropElement>\n );\n};\n\nconst dragNoop = () => true;\n\ninterface BlocksContentProps {\n placeholder?: string;\n ariaLabelId: string;\n autoFocus?: boolean;\n onFocus?: React.FocusEventHandler<HTMLElement>;\n onBlur?: React.FocusEventHandler<HTMLElement>;\n}\n\nconst BlocksContent = ({\n placeholder,\n ariaLabelId,\n autoFocus,\n onFocus,\n onBlur,\n}: BlocksContentProps) => {\n const { editor, disabled, blocks, modifiers, setLiveText, isExpandedMode, flushPendingFormSync } =\n useBlocksEditorContext('BlocksContent');\n const isMobile = useIsMobile();\n const blocksRef = React.useRef<HTMLDivElement>(null);\n const { formatMessage } = useIntl();\n const [dragDirection, setDragDirection] = React.useState<DragDirection | null>(null);\n const { modalElement, handleConversionResult } = useConversionModal();\n\n // Create renderLeaf function based on the modifiers store\n const renderLeaf = React.useCallback(\n (props: ExtendedRenderLeafProps) => baseRenderLeaf(props, modifiers),\n [modifiers]\n );\n\n const handleMoveBlocks = (editor: Editor, event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) return;\n\n const start = Range.start(editor.selection);\n const currentIndex = [start.path[0]];\n let newIndexPosition = 0;\n\n if (event.key === 'ArrowUp') {\n newIndexPosition = currentIndex[0] > 0 ? currentIndex[0] - 1 : currentIndex[0];\n } else {\n newIndexPosition =\n currentIndex[0] < editor.children.length - 1 ? currentIndex[0] + 1 : currentIndex[0];\n }\n\n const newIndex = [newIndexPosition];\n\n if (newIndexPosition !== currentIndex[0]) {\n Transforms.moveNodes(editor, {\n at: currentIndex,\n to: newIndex,\n });\n\n setLiveText(\n formatMessage(\n {\n id: getTranslation('components.Blocks.dnd.reorder'),\n defaultMessage: '{item}, moved. New position in the editor: {position}.',\n },\n {\n item: `${name}.${currentIndex[0] + 1}`,\n position: `${newIndex[0] + 1} of ${editor.children.length}`,\n }\n )\n );\n\n event.preventDefault();\n }\n };\n\n // Create renderElement function base on the blocks store\n const renderElement = React.useCallback(\n (props: RenderElementProps) =>\n baseRenderElement({ props, blocks, editor, dragDirection, setDragDirection, isMobile }),\n [blocks, editor, dragDirection, isMobile, setDragDirection]\n );\n\n const checkSnippet = (event: React.KeyboardEvent<HTMLElement>) => {\n // Get current text block\n if (!editor.selection) {\n return;\n }\n\n const [textNode, textNodePath] = Editor.node(editor, editor.selection.anchor.path);\n\n // Narrow the type to a text node\n if (Editor.isEditor(textNode) || textNode.type !== 'text') {\n return;\n }\n\n // Don't check for snippets if we're not at the start of a block\n if (textNodePath.at(-1) !== 0) {\n return;\n }\n\n // Check if the text node starts with a known snippet\n const blockMatchingSnippet = Object.values(blocks).find((block) => {\n return block?.snippets?.includes(textNode.text);\n });\n\n if (blockMatchingSnippet?.handleConvert) {\n // Prevent the space from being created and delete the snippet\n event.preventDefault();\n Transforms.delete(editor, {\n distance: textNode.text.length,\n unit: 'character',\n reverse: true,\n });\n\n // Convert the selected block\n const maybeRenderModal = blockMatchingSnippet.handleConvert(editor);\n handleConversionResult(maybeRenderModal);\n }\n };\n\n const handleEnter = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n if (!selectedBlock) {\n return;\n }\n\n // Allow forced line breaks when shift is pressed\n if (event.shiftKey && selectedNode.type !== 'image') {\n Transforms.insertText(editor, '\\n');\n return;\n }\n\n // Check if there's an enter handler for the selected block\n if (selectedBlock.handleEnterKey) {\n selectedBlock.handleEnterKey(editor);\n } else {\n blocks.paragraph?.handleEnterKey!(editor);\n }\n };\n\n const handleBackspaceEvent = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n\n if (!selectedBlock) {\n return;\n }\n\n if (selectedBlock.handleBackspaceKey) {\n selectedBlock.handleBackspaceKey(editor, event);\n }\n };\n\n const handleTab = (event: React.KeyboardEvent<HTMLElement>) => {\n if (!editor.selection) {\n return;\n }\n\n const selectedNode = editor.children[editor.selection.anchor.path[0]];\n const selectedBlock = Object.values(blocks).find((block) => block?.matchNode(selectedNode));\n if (!selectedBlock) {\n return;\n }\n\n event.preventDefault();\n\n if (event.shiftKey && selectedBlock.handleShiftTab) {\n // Handle Shift+Tab (unindent)\n selectedBlock.handleShiftTab(editor);\n } else if (!event.shiftKey && selectedBlock.handleTab) {\n // Handle Tab (indent)\n selectedBlock.handleTab(editor);\n }\n };\n\n const handleKeyboardShortcuts = (event: React.KeyboardEvent<HTMLElement>) => {\n const isCtrlOrCmd = event.metaKey || event.ctrlKey;\n\n if (isCtrlOrCmd) {\n // Check if there's a modifier to toggle\n Object.values(modifiers).forEach((value) => {\n if (value.isValidEventKey(event)) {\n event.preventDefault();\n value.handleToggle(editor);\n return;\n }\n });\n if (event.shiftKey && ['ArrowUp', 'ArrowDown'].includes(event.key)) {\n handleMoveBlocks(editor, event);\n }\n }\n };\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLElement> = (event) => {\n // Find the right block-specific handlers for enter and backspace key presses\n switch (event.key) {\n case 'Enter':\n if (!event.nativeEvent.isComposing) {\n event.preventDefault();\n return handleEnter(event);\n }\n break;\n case 'Backspace':\n return handleBackspaceEvent(event);\n case 'Tab':\n return handleTab(event);\n case 'Escape':\n return ReactEditor.blur(editor);\n }\n handleKeyboardShortcuts(event);\n // Check if a snippet was triggered\n if (event.key === ' ') {\n checkSnippet(event);\n }\n };\n\n /**\n * scrollSelectionIntoView : Slate's default method to scroll a DOM selection into the view,\n * thats shifting layout for us when there is a overflowY:scroll on the viewport.\n * We are overriding it to check if the selection is not fully within the visible area of the editor,\n * we use scrollBy one line to the bottom\n */\n\n const handleScrollSelectionIntoView = React.useCallback(() => {\n if (!editor.selection || !blocksRef.current) {\n return;\n }\n\n const domRange = ReactEditor.toDOMRange(editor, editor.selection);\n const domRect = domRange.getBoundingClientRect();\n\n const editorRect = blocksRef.current.getBoundingClientRect();\n\n // Check if the selection is not fully within the visible area of the editor\n if (domRect.top < editorRect.top || domRect.bottom > editorRect.bottom) {\n // Scroll by one line to the bottom\n blocksRef.current.scrollBy({\n top: 28, // 20px is the line-height + 8px line gap\n behavior: 'smooth',\n });\n }\n }, [editor]);\n\n return (\n <Box\n ref={blocksRef}\n grow={1}\n width=\"100%\"\n overflow=\"auto\"\n fontSize={2}\n background=\"neutral0\"\n color=\"neutral800\"\n lineHeight={6}\n paddingLeft={{ initial: 4, medium: 0 }}\n paddingRight={7}\n paddingTop={6}\n paddingBottom={3}\n >\n <StyledEditable\n aria-labelledby={ariaLabelId}\n readOnly={disabled}\n placeholder={placeholder}\n $isExpandedMode={isExpandedMode}\n decorate={decorateCode}\n renderElement={renderElement}\n renderLeaf={renderLeaf}\n onKeyDown={handleKeyDown}\n scrollSelectionIntoView={handleScrollSelectionIntoView}\n autoFocus={autoFocus}\n onFocus={onFocus}\n onBlur={(event) => {\n flushPendingFormSync();\n onBlur?.(event);\n }}\n // As we have our own handler to drag and drop the elements returing true will skip slate's own event handler\n onDrop={dragNoop}\n onDragStart={dragNoop}\n />\n {modalElement}\n </Box>\n );\n};\n\nexport { BlocksContent, BlocksContentProps };\n"],"names":["StyledEditable","styled","Editable","theme","spaces","props","$isExpandedMode","breakpoints","medium","Wrapper","Box","$isOverDropTarget","DropPlaceholder","dragDirection","placeholderMargin","css","DIRECTIONS","UPWARD","DOWNWARD","DragItem","Flex","$dragVisibility","DragIconButton","IconButton","borderRadius","$dragHandleTopMargin","colors","neutral100","neutral150","neutral500","DragAndDropElement","children","index","setDragDirection","dragHandleTopMargin","editor","disabled","name","setLiveText","useBlocksEditorContext","formatMessage","useIntl","dragVisibility","setDragVisibility","React","useState","isDragAndDropEnabled","handleMoveBlock","useCallback","newIndex","currentIndex","Transforms","moveNodes","at","to","currentIndexPosition","slice","newIndexPosition","id","getTranslation","defaultMessage","item","join","position","length","handlerId","isDragging","isOverDropTarget","direction","blockRef","dropRef","dragRef","useDragAndDrop","type","ItemTypes","BLOCKS","displayedValue","onDropItem","composedBoxRefs","useComposedRefs","useEffect","selection","_jsxs","ref","_jsx","borderStyle","borderColor","borderWidth","width","marginLeft","as","CloneDragItem","data-handler-id","gap","paddingLeft","alignItems","onDragStart","event","target","currentTarget","getAttribute","preventDefault","style","opacity","undefined","onDragEnd","onMouseEnter","onFocusCapture","onBlurCapture","onMouseLeave","aria-disabled","tag","contentEditable","role","tabIndex","withTooltip","label","onClick","e","stopPropagation","draggable","Drag","color","baseRenderLeaf","modifiers","wrappedChildren","getEntries","reduce","currentChildren","modifierEntry","modifier","leaf","renderLeaf","span","attributes","className","baseRenderElement","blocks","isMobile","element","blockMatch","Object","values","find","block","matchNode","paragraph","_Fragment","nodePath","ReactEditor","findPath","isDraggable","renderElement","dragNoop","BlocksContent","placeholder","ariaLabelId","autoFocus","onFocus","onBlur","isExpandedMode","flushPendingFormSync","useIsMobile","blocksRef","useRef","modalElement","handleConversionResult","useConversionModal","handleMoveBlocks","start","Range","path","key","checkSnippet","textNode","textNodePath","Editor","node","anchor","isEditor","blockMatchingSnippet","snippets","includes","text","handleConvert","delete","distance","unit","reverse","maybeRenderModal","handleEnter","selectedNode","selectedBlock","shiftKey","insertText","handleEnterKey","handleBackspaceEvent","handleBackspaceKey","handleTab","handleShiftTab","handleKeyboardShortcuts","isCtrlOrCmd","metaKey","ctrlKey","forEach","value","isValidEventKey","handleToggle","handleKeyDown","nativeEvent","isComposing","blur","handleScrollSelectionIntoView","current","domRange","toDOMRange","domRect","getBoundingClientRect","editorRect","top","bottom","scrollBy","behavior","grow","overflow","fontSize","background","lineHeight","initial","paddingRight","paddingTop","paddingBottom","aria-labelledby","readOnly","decorate","decorateCode","onKeyDown","scrollSelectionIntoView","onDrop"],"mappings":"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"}