@strapi/content-manager 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4 → 0.0.0-experimental.332a7d5b6b1d23635d7e205657f0ff39ec133c9e

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 (215) hide show
  1. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
  2. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-D4H-v0et.mjs} +4 -4
  4. package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-D4H-v0et.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-DdkVGfXC.js} +5 -6
  6. package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-DdkVGfXC.js.map} +1 -1
  7. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  9. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  10. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs → EditConfigurationPage-D1nvB7Br.mjs} +4 -4
  11. package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-D1nvB7Br.mjs.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-LYEvR4fW.js} +5 -6
  13. package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-LYEvR4fW.js.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-Bcnff6Vd.mjs} +34 -46
  15. package/dist/_chunks/EditViewPage-Bcnff6Vd.mjs.map +1 -0
  16. package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-DqelJ9UK.js} +36 -49
  17. package/dist/_chunks/EditViewPage-DqelJ9UK.js.map +1 -0
  18. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  19. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  20. package/dist/_chunks/{Form-CPYqIWDG.js → Form-CnHfBeiB.js} +39 -21
  21. package/dist/_chunks/Form-CnHfBeiB.js.map +1 -0
  22. package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-CzPCJi3B.mjs} +37 -18
  23. package/dist/_chunks/Form-CzPCJi3B.mjs.map +1 -0
  24. package/dist/_chunks/{History-wrnHqf09.mjs → History-CcmSn3Mj.mjs} +71 -104
  25. package/dist/_chunks/History-CcmSn3Mj.mjs.map +1 -0
  26. package/dist/_chunks/{History-DNQkXANT.js → History-zArjENzj.js} +81 -115
  27. package/dist/_chunks/History-zArjENzj.js.map +1 -0
  28. package/dist/_chunks/{Field-Bfph5SOd.js → Input-CDHKQd7o.js} +1334 -1239
  29. package/dist/_chunks/Input-CDHKQd7o.js.map +1 -0
  30. package/dist/_chunks/{Field-Cs7duwWd.mjs → Input-aV8SSoTa.mjs} +1192 -1097
  31. package/dist/_chunks/Input-aV8SSoTa.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-BPvzENJJ.mjs} +19 -8
  33. package/dist/_chunks/ListConfigurationPage-BPvzENJJ.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-ByZAO_9H.js} +19 -9
  35. package/dist/_chunks/ListConfigurationPage-ByZAO_9H.js.map +1 -0
  36. package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-BVKBeQAA.js} +108 -74
  37. package/dist/_chunks/ListViewPage-BVKBeQAA.js.map +1 -0
  38. package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-HljQVnFH.mjs} +109 -74
  39. package/dist/_chunks/ListViewPage-HljQVnFH.mjs.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-BV5zfDxr.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-BV5zfDxr.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-BfHaSM-K.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-BfHaSM-K.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-D6ze2nQL.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-D6ze2nQL.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-vdNpc6jb.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-vdNpc6jb.js.map} +1 -1
  48. package/dist/_chunks/Preview-DEHdENT1.js +305 -0
  49. package/dist/_chunks/Preview-DEHdENT1.js.map +1 -0
  50. package/dist/_chunks/Preview-vfWOtPG5.mjs +287 -0
  51. package/dist/_chunks/Preview-vfWOtPG5.mjs.map +1 -0
  52. package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-B7_hbF0w.mjs} +79 -44
  53. package/dist/_chunks/Relations-B7_hbF0w.mjs.map +1 -0
  54. package/dist/_chunks/{Relations-CtELXYIK.js → Relations-DcoOBejP.js} +79 -45
  55. package/dist/_chunks/Relations-DcoOBejP.js.map +1 -0
  56. package/dist/_chunks/{en-uOUIxfcQ.js → en-BR48D_RH.js} +35 -15
  57. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BR48D_RH.js.map} +1 -1
  58. package/dist/_chunks/{en-BrCTWlZv.mjs → en-D65uIF6Y.mjs} +35 -15
  59. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-D65uIF6Y.mjs.map} +1 -1
  60. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  61. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  62. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  63. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  64. package/dist/_chunks/{fr-B7kGGg3E.js → fr-C43IbhA_.js} +16 -3
  65. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-C43IbhA_.js.map} +1 -1
  66. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr-DBseuRuB.mjs} +16 -3
  67. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  68. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  69. package/dist/_chunks/{index-OerGjbAN.js → index-CxLSGwnk.js} +1304 -750
  70. package/dist/_chunks/index-CxLSGwnk.js.map +1 -0
  71. package/dist/_chunks/{index-c_5DdJi-.mjs → index-EH8ZtHd5.mjs} +1323 -769
  72. package/dist/_chunks/index-EH8ZtHd5.mjs.map +1 -0
  73. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  74. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  75. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  76. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  77. package/dist/_chunks/{layout-oPBiO7RY.mjs → layout-CxDMdJ13.mjs} +23 -10
  78. package/dist/_chunks/layout-CxDMdJ13.mjs.map +1 -0
  79. package/dist/_chunks/{layout-Ci7qHlFb.js → layout-DSeUTfMv.js} +23 -11
  80. package/dist/_chunks/layout-DSeUTfMv.js.map +1 -0
  81. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  82. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  83. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  84. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  85. package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-B8_Uu38Q.mjs} +21 -8
  86. package/dist/_chunks/relations-B8_Uu38Q.mjs.map +1 -0
  87. package/dist/_chunks/{relations-COBpStiF.js → relations-S5nNKdN3.js} +20 -7
  88. package/dist/_chunks/relations-S5nNKdN3.js.map +1 -0
  89. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  90. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  91. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  92. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  93. package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -1
  94. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -1
  95. package/dist/admin/index.js +3 -1
  96. package/dist/admin/index.js.map +1 -1
  97. package/dist/admin/index.mjs +6 -4
  98. package/dist/admin/src/content-manager.d.ts +3 -2
  99. package/dist/admin/src/exports.d.ts +2 -1
  100. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  101. package/dist/admin/src/hooks/useDocument.d.ts +49 -1
  102. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  103. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  104. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
  105. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  106. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  107. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  108. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  109. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  110. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  111. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  112. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  113. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  114. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  115. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  116. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  117. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  118. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  119. package/dist/admin/src/preview/index.d.ts +4 -0
  120. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  121. package/dist/admin/src/preview/routes.d.ts +3 -0
  122. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  123. package/dist/admin/src/router.d.ts +1 -1
  124. package/dist/admin/src/services/api.d.ts +1 -1
  125. package/dist/admin/src/services/components.d.ts +2 -2
  126. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  127. package/dist/admin/src/services/documents.d.ts +19 -20
  128. package/dist/admin/src/services/init.d.ts +1 -1
  129. package/dist/admin/src/services/relations.d.ts +2 -2
  130. package/dist/admin/src/services/uid.d.ts +3 -3
  131. package/dist/admin/src/utils/validation.d.ts +4 -1
  132. package/dist/server/index.js +727 -406
  133. package/dist/server/index.js.map +1 -1
  134. package/dist/server/index.mjs +728 -406
  135. package/dist/server/index.mjs.map +1 -1
  136. package/dist/server/src/bootstrap.d.ts.map +1 -1
  137. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  138. package/dist/server/src/controllers/index.d.ts.map +1 -1
  139. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  140. package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
  141. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  142. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  143. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  144. package/dist/server/src/history/services/history.d.ts +3 -3
  145. package/dist/server/src/history/services/history.d.ts.map +1 -1
  146. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  147. package/dist/server/src/history/services/utils.d.ts +8 -12
  148. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  149. package/dist/server/src/index.d.ts +7 -6
  150. package/dist/server/src/index.d.ts.map +1 -1
  151. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  152. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  153. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  154. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  155. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  156. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  157. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  158. package/dist/server/src/preview/index.d.ts +4 -0
  159. package/dist/server/src/preview/index.d.ts.map +1 -0
  160. package/dist/server/src/preview/routes/index.d.ts +8 -0
  161. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  162. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  163. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  164. package/dist/server/src/preview/services/index.d.ts +16 -0
  165. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  166. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  167. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  168. package/dist/server/src/preview/services/preview.d.ts +12 -0
  169. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  170. package/dist/server/src/preview/utils.d.ts +19 -0
  171. package/dist/server/src/preview/utils.d.ts.map +1 -0
  172. package/dist/server/src/register.d.ts.map +1 -1
  173. package/dist/server/src/routes/index.d.ts.map +1 -1
  174. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  175. package/dist/server/src/services/document-metadata.d.ts +12 -10
  176. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  177. package/dist/server/src/services/index.d.ts +7 -6
  178. package/dist/server/src/services/index.d.ts.map +1 -1
  179. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  180. package/dist/server/src/services/utils/populate.d.ts +2 -2
  181. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  182. package/dist/server/src/utils/index.d.ts +2 -0
  183. package/dist/server/src/utils/index.d.ts.map +1 -1
  184. package/dist/shared/contracts/collection-types.d.ts +3 -1
  185. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  186. package/dist/shared/contracts/index.d.ts +1 -0
  187. package/dist/shared/contracts/index.d.ts.map +1 -1
  188. package/dist/shared/contracts/preview.d.ts +27 -0
  189. package/dist/shared/contracts/preview.d.ts.map +1 -0
  190. package/dist/shared/index.js +4 -0
  191. package/dist/shared/index.js.map +1 -1
  192. package/dist/shared/index.mjs +4 -0
  193. package/dist/shared/index.mjs.map +1 -1
  194. package/package.json +17 -16
  195. package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +0 -1
  196. package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
  197. package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
  198. package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
  199. package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
  200. package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
  201. package/dist/_chunks/History-DNQkXANT.js.map +0 -1
  202. package/dist/_chunks/History-wrnHqf09.mjs.map +0 -1
  203. package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
  204. package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
  205. package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
  206. package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
  207. package/dist/_chunks/Relations-BZr8tL0R.mjs.map +0 -1
  208. package/dist/_chunks/Relations-CtELXYIK.js.map +0 -1
  209. package/dist/_chunks/index-OerGjbAN.js.map +0 -1
  210. package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
  211. package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
  212. package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
  213. package/dist/_chunks/relations-BIdWFjdq.mjs.map +0 -1
  214. package/dist/_chunks/relations-COBpStiF.js.map +0 -1
  215. package/strapi-server.js +0 -3
@@ -1,25 +1,76 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { useState, useEffect, useCallback, memo } from "react";
4
- import { useStrapiApp, createContext, useField, useNotification, useForm, useAPIErrorHandler, useQueryParams, useFocusInputField, InputRenderer as InputRenderer$1 } from "@strapi/admin/strapi-admin";
5
- import { Box, SingleSelect, SingleSelectOption, Typography, Flex, BaseLink, Button, Popover, Field, Tooltip, IconButton, useComposedRefs, Portal, FocusTrap, Divider, VisuallyHidden, Grid as Grid$1, Accordion, TextButton, BaseButton, TextInput, IconButtonGroup, Menu, MenuItem } from "@strapi/design-system";
6
- import pipe$1 from "lodash/fp/pipe";
4
+ import { useStrapiApp, createContext, useField, useForm, useNotification, useAPIErrorHandler, useQueryParams, useFocusInputField, InputRenderer as InputRenderer$1 } from "@strapi/admin/strapi-admin";
5
+ import { Box, SingleSelect, SingleSelectOption, Typography, Flex, BaseLink, Button, Popover, Field, Tooltip, IconButton, useComposedRefs, Portal, FocusTrap, Divider, VisuallyHidden, Accordion, Menu, MenuItem, Grid as Grid$1, TextInput, IconButtonGroup, TextButton } from "@strapi/design-system";
6
+ import { CodeBlock as CodeBlock$1, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Code, Expand, PlusCircle, Trash, More, EyeStriked, CheckCircle, WarningCircle, Loader, ArrowClockwise, Plus } from "@strapi/icons";
7
7
  import { useIntl } from "react-intl";
8
- import { m as DOCUMENT_META_FIELDS, g as getTranslation, c as useDoc, e as contentManagerApi, d as buildValidParams, f as useDocumentRBAC, n as useDocLayout } from "./index-c_5DdJi-.mjs";
9
- import { generateNKeysBetween } from "fractional-indexing";
10
- import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from "./Relations-BZr8tL0R.mjs";
11
- import { Code, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Expand, PlusCircle, Plus, Trash, EyeStriked, CheckCircle, WarningCircle, Loader, ArrowClockwise, More } from "@strapi/icons";
8
+ import { g as getTranslation, m as useDocLayout, c as useDoc, n as createDefaultForm, t as transformDocument, e as contentManagerApi, o as CLONE_PATH, d as buildValidParams, f as useDocumentRBAC, S as SINGLE_TYPES } from "./index-EH8ZtHd5.mjs";
12
9
  import { styled, css, keyframes } from "styled-components";
13
- import { C as ComponentIcon, a as COMPONENT_ICONS } from "./ComponentIcon-u4bIXTFY.mjs";
14
- import { getEmptyImage } from "react-dnd-html5-backend";
15
- import { a as DIRECTIONS, u as useDragAndDrop, I as ItemTypes } from "./useDragAndDrop-DdHgKsqq.mjs";
16
- import { g as getIn } from "./objects-mKMAmfec.mjs";
17
10
  import { Editor as Editor$1, Transforms, Node, Element, Range, Path, Point, createEditor } from "slate";
18
11
  import { withHistory } from "slate-history";
19
12
  import { useFocused, useSelected, ReactEditor, Editable, useSlate, Slate, withReact } from "slate-react";
13
+ import * as Prism from "prismjs";
14
+ import "prismjs/themes/prism-solarizedlight.css";
15
+ import "prismjs/components/prism-asmatmel";
16
+ import "prismjs/components/prism-bash";
17
+ import "prismjs/components/prism-basic";
18
+ import "prismjs/components/prism-c";
19
+ import "prismjs/components/prism-clojure";
20
+ import "prismjs/components/prism-cobol";
21
+ import "prismjs/components/prism-cpp";
22
+ import "prismjs/components/prism-csharp";
23
+ import "prismjs/components/prism-dart";
24
+ import "prismjs/components/prism-docker";
25
+ import "prismjs/components/prism-elixir";
26
+ import "prismjs/components/prism-erlang";
27
+ import "prismjs/components/prism-fortran";
28
+ import "prismjs/components/prism-fsharp";
29
+ import "prismjs/components/prism-go";
30
+ import "prismjs/components/prism-graphql";
31
+ import "prismjs/components/prism-groovy";
32
+ import "prismjs/components/prism-haskell";
33
+ import "prismjs/components/prism-haxe";
34
+ import "prismjs/components/prism-ini";
35
+ import "prismjs/components/prism-java";
36
+ import "prismjs/components/prism-javascript";
37
+ import "prismjs/components/prism-jsx";
38
+ import "prismjs/components/prism-json";
39
+ import "prismjs/components/prism-julia";
40
+ import "prismjs/components/prism-kotlin";
41
+ import "prismjs/components/prism-latex";
42
+ import "prismjs/components/prism-lua";
43
+ import "prismjs/components/prism-markdown";
44
+ import "prismjs/components/prism-matlab";
45
+ import "prismjs/components/prism-makefile";
46
+ import "prismjs/components/prism-objectivec";
47
+ import "prismjs/components/prism-perl";
48
+ import "prismjs/components/prism-php";
49
+ import "prismjs/components/prism-powershell";
50
+ import "prismjs/components/prism-python";
51
+ import "prismjs/components/prism-r";
52
+ import "prismjs/components/prism-ruby";
53
+ import "prismjs/components/prism-rust";
54
+ import "prismjs/components/prism-sas";
55
+ import "prismjs/components/prism-scala";
56
+ import "prismjs/components/prism-scheme";
57
+ import "prismjs/components/prism-sql";
58
+ import "prismjs/components/prism-stata";
59
+ import "prismjs/components/prism-swift";
60
+ import "prismjs/components/prism-typescript";
61
+ import "prismjs/components/prism-tsx";
62
+ import "prismjs/components/prism-vbnet";
63
+ import "prismjs/components/prism-yaml";
20
64
  import { p as prefixFileUrlWithBackendUrl, u as usePrev } from "./usePrev-DH6iah0A.mjs";
65
+ import { a as DIRECTIONS, u as useDragAndDrop, I as ItemTypes } from "./useDragAndDrop-DJ6jqvZN.mjs";
21
66
  import * as Toolbar from "@radix-ui/react-toolbar";
22
- import { useLocation } from "react-router-dom";
67
+ import { getEmptyImage } from "react-dnd-html5-backend";
68
+ import { useMatch, useLocation } from "react-router-dom";
69
+ import { g as getIn } from "./objects-D6yBsdmx.mjs";
70
+ import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from "./Relations-B7_hbF0w.mjs";
71
+ import pipe$1 from "lodash/fp/pipe";
72
+ import { C as ComponentIcon, a as COMPONENT_ICONS } from "./ComponentIcon-u4bIXTFY.mjs";
73
+ import { a as useDebounce } from "./relations-B8_Uu38Q.mjs";
23
74
  import CodeMirror from "codemirror5";
24
75
  import sanitizeHtml from "sanitize-html";
25
76
  import { getLanguage, highlight, highlightAuto } from "highlight.js";
@@ -35,93 +86,6 @@ import sub from "markdown-it-sub";
35
86
  import sup from "markdown-it-sup";
36
87
  import "highlight.js/styles/solarized-dark.css";
37
88
  import "codemirror5/addon/display/placeholder";
38
- const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
39
- const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
40
- const traverse = (datum, attributes) => {
41
- return Object.entries(datum).reduce((acc, [key, value]) => {
42
- const attribute = attributes[key];
43
- if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
44
- acc[key] = value;
45
- return acc;
46
- }
47
- if (attribute.type === "component") {
48
- if (attribute.repeatable) {
49
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
50
- acc[key] = componentValue.map(
51
- (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
52
- );
53
- } else {
54
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
55
- acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
56
- }
57
- } else if (attribute.type === "dynamiczone") {
58
- const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
59
- acc[key] = dynamicZoneValue.map(
60
- (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
61
- );
62
- } else if (predicate(attribute, value)) {
63
- acc[key] = transform(value, attribute);
64
- } else {
65
- acc[key] = value;
66
- }
67
- return acc;
68
- }, {});
69
- };
70
- return traverse(data, schema.attributes);
71
- };
72
- const removeProhibitedFields = (prohibitedFields) => traverseData(
73
- (attribute) => prohibitedFields.includes(attribute.type),
74
- () => ""
75
- );
76
- const prepareRelations = traverseData(
77
- (attribute) => attribute.type === "relation",
78
- () => ({
79
- connect: [],
80
- disconnect: []
81
- })
82
- );
83
- const prepareTempKeys = traverseData(
84
- (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
85
- (data) => {
86
- if (Array.isArray(data) && data.length > 0) {
87
- const keys = generateNKeysBetween(void 0, void 0, data.length);
88
- return data.map((datum, index) => ({
89
- ...datum,
90
- __temp_key__: keys[index]
91
- }));
92
- }
93
- return data;
94
- }
95
- );
96
- const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
97
- const schemaKeys = Object.keys(schema.attributes);
98
- const dataKeys = Object.keys(data);
99
- const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
100
- const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
101
- delete acc[key];
102
- return acc;
103
- }, structuredClone(data));
104
- return revisedData;
105
- };
106
- const removeNullValues = (data) => {
107
- return Object.entries(data).reduce((acc, [key, value]) => {
108
- if (value === null) {
109
- return acc;
110
- }
111
- acc[key] = value;
112
- return acc;
113
- }, {});
114
- };
115
- const transformDocument = (schema, components = {}) => (document2) => {
116
- const transformations = pipe$1(
117
- removeFieldsThatDontExistOnSchema(schema),
118
- removeProhibitedFields(["password"])(schema, components),
119
- removeNullValues,
120
- prepareRelations(schema, components),
121
- prepareTempKeys(schema, components)
122
- );
123
- return transformations(document2);
124
- };
125
89
  const componentStore = /* @__PURE__ */ new Map();
126
90
  const useLazyComponents = (componentUids = []) => {
127
91
  const [lazyComponentStore, setLazyComponentStore] = useState(Object.fromEntries(componentStore));
@@ -163,7 +127,8 @@ const useLazyComponents = (componentUids = []) => {
163
127
  const codeLanguages = [
164
128
  {
165
129
  value: "asm",
166
- label: "Assembly"
130
+ label: "Assembly",
131
+ decorate: "asmatmel"
167
132
  },
168
133
  {
169
134
  value: "bash",
@@ -199,7 +164,8 @@ const codeLanguages = [
199
164
  },
200
165
  {
201
166
  value: "dockerfile",
202
- label: "Dockerfile"
167
+ label: "Dockerfile",
168
+ decorate: "docker"
203
169
  },
204
170
  {
205
171
  value: "elixir",
@@ -355,7 +321,8 @@ const codeLanguages = [
355
321
  },
356
322
  {
357
323
  value: "typescript",
358
- label: "TypeScript"
324
+ label: "TypeScript",
325
+ decorate: "ts"
359
326
  },
360
327
  {
361
328
  value: "tsx",
@@ -371,7 +338,8 @@ const codeLanguages = [
371
338
  },
372
339
  {
373
340
  value: "yaml",
374
- label: "YAML"
341
+ label: "YAML",
342
+ decorate: "yml"
375
343
  }
376
344
  ];
377
345
  const baseHandleConvert = (editor, attributesToSet) => {
@@ -437,6 +405,29 @@ const pressEnterTwiceToExit = (editor) => {
437
405
  });
438
406
  }
439
407
  };
408
+ const decorateCode = ([node, path]) => {
409
+ const ranges = [];
410
+ if (!Element.isElement(node) || node.type !== "code") return ranges;
411
+ const text = Node.string(node);
412
+ const language = codeLanguages.find((lang) => lang.value === node.language);
413
+ const decorateKey = language?.decorate ?? language?.value;
414
+ const selectedLanguage = Prism.languages[decorateKey || "plaintext"];
415
+ const tokens = Prism.tokenize(text, selectedLanguage);
416
+ let start = 0;
417
+ for (const token of tokens) {
418
+ const length = token.length;
419
+ const end = start + length;
420
+ if (typeof token !== "string") {
421
+ ranges.push({
422
+ anchor: { path, offset: start },
423
+ focus: { path, offset: end },
424
+ className: `token ${token.type}`
425
+ });
426
+ }
427
+ start = end;
428
+ }
429
+ return ranges;
430
+ };
440
431
  const CodeBlock = styled.pre`
441
432
  border-radius: ${({ theme }) => theme.borderRadius};
442
433
  background-color: ${({ theme }) => theme.colors.neutral100};
@@ -508,7 +499,7 @@ const CodeEditor = (props) => {
508
499
  const codeBlocks = {
509
500
  code: {
510
501
  renderElement: (props) => /* @__PURE__ */ jsx(CodeEditor, { ...props }),
511
- icon: Code,
502
+ icon: CodeBlock$1,
512
503
  label: {
513
504
  id: "components.Blocks.blocks.code",
514
505
  defaultMessage: "Code block"
@@ -521,8 +512,7 @@ const codeBlocks = {
521
512
  handleEnterKey(editor) {
522
513
  pressEnterTwiceToExit(editor);
523
514
  },
524
- snippets: ["```"],
525
- dragHandleTopMargin: "10px"
515
+ snippets: ["```"]
526
516
  }
527
517
  };
528
518
  const H1 = styled(Typography).attrs({ tag: "h1" })`
@@ -697,8 +687,7 @@ const ImageDialog = () => {
697
687
  const [isOpen, setIsOpen] = React.useState(true);
698
688
  const { editor } = useBlocksEditorContext("ImageDialog");
699
689
  const components = useStrapiApp("ImageDialog", (state) => state.components);
700
- if (!components || !isOpen)
701
- return null;
690
+ if (!components || !isOpen) return null;
702
691
  const MediaLibraryDialog = components["media-library"];
703
692
  const insertImages = (images) => {
704
693
  Transforms.unwrapNodes(editor, {
@@ -707,14 +696,12 @@ const ImageDialog = () => {
707
696
  });
708
697
  const nodeEntryBeingReplaced = Editor$1.above(editor, {
709
698
  match(node) {
710
- if (Editor$1.isEditor(node))
711
- return false;
699
+ if (Editor$1.isEditor(node)) return false;
712
700
  const isInlineNode = ["text", "link"].includes(node.type);
713
701
  return !isInlineNode;
714
702
  }
715
703
  });
716
- if (!nodeEntryBeingReplaced)
717
- return;
704
+ if (!nodeEntryBeingReplaced) return;
718
705
  const [, pathToInsert] = nodeEntryBeingReplaced;
719
706
  Transforms.removeNodes(editor);
720
707
  const nodesToInsert = images.map((image) => {
@@ -892,8 +879,7 @@ const LinkContent = React.forwardRef(
892
879
  ReactEditor.focus(editor);
893
880
  };
894
881
  React.useEffect(() => {
895
- if (popoverOpen)
896
- linkInputRef.current?.focus();
882
+ if (popoverOpen) linkInputRef.current?.focus();
897
883
  }, [popoverOpen]);
898
884
  const inputNotDirty = !linkText || !linkUrl || link.url && link.url === linkUrl && elementText && elementText === linkText;
899
885
  return /* @__PURE__ */ jsxs(Popover.Root, { open: popoverOpen, children: [
@@ -963,11 +949,11 @@ const LinkContent = React.forwardRef(
963
949
  ),
964
950
  /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
965
951
  /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: handleClose, children: formatMessage({
966
- id: "components.Blocks.popover.cancel",
952
+ id: "global.cancel",
967
953
  defaultMessage: "Cancel"
968
954
  }) }),
969
955
  /* @__PURE__ */ jsx(Button, { disabled: Boolean(inputNotDirty) || isSaveDisabled, onClick: handleSave, children: formatMessage({
970
- id: "components.Blocks.popover.save",
956
+ id: "global.save",
971
957
  defaultMessage: "Save"
972
958
  }) })
973
959
  ] })
@@ -1048,8 +1034,7 @@ const isText$1 = (node) => {
1048
1034
  return Node.isNode(node) && !Editor$1.isEditor(node) && node.type === "text";
1049
1035
  };
1050
1036
  const handleBackspaceKeyOnList = (editor, event) => {
1051
- if (!editor.selection)
1052
- return;
1037
+ if (!editor.selection) return;
1053
1038
  const [currentListItem, currentListItemPath] = Editor$1.parent(editor, editor.selection.anchor);
1054
1039
  const [currentList, currentListPath] = Editor$1.parent(editor, currentListItemPath);
1055
1040
  const isListEmpty = currentList.children.length === 1 && isText$1(currentListItem.children[0]) && currentListItem.children[0].text === "";
@@ -1158,8 +1143,7 @@ const handleEnterKeyOnList = (editor) => {
1158
1143
  };
1159
1144
  const handleConvertToList = (editor, format) => {
1160
1145
  const convertedPath = baseHandleConvert(editor, { type: "list-item" });
1161
- if (!convertedPath)
1162
- return;
1146
+ if (!convertedPath) return;
1163
1147
  Transforms.wrapNodes(editor, { type: "list", format, children: [] }, { at: convertedPath });
1164
1148
  };
1165
1149
  const handleTabOnList = (editor) => {
@@ -1171,8 +1155,7 @@ const handleTabOnList = (editor) => {
1171
1155
  }
1172
1156
  const [currentListItem, currentListItemPath] = currentListItemEntry;
1173
1157
  const [currentList] = Editor$1.parent(editor, currentListItemPath);
1174
- if (currentListItem === currentList.children[0])
1175
- return;
1158
+ if (currentListItem === currentList.children[0]) return;
1176
1159
  const currentListItemIndex = currentList.children.findIndex((item) => item === currentListItem);
1177
1160
  const previousNode = currentList.children[currentListItemIndex - 1];
1178
1161
  if (previousNode.type === "list") {
@@ -1308,13 +1291,13 @@ const quoteBlocks = {
1308
1291
  handleEnterKey(editor) {
1309
1292
  pressEnterTwiceToExit(editor);
1310
1293
  },
1311
- snippets: [">"],
1312
- dragHandleTopMargin: "6px"
1294
+ snippets: [">"]
1313
1295
  }
1314
1296
  };
1315
1297
  const ToolbarWrapper = styled(Flex)`
1316
1298
  &[aria-disabled='true'] {
1317
1299
  cursor: not-allowed;
1300
+ background: ${({ theme }) => theme.colors.neutral150};
1318
1301
  }
1319
1302
  `;
1320
1303
  const Separator = styled(Toolbar.Separator)`
@@ -1325,7 +1308,7 @@ const Separator = styled(Toolbar.Separator)`
1325
1308
  const FlexButton = styled(Flex)`
1326
1309
  // Inherit the not-allowed cursor from ToolbarWrapper when disabled
1327
1310
  &[aria-disabled] {
1328
- cursor: inherit;
1311
+ cursor: not-allowed;
1329
1312
  }
1330
1313
 
1331
1314
  &[aria-disabled='false'] {
@@ -1407,7 +1390,7 @@ const ToolbarButton = ({
1407
1390
  width: 7,
1408
1391
  height: 7,
1409
1392
  hasRadius: true,
1410
- children: /* @__PURE__ */ jsx(Icon, { width: "1.2rem", height: "1.2rem", fill: disabled ? "neutral300" : enabledColor })
1393
+ children: /* @__PURE__ */ jsx(Icon, { fill: disabled ? "neutral300" : enabledColor })
1411
1394
  }
1412
1395
  )
1413
1396
  }
@@ -1539,8 +1522,7 @@ const isListNode = (node) => {
1539
1522
  const ListButton = ({ block, format }) => {
1540
1523
  const { editor, disabled, blocks } = useBlocksEditorContext("ListButton");
1541
1524
  const isListActive = () => {
1542
- if (!editor.selection)
1543
- return false;
1525
+ if (!editor.selection) return false;
1544
1526
  const currentListEntry = Editor$1.above(editor, {
1545
1527
  match: (node) => !Editor$1.isEditor(node) && node.type === "list",
1546
1528
  at: editor.selection.anchor
@@ -1614,8 +1596,7 @@ const LinkButton = ({ disabled }) => {
1614
1596
  const { editor } = useBlocksEditorContext("LinkButton");
1615
1597
  const isLinkActive = () => {
1616
1598
  const { selection } = editor;
1617
- if (!selection)
1618
- return false;
1599
+ if (!selection) return false;
1619
1600
  const [match] = Array.from(
1620
1601
  Editor$1.nodes(editor, {
1621
1602
  at: Editor$1.unhangRange(editor, selection),
@@ -1679,7 +1660,7 @@ const BlocksToolbar = () => {
1679
1660
  return false;
1680
1661
  };
1681
1662
  const isButtonDisabled = checkButtonDisabled();
1682
- return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, children: [
1663
+ return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, width: "100%", children: [
1683
1664
  /* @__PURE__ */ jsx(BlocksDropdown, {}),
1684
1665
  /* @__PURE__ */ jsx(Separator, {}),
1685
1666
  /* @__PURE__ */ jsx(Toolbar.ToggleGroup, { type: "multiple", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
@@ -1749,33 +1730,36 @@ const DragItem = styled(Flex)`
1749
1730
  }
1750
1731
  `;
1751
1732
  const DragIconButton = styled(IconButton)`
1733
+ user-select: none;
1752
1734
  display: flex;
1753
1735
  align-items: center;
1754
1736
  justify-content: center;
1737
+ border: none;
1755
1738
  border-radius: ${({ theme }) => theme.borderRadius};
1756
- width: ${({ theme }) => theme.spaces[4]};
1757
- height: ${({ theme }) => theme.spaces[6]};
1739
+ padding-left: ${({ theme }) => theme.spaces[0]};
1740
+ padding-right: ${({ theme }) => theme.spaces[0]};
1741
+ padding-top: ${({ theme }) => theme.spaces[1]};
1742
+ padding-bottom: ${({ theme }) => theme.spaces[1]};
1758
1743
  visibility: hidden;
1759
1744
  cursor: grab;
1760
1745
  opacity: inherit;
1761
1746
  margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};
1762
1747
 
1763
1748
  &:hover {
1764
- background: ${({ theme }) => theme.colors.neutral200};
1749
+ background: ${({ theme }) => theme.colors.neutral100};
1765
1750
  }
1766
1751
  &:active {
1767
1752
  cursor: grabbing;
1753
+ background: ${({ theme }) => theme.colors.neutral150};
1768
1754
  }
1769
1755
  &[aria-disabled='true'] {
1770
- cursor: not-allowed;
1771
- background: transparent;
1756
+ visibility: hidden;
1772
1757
  }
1773
1758
  svg {
1774
- height: auto;
1775
1759
  min-width: ${({ theme }) => theme.spaces[3]};
1776
1760
 
1777
1761
  path {
1778
- fill: ${({ theme }) => theme.colors.neutral700};
1762
+ fill: ${({ theme }) => theme.colors.neutral500};
1779
1763
  }
1780
1764
  }
1781
1765
  `;
@@ -1820,8 +1804,7 @@ const DragAndDropElement = ({
1820
1804
  displayedValue: children
1821
1805
  },
1822
1806
  onDropItem(currentIndex, newIndex) {
1823
- if (newIndex)
1824
- handleMoveBlock(newIndex, currentIndex);
1807
+ if (newIndex) handleMoveBlock(newIndex, currentIndex);
1825
1808
  }
1826
1809
  });
1827
1810
  const composedBoxRefs = useComposedRefs(blockRef, dropRef);
@@ -1877,6 +1860,7 @@ const DragAndDropElement = ({
1877
1860
  DragIconButton,
1878
1861
  {
1879
1862
  tag: "div",
1863
+ contentEditable: false,
1880
1864
  role: "button",
1881
1865
  tabIndex: 0,
1882
1866
  withTooltip: false,
@@ -1926,7 +1910,7 @@ const baseRenderLeaf = (props, modifiers2) => {
1926
1910
  }
1927
1911
  return currentChildren;
1928
1912
  }, props.children);
1929
- return /* @__PURE__ */ jsx("span", { ...props.attributes, children: wrappedChildren });
1913
+ return /* @__PURE__ */ jsx("span", { ...props.attributes, className: props.leaf.className, children: wrappedChildren });
1930
1914
  };
1931
1915
  const baseRenderElement = ({
1932
1916
  props,
@@ -1964,8 +1948,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1964
1948
  [modifiers2]
1965
1949
  );
1966
1950
  const handleMoveBlocks = (editor2, event) => {
1967
- if (!editor2.selection)
1968
- return;
1951
+ if (!editor2.selection) return;
1969
1952
  const start = Range.start(editor2.selection);
1970
1953
  const currentIndex = [start.path[0]];
1971
1954
  let newIndexPosition = 0;
@@ -2102,8 +2085,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2102
2085
  }
2103
2086
  };
2104
2087
  const handleScrollSelectionIntoView = () => {
2105
- if (!editor.selection)
2106
- return;
2088
+ if (!editor.selection) return;
2107
2089
  const domRange = ReactEditor.toDOMRange(editor, editor.selection);
2108
2090
  const domRect = domRange.getBoundingClientRect();
2109
2091
  const blocksInput = blocksRef.current;
@@ -2130,7 +2112,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2130
2112
  background: "neutral0",
2131
2113
  color: "neutral800",
2132
2114
  lineHeight: 6,
2133
- paddingRight: 4,
2115
+ paddingRight: 7,
2134
2116
  paddingTop: 6,
2135
2117
  paddingBottom: 3,
2136
2118
  children: [
@@ -2141,6 +2123,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2141
2123
  readOnly: disabled,
2142
2124
  placeholder,
2143
2125
  isExpandedMode,
2126
+ decorate: decorateCode,
2144
2127
  renderElement,
2145
2128
  renderLeaf,
2146
2129
  onKeyDown: handleKeyDown,
@@ -2297,8 +2280,7 @@ const InlineCode = styled.code`
2297
2280
  `;
2298
2281
  const baseCheckIsActive = (editor, name2) => {
2299
2282
  const marks = Editor$1.marks(editor);
2300
- if (!marks)
2301
- return false;
2283
+ if (!marks) return false;
2302
2284
  return Boolean(marks[name2]);
2303
2285
  };
2304
2286
  const baseHandleToggle = (editor, name2) => {
@@ -2464,6 +2446,7 @@ const ExpandIconButton = styled(IconButton)`
2464
2446
  position: absolute;
2465
2447
  bottom: 1.2rem;
2466
2448
  right: 1.2rem;
2449
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2467
2450
  `;
2468
2451
  function useResetKey(value) {
2469
2452
  const slateUpdatesCount = React.useRef(0);
@@ -2595,26 +2578,6 @@ const BlocksInput = React.forwardRef(
2595
2578
  }
2596
2579
  );
2597
2580
  const MemoizedBlocksInput = React.memo(BlocksInput);
2598
- const createDefaultForm = (contentType, components = {}) => {
2599
- const traverseSchema = (attributes) => {
2600
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2601
- if ("default" in attribute) {
2602
- acc[key] = attribute.default;
2603
- } else if (attribute.type === "component" && attribute.required) {
2604
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2605
- if (attribute.repeatable) {
2606
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2607
- } else {
2608
- acc[key] = defaultComponentForm;
2609
- }
2610
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2611
- acc[key] = [];
2612
- }
2613
- return acc;
2614
- }, {});
2615
- };
2616
- return traverseSchema(contentType.attributes);
2617
- };
2618
2581
  const Initializer = ({ disabled, name: name2, onClick }) => {
2619
2582
  const { formatMessage } = useIntl();
2620
2583
  const field = useField(name2);
@@ -2622,7 +2585,7 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2622
2585
  Box,
2623
2586
  {
2624
2587
  tag: "button",
2625
- background: "neutral100",
2588
+ background: disabled ? "neutral150" : "neutral100",
2626
2589
  borderColor: field.error ? "danger600" : "neutral200",
2627
2590
  hasRadius: true,
2628
2591
  disabled,
@@ -2630,109 +2593,470 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2630
2593
  paddingTop: 9,
2631
2594
  paddingBottom: 9,
2632
2595
  type: "button",
2596
+ style: { cursor: disabled ? "not-allowed" : "pointer" },
2633
2597
  children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2634
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(CircleIcon, {}) }),
2635
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { textColor: "primary600", variant: "pi", fontWeight: "bold", children: formatMessage({
2636
- id: getTranslation("components.empty-repeatable"),
2637
- defaultMessage: "No entry yet. Click on the button below to add one."
2638
- }) }) })
2598
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", color: disabled ? "neutral500" : "primary600", children: /* @__PURE__ */ jsx(PlusCircle, { width: "3.2rem", height: "3.2rem" }) }),
2599
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2600
+ Typography,
2601
+ {
2602
+ textColor: disabled ? "neutral600" : "primary600",
2603
+ variant: "pi",
2604
+ fontWeight: "bold",
2605
+ children: formatMessage({
2606
+ id: getTranslation("components.empty-repeatable"),
2607
+ defaultMessage: "No entry yet. Click to add one."
2608
+ })
2609
+ }
2610
+ ) })
2639
2611
  ] })
2640
2612
  }
2641
2613
  ) });
2642
2614
  };
2643
- const CircleIcon = styled(PlusCircle)`
2644
- width: 2.4rem;
2645
- height: 2.4rem;
2615
+ const AddComponentButton = ({
2616
+ hasError,
2617
+ isDisabled,
2618
+ isOpen,
2619
+ children,
2620
+ onClick
2621
+ }) => {
2622
+ return /* @__PURE__ */ jsx(
2623
+ StyledButton,
2624
+ {
2625
+ type: "button",
2626
+ onClick,
2627
+ disabled: isDisabled,
2628
+ background: "neutral0",
2629
+ style: { cursor: isDisabled ? "not-allowed" : "pointer" },
2630
+ variant: "tertiary",
2631
+ children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
2632
+ /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
2633
+ /* @__PURE__ */ jsx(
2634
+ Typography,
2635
+ {
2636
+ variant: "pi",
2637
+ fontWeight: "bold",
2638
+ textColor: hasError && !isOpen ? "danger600" : "neutral600",
2639
+ children
2640
+ }
2641
+ )
2642
+ ] })
2643
+ }
2644
+ );
2645
+ };
2646
+ const StyledAddIcon = styled(PlusCircle)`
2647
+ height: ${({ theme }) => theme.spaces[6]};
2648
+ width: ${({ theme }) => theme.spaces[6]};
2649
+ transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
2650
+
2646
2651
  > circle {
2647
- fill: ${({ theme }) => theme.colors.primary200};
2652
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2648
2653
  }
2649
2654
  > path {
2650
- fill: ${({ theme }) => theme.colors.primary600};
2655
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
2651
2656
  }
2652
2657
  `;
2653
- const NonRepeatableComponent = ({
2654
- attribute,
2655
- name: name2,
2656
- children,
2657
- layout
2658
+ const StyledButton = styled(Button)`
2659
+ padding-left: ${({ theme }) => theme.spaces[3]};
2660
+ border-radius: 26px;
2661
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2662
+ height: 5rem;
2663
+ `;
2664
+ const ComponentCategory = ({
2665
+ category,
2666
+ components = [],
2667
+ variant = "primary",
2668
+ onAddComponent
2658
2669
  }) => {
2659
- const { value } = useField(name2);
2660
- const level = useComponent("NonRepeatableComponent", (state) => state.level);
2661
- const isNested = level > 0;
2662
- return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
2670
+ const { formatMessage } = useIntl();
2671
+ return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
2672
+ /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
2673
+ /* @__PURE__ */ jsx(ResponsiveAccordionContent, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
2674
+ ComponentBox,
2675
+ {
2676
+ tag: "button",
2677
+ type: "button",
2678
+ background: "neutral100",
2679
+ justifyContent: "center",
2680
+ onClick: onAddComponent(uid),
2681
+ hasRadius: true,
2682
+ height: "8.4rem",
2683
+ shrink: 0,
2684
+ borderColor: "neutral200",
2685
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
2686
+ /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
2687
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
2688
+ ] })
2689
+ },
2690
+ uid
2691
+ )) }) })
2692
+ ] });
2693
+ };
2694
+ const ResponsiveAccordionContent = styled(Accordion.Content)`
2695
+ container-type: inline-size;
2696
+ `;
2697
+ const Grid = styled(Box)`
2698
+ display: grid;
2699
+ grid-template-columns: repeat(auto-fill, 100%);
2700
+ grid-gap: ${({ theme }) => theme.spaces[1]};
2701
+
2702
+ @container (min-width: ${() => RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
2703
+ grid-template-columns: repeat(auto-fill, 14rem);
2704
+ }
2705
+ `;
2706
+ const ComponentBox = styled(Flex)`
2707
+ color: ${({ theme }) => theme.colors.neutral600};
2708
+ cursor: pointer;
2709
+
2710
+ @media (prefers-reduced-motion: no-preference) {
2711
+ transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2712
+ }
2713
+
2714
+ &:focus,
2715
+ &:hover {
2716
+ border: 1px solid ${({ theme }) => theme.colors.primary200};
2717
+ background: ${({ theme }) => theme.colors.primary100};
2718
+ color: ${({ theme }) => theme.colors.primary600};
2719
+ }
2720
+ `;
2721
+ const ComponentPicker = ({
2722
+ dynamicComponentsByCategory = {},
2723
+ isOpen,
2724
+ onClickAddComponent
2725
+ }) => {
2726
+ const { formatMessage } = useIntl();
2727
+ const handleAddComponentToDz = (componentUid) => () => {
2728
+ onClickAddComponent(componentUid);
2729
+ };
2730
+ if (!isOpen) {
2731
+ return null;
2732
+ }
2733
+ return /* @__PURE__ */ jsxs(
2663
2734
  Box,
2664
2735
  {
2665
- background: "neutral100",
2666
- paddingLeft: 6,
2667
- paddingRight: 6,
2668
2736
  paddingTop: 6,
2669
2737
  paddingBottom: 6,
2670
- hasRadius: isNested,
2671
- borderColor: isNested ? "neutral200" : void 0,
2672
- children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
2673
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2674
- const completeFieldName = `${name2}.${field.name}`;
2675
- return /* @__PURE__ */ jsx(Grid$1.Item, { col: size, s: 12, xs: 12, children: children({ ...field, name: completeFieldName }) }, completeFieldName);
2676
- }) }, index);
2677
- }) })
2738
+ paddingLeft: 5,
2739
+ paddingRight: 5,
2740
+ background: "neutral0",
2741
+ shadow: "tableShadow",
2742
+ borderColor: "neutral150",
2743
+ hasRadius: true,
2744
+ children: [
2745
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
2746
+ id: getTranslation("components.DynamicZone.ComponentPicker-label"),
2747
+ defaultMessage: "Pick one component"
2748
+ }) }) }),
2749
+ /* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(Accordion.Root, { defaultValue: Object.keys(dynamicComponentsByCategory)[0], children: Object.entries(dynamicComponentsByCategory).map(([category, components], index) => /* @__PURE__ */ jsx(
2750
+ ComponentCategory,
2751
+ {
2752
+ category,
2753
+ components,
2754
+ onAddComponent: handleAddComponentToDz,
2755
+ variant: index % 2 === 1 ? "primary" : "secondary"
2756
+ },
2757
+ category
2758
+ )) }) })
2759
+ ]
2678
2760
  }
2679
- ) });
2761
+ );
2680
2762
  };
2681
- const RepeatableComponent = ({
2682
- attribute,
2763
+ const DynamicComponent = ({
2764
+ componentUid,
2683
2765
  disabled,
2766
+ index,
2684
2767
  name: name2,
2685
- mainField,
2686
- children,
2687
- layout
2768
+ onRemoveComponentClick,
2769
+ onMoveComponent,
2770
+ onGrabItem,
2771
+ onDropItem,
2772
+ onCancel,
2773
+ dynamicComponentsByCategory = {},
2774
+ onAddComponent,
2775
+ children
2688
2776
  }) => {
2689
- const { toggleNotification } = useNotification();
2690
2777
  const { formatMessage } = useIntl();
2691
- const { search: searchString } = useLocation();
2692
- const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
2693
- const { components } = useDoc();
2694
- const { value = [], error } = useField(name2);
2695
- const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
2696
- const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
2697
- const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
2698
- const { max = Infinity } = attribute;
2699
- const [collapseToOpen, setCollapseToOpen] = React.useState("");
2700
- const [liveText, setLiveText] = React.useState("");
2701
- const componentTmpKeyWithFocussedField = React.useMemo(() => {
2702
- if (search.has("field")) {
2703
- const fieldParam = search.get("field");
2704
- if (!fieldParam) {
2705
- return void 0;
2706
- }
2707
- const [, path] = fieldParam.split(`${name2}.`);
2708
- if (getIn(value, path, void 0) !== void 0) {
2709
- const [subpath] = path.split(".");
2710
- return getIn(value, subpath, void 0)?.__temp_key__;
2711
- }
2712
- }
2713
- return void 0;
2714
- }, [search, name2, value]);
2715
- const prevValue = usePrev(value);
2716
- React.useEffect(() => {
2717
- if (prevValue && prevValue.length < value.length) {
2718
- setCollapseToOpen(value[value.length - 1].__temp_key__);
2719
- }
2720
- }, [value, prevValue]);
2778
+ const formValues = useForm("DynamicComponent", (state) => state.values);
2779
+ const {
2780
+ edit: { components }
2781
+ } = useDocLayout();
2782
+ const title = React.useMemo(() => {
2783
+ const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
2784
+ const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
2785
+ const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
2786
+ const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
2787
+ return mainValue;
2788
+ }, [componentUid, components, formValues, name2, index]);
2789
+ const { icon, displayName } = React.useMemo(() => {
2790
+ const [category] = componentUid.split(".");
2791
+ const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
2792
+ (component) => component.uid === componentUid
2793
+ ) ?? { icon: null, displayName: null };
2794
+ return { icon: icon2, displayName: displayName2 };
2795
+ }, [componentUid, dynamicComponentsByCategory]);
2796
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2797
+ type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
2798
+ index,
2799
+ item: {
2800
+ index,
2801
+ displayedValue: `${displayName} ${title}`,
2802
+ icon
2803
+ },
2804
+ onMoveItem: onMoveComponent,
2805
+ onDropItem,
2806
+ onGrabItem,
2807
+ onCancel
2808
+ });
2721
2809
  React.useEffect(() => {
2722
- if (typeof componentTmpKeyWithFocussedField === "string") {
2723
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2810
+ dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2811
+ }, [dragPreviewRef, index]);
2812
+ const accordionValue = React.useId();
2813
+ const { value = [], rawError } = useField(`${name2}.${index}`);
2814
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
2815
+ React.useEffect(() => {
2816
+ if (rawError && value) {
2817
+ setCollapseToOpen(accordionValue);
2724
2818
  }
2725
- }, [componentTmpKeyWithFocussedField]);
2726
- const toggleCollapses = () => {
2727
- setCollapseToOpen("");
2819
+ }, [rawError, value, accordionValue]);
2820
+ const composedBoxRefs = useComposedRefs(boxRef, dropRef);
2821
+ const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
2822
+ /* @__PURE__ */ jsx(
2823
+ IconButton,
2824
+ {
2825
+ variant: "ghost",
2826
+ label: formatMessage(
2827
+ {
2828
+ id: getTranslation("components.DynamicZone.delete-label"),
2829
+ defaultMessage: "Delete {name}"
2830
+ },
2831
+ { name: title }
2832
+ ),
2833
+ onClick: onRemoveComponentClick,
2834
+ children: /* @__PURE__ */ jsx(Trash, {})
2835
+ }
2836
+ ),
2837
+ /* @__PURE__ */ jsx(
2838
+ IconButton,
2839
+ {
2840
+ variant: "ghost",
2841
+ onClick: (e) => e.stopPropagation(),
2842
+ "data-handler-id": handlerId,
2843
+ ref: dragRef,
2844
+ label: formatMessage({
2845
+ id: getTranslation("components.DragHandle-label"),
2846
+ defaultMessage: "Drag"
2847
+ }),
2848
+ onKeyDown: handleKeyDown,
2849
+ children: /* @__PURE__ */ jsx(Drag, {})
2850
+ }
2851
+ ),
2852
+ /* @__PURE__ */ jsxs(Menu.Root, { children: [
2853
+ /* @__PURE__ */ jsx(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 0, paddingRight: 0, children: /* @__PURE__ */ jsx(
2854
+ IconButton,
2855
+ {
2856
+ variant: "ghost",
2857
+ label: formatMessage({
2858
+ id: getTranslation("components.DynamicZone.more-actions"),
2859
+ defaultMessage: "More actions"
2860
+ }),
2861
+ tag: "span",
2862
+ children: /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false })
2863
+ }
2864
+ ) }),
2865
+ /* @__PURE__ */ jsxs(Menu.Content, { children: [
2866
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2867
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2868
+ id: getTranslation("components.DynamicZone.add-item-above"),
2869
+ defaultMessage: "Add component above"
2870
+ }) }),
2871
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2872
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2873
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
2874
+ ] }, category)) })
2875
+ ] }),
2876
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2877
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2878
+ id: getTranslation("components.DynamicZone.add-item-below"),
2879
+ defaultMessage: "Add component below"
2880
+ }) }),
2881
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2882
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2883
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
2884
+ ] }, category)) })
2885
+ ] })
2886
+ ] })
2887
+ ] })
2888
+ ] });
2889
+ const accordionTitle = title ? `${displayName} ${title}` : displayName;
2890
+ return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
2891
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
2892
+ /* @__PURE__ */ jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsx(Accordion.Root, { value: collapseToOpen, onValueChange: setCollapseToOpen, children: /* @__PURE__ */ jsxs(Accordion.Item, { value: accordionValue, children: [
2893
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
2894
+ /* @__PURE__ */ jsx(
2895
+ Accordion.Trigger,
2896
+ {
2897
+ icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
2898
+ children: accordionTitle
2899
+ }
2900
+ ),
2901
+ /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
2902
+ ] }),
2903
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsx(Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsx(
2904
+ Grid$1.Item,
2905
+ {
2906
+ col: 12,
2907
+ s: 12,
2908
+ xs: 12,
2909
+ direction: "column",
2910
+ alignItems: "stretch",
2911
+ children: /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
2912
+ const fieldName = `${name2}.${index}.${field.name}`;
2913
+ const fieldWithTranslatedLabel = {
2914
+ ...field,
2915
+ label: formatMessage({
2916
+ id: `content-manager.components.${componentUid}.${field.name}`,
2917
+ defaultMessage: field.label
2918
+ })
2919
+ };
2920
+ return /* @__PURE__ */ jsx(
2921
+ ResponsiveGridItem,
2922
+ {
2923
+ col: size,
2924
+ s: 12,
2925
+ xs: 12,
2926
+ direction: "column",
2927
+ alignItems: "stretch",
2928
+ children: children ? children({ ...fieldWithTranslatedLabel, name: fieldName }) : /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
2929
+ },
2930
+ fieldName
2931
+ );
2932
+ }) })
2933
+ },
2934
+ rowInd
2935
+ )) }) }) }) })
2936
+ ] }) }) })
2937
+ ] });
2938
+ };
2939
+ const StyledBox = styled(Box)`
2940
+ > div:first-child {
2941
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
2942
+ }
2943
+ `;
2944
+ const AccordionContentRadius = styled(Box)`
2945
+ border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
2946
+ `;
2947
+ const Rectangle = styled(Box)`
2948
+ width: ${({ theme }) => theme.spaces[2]};
2949
+ height: ${({ theme }) => theme.spaces[4]};
2950
+ `;
2951
+ const Preview$1 = styled.span`
2952
+ display: block;
2953
+ background-color: ${({ theme }) => theme.colors.primary100};
2954
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2955
+ outline-offset: -1px;
2956
+ padding: ${({ theme }) => theme.spaces[6]};
2957
+ `;
2958
+ const ComponentContainer = styled(Box)`
2959
+ list-style: none;
2960
+ padding: 0;
2961
+ margin: 0;
2962
+ `;
2963
+ const DynamicZoneLabel = ({
2964
+ hint,
2965
+ label,
2966
+ labelAction,
2967
+ name: name2,
2968
+ numberOfComponents = 0,
2969
+ required
2970
+ }) => {
2971
+ return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2972
+ Box,
2973
+ {
2974
+ paddingTop: 3,
2975
+ paddingBottom: 3,
2976
+ paddingRight: 4,
2977
+ paddingLeft: 4,
2978
+ borderRadius: "26px",
2979
+ background: "neutral0",
2980
+ shadow: "filterShadow",
2981
+ color: "neutral500",
2982
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
2983
+ /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
2984
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
2985
+ label || name2,
2986
+ " "
2987
+ ] }),
2988
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
2989
+ "(",
2990
+ numberOfComponents,
2991
+ ")"
2992
+ ] }),
2993
+ required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
2994
+ labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
2995
+ ] }),
2996
+ hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
2997
+ ] })
2998
+ }
2999
+ ) });
3000
+ };
3001
+ const [DynamicZoneProvider, useDynamicZone] = createContext(
3002
+ "DynamicZone",
3003
+ {
3004
+ isInDynamicZone: false
3005
+ }
3006
+ );
3007
+ const DynamicZone = ({
3008
+ attribute,
3009
+ disabled: disabledProp,
3010
+ hint,
3011
+ label,
3012
+ labelAction,
3013
+ name: name2,
3014
+ required = false,
3015
+ children
3016
+ }) => {
3017
+ const { max = Infinity, min = -Infinity } = attribute ?? {};
3018
+ const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
3019
+ const [liveText, setLiveText] = React.useState("");
3020
+ const { components, isLoading } = useDoc();
3021
+ const disabled = disabledProp || isLoading;
3022
+ const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
3023
+ "DynamicZone",
3024
+ ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
3025
+ addFieldRow: addFieldRow2,
3026
+ removeFieldRow: removeFieldRow2,
3027
+ moveFieldRow: moveFieldRow2
3028
+ })
3029
+ );
3030
+ const { value = [], error } = useField(name2);
3031
+ const dynamicComponentsByCategory = React.useMemo(() => {
3032
+ return attribute.components.reduce((acc, componentUid) => {
3033
+ const { category, info } = components[componentUid] ?? { info: {} };
3034
+ const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
3035
+ if (!acc[category]) {
3036
+ acc[category] = [];
3037
+ }
3038
+ acc[category] = [...acc[category], component];
3039
+ return acc;
3040
+ }, {});
3041
+ }, [attribute.components, components]);
3042
+ const { formatMessage } = useIntl();
3043
+ const { toggleNotification } = useNotification();
3044
+ const dynamicDisplayedComponentsLength = value.length;
3045
+ const handleAddComponent = (uid, position) => {
3046
+ setAddComponentIsOpen(false);
3047
+ const schema = components[uid];
3048
+ const form = createDefaultForm(schema, components);
3049
+ const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
3050
+ ...data2,
3051
+ __component: uid
3052
+ }));
3053
+ const data = transformations(form);
3054
+ addFieldRow(name2, data, position);
2728
3055
  };
2729
- const handleClick = () => {
2730
- if (value.length < max) {
2731
- const schema = components[attribute.component];
2732
- const form = createDefaultForm(schema, components);
2733
- const data = transformDocument(schema, components)(form);
2734
- addFieldRow(name2, data);
2735
- } else if (value.length >= max) {
3056
+ const handleClickOpenPicker = () => {
3057
+ if (dynamicDisplayedComponentsLength < max) {
3058
+ setAddComponentIsOpen((prev) => !prev);
3059
+ } else {
2736
3060
  toggleNotification({
2737
3061
  type: "info",
2738
3062
  message: formatMessage({
@@ -2741,7 +3065,7 @@ const RepeatableComponent = ({
2741
3065
  });
2742
3066
  }
2743
3067
  };
2744
- const handleMoveComponentField = (newIndex, currentIndex) => {
3068
+ const handleMoveComponent = (newIndex, currentIndex) => {
2745
3069
  setLiveText(
2746
3070
  formatMessage(
2747
3071
  {
@@ -2756,9 +3080,6 @@ const RepeatableComponent = ({
2756
3080
  );
2757
3081
  moveFieldRow(name2, currentIndex, newIndex);
2758
3082
  };
2759
- const handleValueChange = (key) => {
2760
- setCollapseToOpen(key);
2761
- };
2762
3083
  const getItemPos = (index) => `${index + 1} of ${value.length}`;
2763
3084
  const handleCancel = (index) => {
2764
3085
  setLiveText(
@@ -2801,425 +3122,115 @@ const RepeatableComponent = ({
2801
3122
  )
2802
3123
  );
2803
3124
  };
3125
+ const handleRemoveComponent = (name22, currentIndex) => () => {
3126
+ removeFieldRow(name22, currentIndex);
3127
+ };
3128
+ const hasError = error !== void 0;
3129
+ const renderButtonLabel = () => {
3130
+ if (addComponentIsOpen) {
3131
+ return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
3132
+ }
3133
+ if (hasError && dynamicDisplayedComponentsLength > max) {
3134
+ return formatMessage(
3135
+ {
3136
+ id: getTranslation(`components.DynamicZone.extra-components`),
3137
+ defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
3138
+ },
3139
+ {
3140
+ number: dynamicDisplayedComponentsLength - max
3141
+ }
3142
+ );
3143
+ }
3144
+ if (hasError && dynamicDisplayedComponentsLength < min) {
3145
+ return formatMessage(
3146
+ {
3147
+ id: getTranslation(`components.DynamicZone.missing-components`),
3148
+ defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
3149
+ },
3150
+ { number: min - dynamicDisplayedComponentsLength }
3151
+ );
3152
+ }
3153
+ return formatMessage(
3154
+ {
3155
+ id: getTranslation("components.DynamicZone.add-component"),
3156
+ defaultMessage: "Add a component to {componentName}"
3157
+ },
3158
+ { componentName: label || name2 }
3159
+ );
3160
+ };
3161
+ const level = useComponent("DynamicZone", (state) => state.level);
2804
3162
  const ariaDescriptionId = React.useId();
2805
- const level = useComponent("RepeatableComponent", (state) => state.level);
2806
- if (value.length === 0) {
2807
- return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2808
- }
2809
- return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
2810
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2811
- id: getTranslation("dnd.instructions"),
2812
- defaultMessage: `Press spacebar to grab and re-order`
2813
- }) }),
2814
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2815
- /* @__PURE__ */ jsxs(
2816
- AccordionRoot,
3163
+ return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
3164
+ dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
3165
+ /* @__PURE__ */ jsx(
3166
+ DynamicZoneLabel,
3167
+ {
3168
+ hint,
3169
+ label,
3170
+ labelAction,
3171
+ name: name2,
3172
+ numberOfComponents: dynamicDisplayedComponentsLength,
3173
+ required
3174
+ }
3175
+ ),
3176
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
3177
+ id: getTranslation("dnd.instructions"),
3178
+ defaultMessage: `Press spacebar to grab and re-order`
3179
+ }) }),
3180
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
3181
+ /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
3182
+ ComponentProvider,
3183
+ {
3184
+ level: level + 1,
3185
+ uid: field.__component,
3186
+ id: field.id,
3187
+ type: "dynamiczone",
3188
+ children: /* @__PURE__ */ jsx(
3189
+ DynamicComponent,
3190
+ {
3191
+ disabled,
3192
+ name: name2,
3193
+ index,
3194
+ componentUid: field.__component,
3195
+ onMoveComponent: handleMoveComponent,
3196
+ onRemoveComponentClick: handleRemoveComponent(name2, index),
3197
+ onCancel: handleCancel,
3198
+ onDropItem: handleDropItem,
3199
+ onGrabItem: handleGrabItem,
3200
+ onAddComponent: handleAddComponent,
3201
+ dynamicComponentsByCategory,
3202
+ children
3203
+ }
3204
+ )
3205
+ },
3206
+ field.__temp_key__
3207
+ )) })
3208
+ ] }),
3209
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
3210
+ AddComponentButton,
2817
3211
  {
2818
- $error: error,
2819
- value: collapseToOpen,
2820
- onValueChange: handleValueChange,
2821
- "aria-describedby": ariaDescriptionId,
2822
- children: [
2823
- value.map(({ __temp_key__: key, id }, index) => {
2824
- const nameWithIndex = `${name2}.${index}`;
2825
- return /* @__PURE__ */ jsx(
2826
- ComponentProvider,
2827
- {
2828
- id,
2829
- uid: attribute.component,
2830
- level: level + 1,
2831
- type: "repeatable",
2832
- children: /* @__PURE__ */ jsx(
2833
- Component,
2834
- {
2835
- disabled,
2836
- name: nameWithIndex,
2837
- attribute,
2838
- index,
2839
- mainField,
2840
- onMoveItem: handleMoveComponentField,
2841
- onDeleteComponent: () => {
2842
- removeFieldRow(name2, index);
2843
- toggleCollapses();
2844
- },
2845
- toggleCollapses,
2846
- onCancel: handleCancel,
2847
- onDropItem: handleDropItem,
2848
- onGrabItem: handleGrabItem,
2849
- __temp_key__: key,
2850
- children: layout.map((row, index2) => {
2851
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2852
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2853
- return /* @__PURE__ */ jsx(Grid$1.Item, { col: size, s: 12, xs: 12, children: children({ ...field, name: completeFieldName }) }, completeFieldName);
2854
- }) }, index2);
2855
- })
2856
- }
2857
- )
2858
- },
2859
- key
2860
- );
2861
- }),
2862
- /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
2863
- id: getTranslation("containers.EditView.add.new-entry"),
2864
- defaultMessage: "Add an entry"
2865
- }) })
2866
- ]
3212
+ hasError,
3213
+ isDisabled: disabled,
3214
+ isOpen: addComponentIsOpen,
3215
+ onClick: handleClickOpenPicker,
3216
+ children: renderButtonLabel()
3217
+ }
3218
+ ) }),
3219
+ /* @__PURE__ */ jsx(
3220
+ ComponentPicker,
3221
+ {
3222
+ dynamicComponentsByCategory,
3223
+ isOpen: addComponentIsOpen,
3224
+ onClickAddComponent: handleAddComponent
2867
3225
  }
2868
3226
  )
2869
- ] });
3227
+ ] }) });
2870
3228
  };
2871
- const AccordionRoot = styled(Accordion.Root)`
2872
- border: 1px solid
2873
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
2874
- `;
2875
- const TextButtonCustom = styled(TextButton)`
2876
- width: 100%;
2877
- display: flex;
2878
- justify-content: center;
2879
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
2880
- padding-inline: ${(props) => props.theme.spaces[6]};
2881
- padding-block: ${(props) => props.theme.spaces[3]};
2882
-
2883
- &:not([disabled]) {
2884
- cursor: pointer;
2885
-
2886
- &:hover {
2887
- background-color: ${(props) => props.theme.colors.primary100};
2888
- }
2889
- }
2890
-
2891
- span {
2892
- font-weight: 600;
2893
- font-size: 1.4rem;
2894
- line-height: 2.4rem;
2895
- }
2896
-
2897
- @media (prefers-reduced-motion: no-preference) {
2898
- transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2899
- }
2900
- `;
2901
- const Component = ({
2902
- disabled,
2903
- index,
2904
- name: name2,
2905
- mainField = {
2906
- name: "id",
2907
- type: "integer"
2908
- },
2909
- children,
2910
- onDeleteComponent,
2911
- toggleCollapses,
2912
- __temp_key__,
2913
- ...dragProps
2914
- }) => {
3229
+ const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
2915
3230
  const { formatMessage } = useIntl();
2916
- const displayValue = useForm("RepeatableComponent", (state) => {
2917
- return getIn(state.values, [...name2.split("."), mainField.name]);
2918
- });
2919
- const accordionRef = React.useRef(null);
2920
- const componentKey = name2.split(".").slice(0, -1).join(".");
2921
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2922
- type: `${ItemTypes.COMPONENT}_${componentKey}`,
2923
- index,
2924
- item: {
2925
- index,
2926
- displayedValue: displayValue
2927
- },
2928
- onStart() {
2929
- toggleCollapses();
2930
- },
2931
- ...dragProps
2932
- });
2933
- React.useEffect(() => {
2934
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2935
- }, [dragPreviewRef, index]);
2936
- const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
2937
- const composedBoxRefs = useComposedRefs(
2938
- boxRef,
2939
- dropRef
2940
- );
2941
- return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
2942
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
2943
- /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
2944
- /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
2945
- /* @__PURE__ */ jsx(
2946
- IconButton,
2947
- {
2948
- borderWidth: 0,
2949
- onClick: onDeleteComponent,
2950
- label: formatMessage({
2951
- id: getTranslation("containers.Edit.delete"),
2952
- defaultMessage: "Delete"
2953
- }),
2954
- children: /* @__PURE__ */ jsx(Trash, {})
2955
- }
2956
- ),
2957
- /* @__PURE__ */ jsx(
2958
- IconButton,
2959
- {
2960
- ref: composedAccordionRefs,
2961
- borderWidth: 0,
2962
- onClick: (e) => e.stopPropagation(),
2963
- "data-handler-id": handlerId,
2964
- label: formatMessage({
2965
- id: getTranslation("components.DragHandle-label"),
2966
- defaultMessage: "Drag"
2967
- }),
2968
- onKeyDown: handleKeyDown,
2969
- children: /* @__PURE__ */ jsx(Drag, {})
2970
- }
2971
- )
2972
- ] })
2973
- ] }),
2974
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
2975
- Flex,
2976
- {
2977
- direction: "column",
2978
- alignItems: "stretch",
2979
- background: "neutral100",
2980
- padding: 6,
2981
- gap: 6,
2982
- children
2983
- }
2984
- ) })
2985
- ] }) });
2986
- };
2987
- const Preview$1 = () => {
2988
- return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
2989
- };
2990
- const StyledSpan = styled(Box)`
2991
- display: block;
2992
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2993
- outline-offset: -1px;
2994
- `;
2995
- const ComponentInput = ({
2996
- label,
2997
- required,
2998
- name: name2,
2999
- attribute,
3000
- disabled,
3001
- labelAction,
3002
- ...props
3003
- }) => {
3004
- const { formatMessage } = useIntl();
3005
- const field = useField(name2);
3006
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
3007
- const { components } = useDoc();
3008
- const handleInitialisationClick = () => {
3009
- const schema = components[attribute.component];
3010
- const form = createDefaultForm(schema, components);
3011
- const data = transformDocument(schema, components)(form);
3012
- field.onChange(name2, data);
3013
- };
3014
- return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
3015
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3016
- /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
3017
- label,
3018
- attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
3019
- " (",
3020
- Array.isArray(field.value) ? field.value.length : 0,
3021
- ")"
3022
- ] })
3023
- ] }),
3024
- showResetComponent && /* @__PURE__ */ jsx(
3025
- IconButton,
3026
- {
3027
- label: formatMessage({
3028
- id: getTranslation("components.reset-entry"),
3029
- defaultMessage: "Reset Entry"
3030
- }),
3031
- borderWidth: 0,
3032
- onClick: () => {
3033
- field.onChange(name2, null);
3034
- },
3035
- children: /* @__PURE__ */ jsx(Trash, {})
3036
- }
3037
- )
3038
- ] }),
3039
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
3040
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
3041
- attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
3042
- /* @__PURE__ */ jsx(Field.Error, {})
3043
- ] });
3044
- };
3045
- const MemoizedComponentInput = React.memo(ComponentInput);
3046
- const AddComponentButton = ({
3047
- hasError,
3048
- isDisabled,
3049
- isOpen,
3050
- children,
3051
- onClick
3052
- }) => {
3053
- return /* @__PURE__ */ jsx(
3054
- StyledButton,
3055
- {
3056
- type: "button",
3057
- onClick,
3058
- disabled: isDisabled,
3059
- background: "neutral0",
3060
- paddingTop: 3,
3061
- paddingBottom: 3,
3062
- paddingLeft: 4,
3063
- paddingRight: 4,
3064
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
3065
- children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
3066
- /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
3067
- /* @__PURE__ */ jsx(
3068
- AddComponentTitle,
3069
- {
3070
- variant: "pi",
3071
- fontWeight: "bold",
3072
- textColor: hasError && !isOpen ? "danger600" : "neutral500",
3073
- children
3074
- }
3075
- )
3076
- ] })
3077
- }
3078
- );
3079
- };
3080
- const StyledAddIcon = styled(PlusCircle)`
3081
- height: ${({ theme }) => theme.spaces[6]};
3082
- width: ${({ theme }) => theme.spaces[6]};
3083
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
3084
-
3085
- > circle {
3086
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
3087
- }
3088
- > path {
3089
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral600};
3090
- }
3091
- `;
3092
- const AddComponentTitle = styled(Typography)``;
3093
- const StyledButton = styled(BaseButton)`
3094
- border-radius: 26px;
3095
- border-color: ${({ theme }) => theme.colors.neutral150};
3096
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
3097
-
3098
- &:hover {
3099
- ${AddComponentTitle} {
3100
- color: ${({ theme }) => theme.colors.primary600};
3101
- }
3102
-
3103
- ${StyledAddIcon} {
3104
- > circle {
3105
- fill: ${({ theme }) => theme.colors.primary600};
3106
- }
3107
- > path {
3108
- fill: ${({ theme }) => theme.colors.neutral100};
3109
- }
3110
- }
3111
- }
3112
- &:active {
3113
- ${AddComponentTitle} {
3114
- color: ${({ theme }) => theme.colors.primary600};
3115
- }
3116
- ${StyledAddIcon} {
3117
- > circle {
3118
- fill: ${({ theme }) => theme.colors.primary600};
3119
- }
3120
- > path {
3121
- fill: ${({ theme }) => theme.colors.neutral100};
3122
- }
3123
- }
3124
- }
3125
- `;
3126
- const ComponentCategory = ({
3127
- category,
3128
- components = [],
3129
- variant = "primary",
3130
- onAddComponent
3131
- }) => {
3132
- const { formatMessage } = useIntl();
3133
- return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
3134
- /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
3135
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
3136
- ComponentBox,
3137
- {
3138
- tag: "button",
3139
- type: "button",
3140
- background: "neutral100",
3141
- justifyContent: "center",
3142
- onClick: onAddComponent(uid),
3143
- hasRadius: true,
3144
- height: "8.4rem",
3145
- shrink: 0,
3146
- borderColor: "neutral200",
3147
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
3148
- /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
3149
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
3150
- ] })
3151
- },
3152
- uid
3153
- )) }) })
3154
- ] });
3155
- };
3156
- const Grid = styled(Box)`
3157
- display: grid;
3158
- grid-template-columns: repeat(auto-fit, 14rem);
3159
- grid-gap: ${({ theme }) => theme.spaces[1]};
3160
- `;
3161
- const ComponentBox = styled(Flex)`
3162
- color: ${({ theme }) => theme.colors.neutral600};
3163
- cursor: pointer;
3164
-
3165
- @media (prefers-reduced-motion: no-preference) {
3166
- transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3167
- }
3168
-
3169
- &:focus,
3170
- &:hover {
3171
- border: 1px solid ${({ theme }) => theme.colors.primary200};
3172
- background: ${({ theme }) => theme.colors.primary100};
3173
- color: ${({ theme }) => theme.colors.primary600};
3174
- }
3175
- `;
3176
- const ComponentPicker = ({
3177
- dynamicComponentsByCategory = {},
3178
- isOpen,
3179
- onClickAddComponent
3180
- }) => {
3181
- const { formatMessage } = useIntl();
3182
- const handleAddComponentToDz = (componentUid) => () => {
3183
- onClickAddComponent(componentUid);
3184
- };
3185
- if (!isOpen) {
3186
- return null;
3187
- }
3188
- return /* @__PURE__ */ jsxs(
3189
- Box,
3190
- {
3191
- paddingTop: 6,
3192
- paddingBottom: 6,
3193
- paddingLeft: 5,
3194
- paddingRight: 5,
3195
- background: "neutral0",
3196
- shadow: "tableShadow",
3197
- borderColor: "neutral150",
3198
- hasRadius: true,
3199
- children: [
3200
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
3201
- id: getTranslation("components.DynamicZone.ComponentPicker-label"),
3202
- defaultMessage: "Pick one component"
3203
- }) }) }),
3204
- /* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(Accordion.Root, { defaultValue: Object.keys(dynamicComponentsByCategory)[0], children: Object.entries(dynamicComponentsByCategory).map(([category, components], index) => /* @__PURE__ */ jsx(
3205
- ComponentCategory,
3206
- {
3207
- category,
3208
- components,
3209
- onAddComponent: handleAddComponentToDz,
3210
- variant: index % 2 === 1 ? "primary" : "secondary"
3211
- },
3212
- category
3213
- )) }) })
3214
- ]
3215
- }
3216
- );
3217
- };
3218
- const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3219
- const { formatMessage } = useIntl();
3220
- const placeholder = formatMessage({
3221
- id: "components.NotAllowedInput.text",
3222
- defaultMessage: "No permissions to see this field"
3231
+ const placeholder = formatMessage({
3232
+ id: "components.NotAllowedInput.text",
3233
+ defaultMessage: "No permissions to see this field"
3223
3234
  });
3224
3235
  return /* @__PURE__ */ jsxs(Field.Root, { id: name2, hint, name: name2, required, children: [
3225
3236
  /* @__PURE__ */ jsx(Field.Label, { children: label }),
@@ -3236,18 +3247,6 @@ const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3236
3247
  /* @__PURE__ */ jsx(Field.Hint, {})
3237
3248
  ] });
3238
3249
  };
3239
- function useDebounce(value, delay) {
3240
- const [debouncedValue, setDebouncedValue] = useState(value);
3241
- useEffect(() => {
3242
- const handler = setTimeout(() => {
3243
- setDebouncedValue(value);
3244
- }, delay);
3245
- return () => {
3246
- clearTimeout(handler);
3247
- };
3248
- }, [value, delay]);
3249
- return debouncedValue;
3250
- }
3251
3250
  const uidApi = contentManagerApi.injectEndpoints({
3252
3251
  endpoints: (builder) => ({
3253
3252
  getDefaultUID: builder.query({
@@ -3282,7 +3281,10 @@ const uidApi = contentManagerApi.injectEndpoints({
3282
3281
  config: {
3283
3282
  params
3284
3283
  }
3285
- })
3284
+ }),
3285
+ providesTags: (_res, _error, params) => [
3286
+ { type: "UidAvailability", id: params.contentTypeUID }
3287
+ ]
3286
3288
  })
3287
3289
  })
3288
3290
  });
@@ -3294,8 +3296,10 @@ const UIDInput = React.forwardRef(
3294
3296
  const allFormValues = useForm("InputUID", (form) => form.values);
3295
3297
  const [availability, setAvailability] = React.useState();
3296
3298
  const [showRegenerate, setShowRegenerate] = React.useState(false);
3299
+ const isCloning = useMatch(CLONE_PATH) !== null;
3297
3300
  const field = useField(name2);
3298
3301
  const debouncedValue = useDebounce(field.value, 300);
3302
+ const hasChanged = debouncedValue !== field.initialValue;
3299
3303
  const { toggleNotification } = useNotification();
3300
3304
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
3301
3305
  const { formatMessage } = useIntl();
@@ -3371,8 +3375,9 @@ const UIDInput = React.forwardRef(
3371
3375
  params
3372
3376
  },
3373
3377
  {
3378
+ // Don't check availability if the value is empty or wasn't changed
3374
3379
  skip: !Boolean(
3375
- debouncedValue !== field.initialValue && debouncedValue && UID_REGEX.test(debouncedValue.trim())
3380
+ (hasChanged || isCloning) && debouncedValue && UID_REGEX.test(debouncedValue.trim())
3376
3381
  )
3377
3382
  }
3378
3383
  );
@@ -3401,6 +3406,7 @@ const UIDInput = React.forwardRef(
3401
3406
  const isLoading = isGeneratingDefaultUID || isGeneratingUID || isCheckingAvailability;
3402
3407
  const fieldRef = useFocusInputField(name2);
3403
3408
  const composedRefs = useComposedRefs(ref, fieldRef);
3409
+ const shouldShowAvailability = (hasChanged || isCloning) && debouncedValue != null && availability && !showRegenerate;
3404
3410
  return /* @__PURE__ */ jsxs(Field.Root, { hint, name: name2, error: field.error, required, children: [
3405
3411
  /* @__PURE__ */ jsx(Field.Label, { action: labelAction, children: label }),
3406
3412
  /* @__PURE__ */ jsx(
@@ -3409,7 +3415,7 @@ const UIDInput = React.forwardRef(
3409
3415
  ref: composedRefs,
3410
3416
  disabled: props.disabled,
3411
3417
  endAction: /* @__PURE__ */ jsxs(Flex, { position: "relative", gap: 1, children: [
3412
- availability && !showRegenerate && /* @__PURE__ */ jsxs(
3418
+ shouldShowAvailability && /* @__PURE__ */ jsxs(
3413
3419
  TextValidation,
3414
3420
  {
3415
3421
  alignItems: "center",
@@ -3698,8 +3704,7 @@ const Wrapper = styled.div`
3698
3704
  `;
3699
3705
  var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, unorderedListRE = /[*+-]\s/;
3700
3706
  function newlineAndIndentContinueMarkdownList(cm) {
3701
- if (cm.getOption("disableInput"))
3702
- return CodeMirror.Pass;
3707
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
3703
3708
  var ranges = cm.listSelections(), replacements = [];
3704
3709
  for (var i = 0; i < ranges.length; i++) {
3705
3710
  var pos = ranges[i].head;
@@ -3733,8 +3738,7 @@ function newlineAndIndentContinueMarkdownList(cm) {
3733
3738
  var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
3734
3739
  var bullet = numbered ? parseInt(match[3], 10) + 1 + match[4] : match[2].replace("x", " ");
3735
3740
  replacements[i] = "\n" + indent + bullet + after;
3736
- if (numbered)
3737
- incrementRemainingMarkdownListNumbers(cm, pos);
3741
+ if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
3738
3742
  }
3739
3743
  }
3740
3744
  cm.replaceSelections(replacements);
@@ -3752,10 +3756,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3752
3756
  var newNumber = parseInt(startItem[3], 10) + lookAhead - skipCount;
3753
3757
  var nextNumber = parseInt(nextItem[3], 10), itemNumber = nextNumber;
3754
3758
  if (startIndent === nextIndent && !isNaN(nextNumber)) {
3755
- if (newNumber === nextNumber)
3756
- itemNumber = nextNumber + 1;
3757
- if (newNumber > nextNumber)
3758
- itemNumber = newNumber + 1;
3759
+ if (newNumber === nextNumber) itemNumber = nextNumber + 1;
3760
+ if (newNumber > nextNumber) itemNumber = newNumber + 1;
3759
3761
  cm.replaceRange(
3760
3762
  nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
3761
3763
  {
@@ -3768,10 +3770,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3768
3770
  }
3769
3771
  );
3770
3772
  } else {
3771
- if (startIndent.length > nextIndent.length)
3772
- return;
3773
- if (startIndent.length < nextIndent.length && lookAhead === 1)
3774
- return;
3773
+ if (startIndent.length > nextIndent.length) return;
3774
+ if (startIndent.length < nextIndent.length && lookAhead === 1) return;
3775
3775
  skipCount += 1;
3776
3776
  }
3777
3777
  }
@@ -4243,7 +4243,7 @@ const EditorLayout = ({
4243
4243
  justifyContent: "flex-end",
4244
4244
  shrink: 0,
4245
4245
  width: "100%",
4246
- children: /* @__PURE__ */ jsxs(ExpandButton$1, { onClick: onCollapse, children: [
4246
+ children: /* @__PURE__ */ jsxs(ExpandButton$1, { onClick: onCollapse, variant: "tertiary", size: "M", children: [
4247
4247
  /* @__PURE__ */ jsx(Typography, { children: formatMessage({
4248
4248
  id: "components.Wysiwyg.collapse",
4249
4249
  defaultMessage: "Collapse"
@@ -4261,12 +4261,14 @@ const EditorLayout = ({
4261
4261
  ) }) });
4262
4262
  }
4263
4263
  return /* @__PURE__ */ jsx(
4264
- Box,
4264
+ Flex,
4265
4265
  {
4266
4266
  borderColor: error ? "danger600" : "neutral200",
4267
4267
  borderStyle: "solid",
4268
4268
  borderWidth: "1px",
4269
4269
  hasRadius: true,
4270
+ direction: "column",
4271
+ alignItems: "stretch",
4270
4272
  children
4271
4273
  }
4272
4274
  );
@@ -4277,11 +4279,19 @@ const ExpandWrapper = styled(Flex)`
4277
4279
  const BoxWithBorder = styled(Box)`
4278
4280
  border-right: 1px solid ${({ theme }) => theme.colors.neutral200};
4279
4281
  `;
4280
- const ExpandButton$1 = styled(BaseButton)`
4282
+ const ExpandButton$1 = styled(Button)`
4281
4283
  background-color: transparent;
4282
4284
  border: none;
4283
4285
  align-items: center;
4284
4286
 
4287
+ & > span {
4288
+ display: flex;
4289
+ justify-content: space-between;
4290
+ align-items: center;
4291
+ width: 100%;
4292
+ font-weight: ${({ theme }) => theme.fontWeights.regular};
4293
+ }
4294
+
4285
4295
  svg {
4286
4296
  margin-left: ${({ theme }) => `${theme.spaces[2]}`};
4287
4297
 
@@ -4548,41 +4558,29 @@ const quoteAndCodeHandler = (editor, markdownType) => {
4548
4558
  insertWithoutTextToEdit(editor, markdownType, line, contentLength);
4549
4559
  }
4550
4560
  };
4551
- const CustomIconButton = styled(IconButton)`
4552
- padding: ${({ theme }) => theme.spaces[2]};
4553
-
4554
- svg {
4555
- width: 1.8rem;
4556
- height: 1.8rem;
4557
- }
4558
- `;
4559
- const CustomLinkIconButton = styled(CustomIconButton)`
4560
- svg {
4561
- width: 0.8rem;
4562
- height: 0.8rem;
4563
- }
4564
- `;
4565
4561
  const MainButtons = styled(IconButtonGroup)`
4566
4562
  margin-left: ${({ theme }) => theme.spaces[4]};
4567
4563
  `;
4568
4564
  const MoreButton = styled(IconButton)`
4569
4565
  margin: ${({ theme }) => `0 ${theme.spaces[2]}`};
4570
- padding: ${({ theme }) => theme.spaces[2]};
4571
-
4572
- svg {
4573
- width: 1.8rem;
4574
- height: 1.8rem;
4575
- }
4576
4566
  `;
4577
4567
  const IconButtonGroupMargin = styled(IconButtonGroup)`
4578
4568
  margin-right: ${({ theme }) => `${theme.spaces[2]}`};
4579
4569
  `;
4580
- const ExpandButton = styled(BaseButton)`
4570
+ const ExpandButton = styled(Button)`
4581
4571
  background-color: transparent;
4582
4572
  border: none;
4583
4573
  align-items: center;
4584
4574
 
4585
- svg {
4575
+ & > span {
4576
+ display: flex;
4577
+ justify-content: space-between;
4578
+ align-items: center;
4579
+ width: 100%;
4580
+ font-weight: ${({ theme }) => theme.fontWeights.regular};
4581
+ }
4582
+
4583
+ svg {
4586
4584
  margin-left: ${({ theme }) => `${theme.spaces[2]}`};
4587
4585
  path {
4588
4586
  fill: ${({ theme }) => theme.colors.neutral700};
@@ -4593,7 +4591,7 @@ const ExpandButton = styled(BaseButton)`
4593
4591
  `;
4594
4592
  const WysiwygFooter = ({ onToggleExpand }) => {
4595
4593
  const { formatMessage } = useIntl();
4596
- return /* @__PURE__ */ jsx(Box, { padding: 2, background: "neutral100", borderRadius: `0 0 0.4rem 0.4rem`, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", alignItems: "flex-end", children: /* @__PURE__ */ jsxs(ExpandButton, { id: "expand", onClick: onToggleExpand, children: [
4594
+ return /* @__PURE__ */ jsx(Box, { padding: 2, background: "neutral100", borderRadius: `0 0 0.4rem 0.4rem`, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", alignItems: "flex-end", children: /* @__PURE__ */ jsxs(ExpandButton, { id: "expand", onClick: onToggleExpand, variant: "tertiary", size: "M", children: [
4597
4595
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", children: formatMessage({
4598
4596
  id: "components.WysiwygBottomControls.fullscreen",
4599
4597
  defaultMessage: "Expand"
@@ -4630,18 +4628,27 @@ const WysiwygNav = ({
4630
4628
  borderRadius: `0.4rem 0.4rem 0 0`,
4631
4629
  children: [
4632
4630
  /* @__PURE__ */ jsxs(Flex, { children: [
4633
- /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsxs(SingleSelect, { disabled: true, placeholder: selectPlaceholder, "aria-label": selectPlaceholder, children: [
4634
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4635
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4636
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4637
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4638
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4639
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4640
- ] }) }),
4631
+ /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsxs(
4632
+ SingleSelect,
4633
+ {
4634
+ disabled: true,
4635
+ placeholder: selectPlaceholder,
4636
+ "aria-label": selectPlaceholder,
4637
+ size: "S",
4638
+ children: [
4639
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4640
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4641
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4642
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4643
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4644
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4645
+ ]
4646
+ }
4647
+ ) }),
4641
4648
  /* @__PURE__ */ jsxs(MainButtons, { children: [
4642
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Bold", name: "Bold", children: /* @__PURE__ */ jsx(Bold, {}) }),
4643
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Italic", name: "Italic", children: /* @__PURE__ */ jsx(Italic, {}) }),
4644
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Underline", name: "Underline", children: /* @__PURE__ */ jsx(Underline, {}) })
4649
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Bold", name: "Bold", children: /* @__PURE__ */ jsx(Bold, {}) }),
4650
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Italic", name: "Italic", children: /* @__PURE__ */ jsx(Italic, {}) }),
4651
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Underline", name: "Underline", children: /* @__PURE__ */ jsx(Underline, {}) })
4645
4652
  ] }),
4646
4653
  /* @__PURE__ */ jsx(MoreButton, { disabled: true, label: "More", children: /* @__PURE__ */ jsx(More, {}) })
4647
4654
  ] }),
@@ -4668,6 +4675,7 @@ const WysiwygNav = ({
4668
4675
  placeholder: selectPlaceholder,
4669
4676
  "aria-label": selectPlaceholder,
4670
4677
  onChange: (value) => onActionClick(value, editorRef),
4678
+ size: "S",
4671
4679
  children: [
4672
4680
  /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4673
4681
  /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
@@ -4679,17 +4687,9 @@ const WysiwygNav = ({
4679
4687
  }
4680
4688
  ) }),
4681
4689
  /* @__PURE__ */ jsxs(MainButtons, { children: [
4690
+ /* @__PURE__ */ jsx(IconButton, { onClick: () => onActionClick("Bold", editorRef), label: "Bold", name: "Bold", children: /* @__PURE__ */ jsx(Bold, {}) }),
4682
4691
  /* @__PURE__ */ jsx(
4683
- CustomIconButton,
4684
- {
4685
- onClick: () => onActionClick("Bold", editorRef),
4686
- label: "Bold",
4687
- name: "Bold",
4688
- children: /* @__PURE__ */ jsx(Bold, {})
4689
- }
4690
- ),
4691
- /* @__PURE__ */ jsx(
4692
- CustomIconButton,
4692
+ IconButton,
4693
4693
  {
4694
4694
  onClick: () => onActionClick("Italic", editorRef),
4695
4695
  label: "Italic",
@@ -4698,7 +4698,7 @@ const WysiwygNav = ({
4698
4698
  }
4699
4699
  ),
4700
4700
  /* @__PURE__ */ jsx(
4701
- CustomIconButton,
4701
+ IconButton,
4702
4702
  {
4703
4703
  onClick: () => onActionClick("Underline", editorRef),
4704
4704
  label: "Underline",
@@ -4712,7 +4712,7 @@ const WysiwygNav = ({
4712
4712
  /* @__PURE__ */ jsx(Popover.Content, { sideOffset: 12, children: /* @__PURE__ */ jsxs(Flex, { padding: 2, children: [
4713
4713
  /* @__PURE__ */ jsxs(IconButtonGroupMargin, { children: [
4714
4714
  /* @__PURE__ */ jsx(
4715
- CustomIconButton,
4715
+ IconButton,
4716
4716
  {
4717
4717
  onClick: () => onActionClick("Strikethrough", editorRef, handleTogglePopover),
4718
4718
  label: "Strikethrough",
@@ -4721,7 +4721,7 @@ const WysiwygNav = ({
4721
4721
  }
4722
4722
  ),
4723
4723
  /* @__PURE__ */ jsx(
4724
- CustomIconButton,
4724
+ IconButton,
4725
4725
  {
4726
4726
  onClick: () => onActionClick("BulletList", editorRef, handleTogglePopover),
4727
4727
  label: "BulletList",
@@ -4730,7 +4730,7 @@ const WysiwygNav = ({
4730
4730
  }
4731
4731
  ),
4732
4732
  /* @__PURE__ */ jsx(
4733
- CustomIconButton,
4733
+ IconButton,
4734
4734
  {
4735
4735
  onClick: () => onActionClick("NumberList", editorRef, handleTogglePopover),
4736
4736
  label: "NumberList",
@@ -4741,7 +4741,7 @@ const WysiwygNav = ({
4741
4741
  ] }),
4742
4742
  /* @__PURE__ */ jsxs(IconButtonGroup, { children: [
4743
4743
  /* @__PURE__ */ jsx(
4744
- CustomIconButton,
4744
+ IconButton,
4745
4745
  {
4746
4746
  onClick: () => onActionClick("Code", editorRef, handleTogglePopover),
4747
4747
  label: "Code",
@@ -4750,7 +4750,7 @@ const WysiwygNav = ({
4750
4750
  }
4751
4751
  ),
4752
4752
  /* @__PURE__ */ jsx(
4753
- CustomIconButton,
4753
+ IconButton,
4754
4754
  {
4755
4755
  onClick: () => {
4756
4756
  handleTogglePopover();
@@ -4762,7 +4762,7 @@ const WysiwygNav = ({
4762
4762
  }
4763
4763
  ),
4764
4764
  /* @__PURE__ */ jsx(
4765
- CustomLinkIconButton,
4765
+ IconButton,
4766
4766
  {
4767
4767
  onClick: () => onActionClick("Link", editorRef, handleTogglePopover),
4768
4768
  label: "Link",
@@ -4771,7 +4771,7 @@ const WysiwygNav = ({
4771
4771
  }
4772
4772
  ),
4773
4773
  /* @__PURE__ */ jsx(
4774
- CustomIconButton,
4774
+ IconButton,
4775
4775
  {
4776
4776
  onClick: () => onActionClick("Quote", editorRef, handleTogglePopover),
4777
4777
  label: "Quote",
@@ -4908,15 +4908,19 @@ const Wysiwyg = React.forwardRef(
4908
4908
  );
4909
4909
  const MemoizedWysiwyg = React.memo(Wysiwyg);
4910
4910
  const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4911
- const { id } = useDoc();
4911
+ const { id, document: document2, collectionType } = useDoc();
4912
4912
  const isFormDisabled = useForm("InputRenderer", (state) => state.disabled);
4913
4913
  const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4914
4914
  const canCreateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4915
4915
  const canReadFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4916
4916
  const canUpdateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4917
4917
  const canUserAction = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4918
- const editableFields = id ? canUpdateFields : canCreateFields;
4919
- const readableFields = id ? canReadFields : canCreateFields;
4918
+ let idToCheck = id;
4919
+ if (collectionType === SINGLE_TYPES) {
4920
+ idToCheck = document2?.documentId;
4921
+ }
4922
+ const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4923
+ const readableFields = idToCheck ? canReadFields : canCreateFields;
4920
4924
  const canUserReadField = canUserAction(props.name, readableFields, props.type);
4921
4925
  const canUserEditField = canUserAction(props.name, editableFields, props.type);
4922
4926
  const fields = useStrapiApp("InputRenderer", (app) => app.fields);
@@ -4927,6 +4931,7 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4927
4931
  const {
4928
4932
  edit: { components }
4929
4933
  } = useDocLayout();
4934
+ const field = useField(props.name);
4930
4935
  if (!visible) {
4931
4936
  return null;
4932
4937
  }
@@ -4937,7 +4942,7 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4937
4942
  if (attributeHasCustomFieldProperty(props.attribute)) {
4938
4943
  const CustomInput = lazyComponentStore[props.attribute.customField];
4939
4944
  if (CustomInput) {
4940
- return /* @__PURE__ */ jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
4945
+ return /* @__PURE__ */ jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
4941
4946
  }
4942
4947
  return /* @__PURE__ */ jsx(
4943
4948
  InputRenderer$1,
@@ -5050,260 +5055,193 @@ const getMinMax = (attribute) => {
5050
5055
  }
5051
5056
  };
5052
5057
  const MemoizedInputRenderer = memo(InputRenderer);
5053
- const DynamicComponent = ({
5054
- componentUid,
5055
- disabled,
5056
- index,
5057
- name: name2,
5058
- onRemoveComponentClick,
5059
- onMoveComponent,
5060
- onGrabItem,
5061
- onDropItem,
5062
- onCancel,
5063
- dynamicComponentsByCategory = {},
5064
- onAddComponent
5065
- }) => {
5066
- const { formatMessage } = useIntl();
5067
- const formValues = useForm("DynamicComponent", (state) => state.values);
5068
- const {
5069
- edit: { components }
5070
- } = useDocLayout();
5071
- const title = React.useMemo(() => {
5072
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
5073
- const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
5074
- const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
5075
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
5076
- return mainValue;
5077
- }, [componentUid, components, formValues, name2, index]);
5078
- const { icon, displayName } = React.useMemo(() => {
5079
- const [category] = componentUid.split(".");
5080
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
5081
- (component) => component.uid === componentUid
5082
- ) ?? { icon: null, displayName: null };
5083
- return { icon: icon2, displayName: displayName2 };
5084
- }, [componentUid, dynamicComponentsByCategory]);
5085
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
5086
- type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
5087
- index,
5088
- item: {
5089
- index,
5090
- displayedValue: `${displayName} ${title}`,
5091
- icon
5092
- },
5093
- onMoveItem: onMoveComponent,
5094
- onDropItem,
5095
- onGrabItem,
5096
- onCancel
5097
- });
5098
- React.useEffect(() => {
5099
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
5100
- }, [dragPreviewRef, index]);
5101
- const composedBoxRefs = useComposedRefs(boxRef, dropRef);
5102
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
5103
- /* @__PURE__ */ jsx(
5104
- IconButton,
5105
- {
5106
- borderWidth: 0,
5107
- label: formatMessage(
5108
- {
5109
- id: getTranslation("components.DynamicZone.delete-label"),
5110
- defaultMessage: "Delete {name}"
5111
- },
5112
- { name: title }
5113
- ),
5114
- onClick: onRemoveComponentClick,
5115
- children: /* @__PURE__ */ jsx(Trash, {})
5116
- }
5117
- ),
5118
- /* @__PURE__ */ jsx(
5119
- IconButton,
5120
- {
5121
- borderWidth: 0,
5122
- onClick: (e) => e.stopPropagation(),
5123
- "data-handler-id": handlerId,
5124
- ref: dragRef,
5125
- label: formatMessage({
5126
- id: getTranslation("components.DragHandle-label"),
5127
- defaultMessage: "Drag"
5128
- }),
5129
- onKeyDown: handleKeyDown,
5130
- children: /* @__PURE__ */ jsx(Drag, {})
5131
- }
5132
- ),
5133
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
5134
- /* @__PURE__ */ jsxs(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
5135
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
5136
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage({
5137
- id: getTranslation("components.DynamicZone.more-actions"),
5138
- defaultMessage: "More actions"
5139
- }) })
5140
- ] }),
5141
- /* @__PURE__ */ jsxs(Menu.Content, { children: [
5142
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5143
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5144
- id: getTranslation("components.DynamicZone.add-item-above"),
5145
- defaultMessage: "Add component above"
5146
- }) }),
5147
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5148
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5149
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
5150
- ] }, category)) })
5151
- ] }),
5152
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5153
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5154
- id: getTranslation("components.DynamicZone.add-item-below"),
5155
- defaultMessage: "Add component below"
5156
- }) }),
5157
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5158
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5159
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
5160
- ] }, category)) })
5161
- ] })
5162
- ] })
5163
- ] })
5164
- ] });
5165
- const accordionTitle = title ? `${displayName} ${title}` : displayName;
5166
- const accordionValue = React.useId();
5167
- return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
5168
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
5169
- /* @__PURE__ */ jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsxs(Accordion.Item, { value: accordionValue, children: [
5170
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5171
- /* @__PURE__ */ jsx(
5172
- Accordion.Trigger,
5173
- {
5174
- icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
5175
- children: accordionTitle
5176
- }
5177
- ),
5178
- /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
5179
- ] }),
5180
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsx(Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
5181
- const fieldName = `${name2}.${index}.${field.name}`;
5182
- return /* @__PURE__ */ jsx(Grid$1.Item, { col: size, s: 12, xs: 12, children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...field, name: fieldName }) }, fieldName);
5183
- }) }, rowInd)) }) }) })
5184
- ] }) }) })
5185
- ] });
5058
+ const RESPONSIVE_CONTAINER_BREAKPOINTS = {
5059
+ sm: "27.5rem"
5060
+ // 440px
5186
5061
  };
5187
- const StyledBox = styled(Box)`
5188
- > div:first-child {
5189
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5190
- }
5191
- `;
5192
- const AccordionContentRadius = styled(Box)`
5193
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5194
- `;
5195
- const Rectangle = styled(Box)`
5196
- width: ${({ theme }) => theme.spaces[2]};
5197
- height: ${({ theme }) => theme.spaces[4]};
5198
- `;
5199
- const Preview = styled.span`
5200
- display: block;
5201
- background-color: ${({ theme }) => theme.colors.primary100};
5202
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5203
- outline-offset: -1px;
5204
- padding: ${({ theme }) => theme.spaces[6]};
5062
+ const ResponsiveGridRoot = styled(Grid$1.Root)`
5063
+ container-type: inline-size;
5205
5064
  `;
5206
- const ComponentContainer = styled(Box)`
5207
- list-style: none;
5208
- padding: 0;
5209
- margin: 0;
5065
+ const ResponsiveGridItem = styled(Grid$1.Item)`
5066
+ grid-column: span 12;
5067
+
5068
+ @container (min-width: ${RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
5069
+ ${({ col }) => col && `grid-column: span ${col};`}
5070
+ }
5210
5071
  `;
5211
- const DynamicZoneLabel = ({
5212
- hint,
5213
- label,
5214
- labelAction,
5072
+ const FormLayout = ({ layout }) => {
5073
+ const { formatMessage } = useIntl();
5074
+ const { model } = useDoc();
5075
+ return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((panel, index) => {
5076
+ if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) {
5077
+ const [row] = panel;
5078
+ const [field] = row;
5079
+ const fieldWithTranslatedLabel = {
5080
+ ...field,
5081
+ label: formatMessage({
5082
+ id: `content-manager.content-types.${model}.${field.name}`,
5083
+ defaultMessage: field.label
5084
+ })
5085
+ };
5086
+ return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: /* @__PURE__ */ jsx(Grid$1.Item, { col: 12, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel }) }) }, field.name);
5087
+ }
5088
+ return /* @__PURE__ */ jsx(
5089
+ Box,
5090
+ {
5091
+ hasRadius: true,
5092
+ background: "neutral0",
5093
+ shadow: "tableShadow",
5094
+ paddingLeft: 6,
5095
+ paddingRight: 6,
5096
+ paddingTop: 6,
5097
+ paddingBottom: 6,
5098
+ borderColor: "neutral150",
5099
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: panel.map((row, gridRowIndex) => /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5100
+ const fieldWithTranslatedLabel = {
5101
+ ...field,
5102
+ label: formatMessage({
5103
+ id: `content-manager.content-types.${model}.${field.name}`,
5104
+ defaultMessage: field.label
5105
+ })
5106
+ };
5107
+ return /* @__PURE__ */ jsx(
5108
+ ResponsiveGridItem,
5109
+ {
5110
+ col: size,
5111
+ s: 12,
5112
+ xs: 12,
5113
+ direction: "column",
5114
+ alignItems: "stretch",
5115
+ children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel })
5116
+ },
5117
+ field.name
5118
+ );
5119
+ }) }, gridRowIndex)) })
5120
+ },
5121
+ index
5122
+ );
5123
+ }) });
5124
+ };
5125
+ const NonRepeatableComponent = ({
5126
+ attribute,
5215
5127
  name: name2,
5216
- numberOfComponents = 0,
5217
- required
5128
+ children,
5129
+ layout
5218
5130
  }) => {
5219
- return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5131
+ const { formatMessage } = useIntl();
5132
+ const { value } = useField(name2);
5133
+ const level = useComponent("NonRepeatableComponent", (state) => state.level);
5134
+ const isNested = level > 0;
5135
+ return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
5220
5136
  Box,
5221
5137
  {
5222
- paddingTop: 3,
5223
- paddingBottom: 3,
5224
- paddingRight: 4,
5225
- paddingLeft: 4,
5226
- borderRadius: "26px",
5227
- background: "neutral0",
5228
- shadow: "filterShadow",
5229
- color: "neutral500",
5230
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
5231
- /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
5232
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5233
- label || name2,
5234
- " "
5235
- ] }),
5236
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5237
- "(",
5238
- numberOfComponents,
5239
- ")"
5240
- ] }),
5241
- required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
5242
- labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
5243
- ] }),
5244
- hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
5245
- ] })
5138
+ background: "neutral100",
5139
+ paddingLeft: 6,
5140
+ paddingRight: 6,
5141
+ paddingTop: 6,
5142
+ paddingBottom: 6,
5143
+ hasRadius: isNested,
5144
+ borderColor: isNested ? "neutral200" : void 0,
5145
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
5146
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5147
+ const completeFieldName = `${name2}.${field.name}`;
5148
+ const translatedLabel = formatMessage({
5149
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5150
+ defaultMessage: field.label
5151
+ });
5152
+ return /* @__PURE__ */ jsx(
5153
+ ResponsiveGridItem,
5154
+ {
5155
+ col: size,
5156
+ s: 12,
5157
+ xs: 12,
5158
+ direction: "column",
5159
+ alignItems: "stretch",
5160
+ children: children({ ...field, label: translatedLabel, name: completeFieldName })
5161
+ },
5162
+ completeFieldName
5163
+ );
5164
+ }) }, index);
5165
+ }) })
5246
5166
  }
5247
5167
  ) });
5248
5168
  };
5249
- const [DynamicZoneProvider, useDynamicZone] = createContext(
5250
- "DynamicZone",
5251
- {
5252
- isInDynamicZone: false
5253
- }
5254
- );
5255
- const DynamicZone = ({
5169
+ const RepeatableComponent = ({
5256
5170
  attribute,
5257
- disabled: disabledProp,
5258
- hint,
5259
- label,
5260
- labelAction,
5171
+ disabled,
5261
5172
  name: name2,
5262
- required = false
5173
+ mainField,
5174
+ children,
5175
+ layout
5263
5176
  }) => {
5264
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5265
- const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
5266
- const [liveText, setLiveText] = React.useState("");
5267
- const { components, isLoading } = useDoc();
5268
- const disabled = disabledProp || isLoading;
5269
- const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
5270
- "DynamicZone",
5271
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5272
- addFieldRow: addFieldRow2,
5273
- removeFieldRow: removeFieldRow2,
5274
- moveFieldRow: moveFieldRow2
5275
- })
5276
- );
5277
- const { value = [], error } = useField(name2);
5278
- const dynamicComponentsByCategory = React.useMemo(() => {
5279
- return attribute.components.reduce((acc, componentUid) => {
5280
- const { category, info } = components[componentUid] ?? { info: {} };
5281
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5282
- if (!acc[category]) {
5283
- acc[category] = [];
5284
- }
5285
- acc[category] = [...acc[category], component];
5286
- return acc;
5287
- }, {});
5288
- }, [attribute.components, components]);
5289
- const { formatMessage } = useIntl();
5290
5177
  const { toggleNotification } = useNotification();
5291
- const dynamicDisplayedComponentsLength = value.length;
5292
- const handleAddComponent = (uid, position) => {
5293
- setAddComponentIsOpen(false);
5294
- const schema = components[uid];
5295
- const form = createDefaultForm(schema, components);
5296
- const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
5297
- ...data2,
5298
- __component: uid
5299
- }));
5300
- const data = transformations(form);
5301
- addFieldRow(name2, data, position);
5178
+ const { formatMessage } = useIntl();
5179
+ const { search: searchString } = useLocation();
5180
+ const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
5181
+ const { components } = useDoc();
5182
+ const {
5183
+ value = [],
5184
+ error,
5185
+ rawError
5186
+ } = useField(name2);
5187
+ const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
5188
+ const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
5189
+ const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
5190
+ const { max = Infinity } = attribute;
5191
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
5192
+ const [liveText, setLiveText] = React.useState("");
5193
+ React.useEffect(() => {
5194
+ const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
5195
+ const hasNestedValue = value && Array.isArray(value) && value.length > 0;
5196
+ if (hasNestedErrors && hasNestedValue) {
5197
+ const errorOpenItems = rawError.map((_, idx) => {
5198
+ return value[idx] ? value[idx].__temp_key__ : null;
5199
+ }).filter((value2) => !!value2);
5200
+ if (errorOpenItems && errorOpenItems.length > 0) {
5201
+ setCollapseToOpen((collapseToOpen2) => {
5202
+ if (!errorOpenItems.includes(collapseToOpen2)) {
5203
+ return errorOpenItems[0];
5204
+ }
5205
+ return collapseToOpen2;
5206
+ });
5207
+ }
5208
+ }
5209
+ }, [rawError, value]);
5210
+ const componentTmpKeyWithFocussedField = React.useMemo(() => {
5211
+ if (search.has("field")) {
5212
+ const fieldParam = search.get("field");
5213
+ if (!fieldParam) {
5214
+ return void 0;
5215
+ }
5216
+ const [, path] = fieldParam.split(`${name2}.`);
5217
+ if (getIn(value, path, void 0) !== void 0) {
5218
+ const [subpath] = path.split(".");
5219
+ return getIn(value, subpath, void 0)?.__temp_key__;
5220
+ }
5221
+ }
5222
+ return void 0;
5223
+ }, [search, name2, value]);
5224
+ const prevValue = usePrev(value);
5225
+ React.useEffect(() => {
5226
+ if (prevValue && prevValue.length < value.length) {
5227
+ setCollapseToOpen(value[value.length - 1].__temp_key__);
5228
+ }
5229
+ }, [value, prevValue]);
5230
+ React.useEffect(() => {
5231
+ if (typeof componentTmpKeyWithFocussedField === "string") {
5232
+ setCollapseToOpen(componentTmpKeyWithFocussedField);
5233
+ }
5234
+ }, [componentTmpKeyWithFocussedField]);
5235
+ const toggleCollapses = () => {
5236
+ setCollapseToOpen("");
5302
5237
  };
5303
- const handleClickOpenPicker = () => {
5304
- if (dynamicDisplayedComponentsLength < max) {
5305
- setAddComponentIsOpen((prev) => !prev);
5306
- } else {
5238
+ const handleClick = () => {
5239
+ if (value.length < max) {
5240
+ const schema = components[attribute.component];
5241
+ const form = createDefaultForm(schema, components);
5242
+ const data = transformDocument(schema, components)(form);
5243
+ addFieldRow(name2, data);
5244
+ } else if (value.length >= max) {
5307
5245
  toggleNotification({
5308
5246
  type: "info",
5309
5247
  message: formatMessage({
@@ -5312,7 +5250,7 @@ const DynamicZone = ({
5312
5250
  });
5313
5251
  }
5314
5252
  };
5315
- const handleMoveComponent = (newIndex, currentIndex) => {
5253
+ const handleMoveComponentField = (newIndex, currentIndex) => {
5316
5254
  setLiveText(
5317
5255
  formatMessage(
5318
5256
  {
@@ -5327,6 +5265,9 @@ const DynamicZone = ({
5327
5265
  );
5328
5266
  moveFieldRow(name2, currentIndex, newIndex);
5329
5267
  };
5268
+ const handleValueChange = (key) => {
5269
+ setCollapseToOpen(key);
5270
+ };
5330
5271
  const getItemPos = (index) => `${index + 1} of ${value.length}`;
5331
5272
  const handleCancel = (index) => {
5332
5273
  setLiveText(
@@ -5369,123 +5310,277 @@ const DynamicZone = ({
5369
5310
  )
5370
5311
  );
5371
5312
  };
5372
- const handleRemoveComponent = (name22, currentIndex) => () => {
5373
- removeFieldRow(name22, currentIndex);
5374
- };
5375
- const hasError = error !== void 0;
5376
- const renderButtonLabel = () => {
5377
- if (addComponentIsOpen) {
5378
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5379
- }
5380
- if (hasError && dynamicDisplayedComponentsLength > max) {
5381
- return formatMessage(
5382
- {
5383
- id: getTranslation(`components.DynamicZone.extra-components`),
5384
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5385
- },
5386
- {
5387
- number: dynamicDisplayedComponentsLength - max
5388
- }
5389
- );
5390
- }
5391
- if (hasError && dynamicDisplayedComponentsLength < min) {
5392
- return formatMessage(
5393
- {
5394
- id: getTranslation(`components.DynamicZone.missing-components`),
5395
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5396
- },
5397
- { number: min - dynamicDisplayedComponentsLength }
5398
- );
5399
- }
5400
- return formatMessage(
5401
- {
5402
- id: getTranslation("components.DynamicZone.add-component"),
5403
- defaultMessage: "Add a component to {componentName}"
5404
- },
5405
- { componentName: label || name2 }
5406
- );
5407
- };
5408
- const level = useComponent("DynamicZone", (state) => state.level);
5409
5313
  const ariaDescriptionId = React.useId();
5410
- return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5411
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
5412
- /* @__PURE__ */ jsx(
5413
- DynamicZoneLabel,
5414
- {
5415
- hint,
5416
- label,
5417
- labelAction,
5418
- name: name2,
5419
- numberOfComponents: dynamicDisplayedComponentsLength,
5420
- required
5421
- }
5422
- ),
5423
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5424
- id: getTranslation("dnd.instructions"),
5425
- defaultMessage: `Press spacebar to grab and re-order`
5426
- }) }),
5427
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5428
- /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
5429
- ComponentProvider,
5430
- {
5431
- level: level + 1,
5432
- uid: field.__component,
5433
- id: field.id,
5434
- type: "dynamiczone",
5435
- children: /* @__PURE__ */ jsx(
5436
- DynamicComponent,
5437
- {
5438
- disabled,
5439
- name: name2,
5440
- index,
5441
- componentUid: field.__component,
5442
- onMoveComponent: handleMoveComponent,
5443
- onRemoveComponentClick: handleRemoveComponent(name2, index),
5444
- onCancel: handleCancel,
5445
- onDropItem: handleDropItem,
5446
- onGrabItem: handleGrabItem,
5447
- onAddComponent: handleAddComponent,
5448
- dynamicComponentsByCategory
5449
- }
5450
- )
5451
- },
5452
- field.__temp_key__
5453
- )) })
5454
- ] }),
5455
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5456
- AddComponentButton,
5314
+ const level = useComponent("RepeatableComponent", (state) => state.level);
5315
+ if (value.length === 0) {
5316
+ return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
5317
+ }
5318
+ return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
5319
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5320
+ id: getTranslation("dnd.instructions"),
5321
+ defaultMessage: `Press spacebar to grab and re-order`
5322
+ }) }),
5323
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5324
+ /* @__PURE__ */ jsxs(
5325
+ AccordionRoot,
5457
5326
  {
5458
- hasError,
5459
- isDisabled: disabled,
5460
- isOpen: addComponentIsOpen,
5461
- onClick: handleClickOpenPicker,
5462
- children: renderButtonLabel()
5327
+ $error: error,
5328
+ value: collapseToOpen,
5329
+ onValueChange: handleValueChange,
5330
+ "aria-describedby": ariaDescriptionId,
5331
+ children: [
5332
+ value.map(({ __temp_key__: key, id }, index) => {
5333
+ const nameWithIndex = `${name2}.${index}`;
5334
+ return /* @__PURE__ */ jsx(
5335
+ ComponentProvider,
5336
+ {
5337
+ id,
5338
+ uid: attribute.component,
5339
+ level: level + 1,
5340
+ type: "repeatable",
5341
+ children: /* @__PURE__ */ jsx(
5342
+ Component,
5343
+ {
5344
+ disabled,
5345
+ name: nameWithIndex,
5346
+ attribute,
5347
+ index,
5348
+ mainField,
5349
+ onMoveItem: handleMoveComponentField,
5350
+ onDeleteComponent: () => {
5351
+ removeFieldRow(name2, index);
5352
+ toggleCollapses();
5353
+ },
5354
+ toggleCollapses,
5355
+ onCancel: handleCancel,
5356
+ onDropItem: handleDropItem,
5357
+ onGrabItem: handleGrabItem,
5358
+ __temp_key__: key,
5359
+ children: layout.map((row, index2) => {
5360
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5361
+ const completeFieldName = `${nameWithIndex}.${field.name}`;
5362
+ const translatedLabel = formatMessage({
5363
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5364
+ defaultMessage: field.label
5365
+ });
5366
+ return /* @__PURE__ */ jsx(
5367
+ ResponsiveGridItem,
5368
+ {
5369
+ col: size,
5370
+ s: 12,
5371
+ xs: 12,
5372
+ direction: "column",
5373
+ alignItems: "stretch",
5374
+ children: children({
5375
+ ...field,
5376
+ label: translatedLabel,
5377
+ name: completeFieldName
5378
+ })
5379
+ },
5380
+ completeFieldName
5381
+ );
5382
+ }) }, index2);
5383
+ })
5384
+ }
5385
+ )
5386
+ },
5387
+ key
5388
+ );
5389
+ }),
5390
+ /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
5391
+ id: getTranslation("containers.EditView.add.new-entry"),
5392
+ defaultMessage: "Add an entry"
5393
+ }) })
5394
+ ]
5463
5395
  }
5464
- ) }),
5465
- /* @__PURE__ */ jsx(
5466
- ComponentPicker,
5396
+ )
5397
+ ] });
5398
+ };
5399
+ const AccordionRoot = styled(Accordion.Root)`
5400
+ border: 1px solid
5401
+ ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
5402
+ `;
5403
+ const TextButtonCustom = styled(TextButton)`
5404
+ width: 100%;
5405
+ display: flex;
5406
+ justify-content: center;
5407
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
5408
+ padding-inline: ${(props) => props.theme.spaces[6]};
5409
+ padding-block: ${(props) => props.theme.spaces[3]};
5410
+
5411
+ &:not([disabled]) {
5412
+ cursor: pointer;
5413
+
5414
+ &:hover {
5415
+ background-color: ${(props) => props.theme.colors.primary100};
5416
+ }
5417
+ }
5418
+
5419
+ span {
5420
+ font-weight: 600;
5421
+ font-size: 1.4rem;
5422
+ line-height: 2.4rem;
5423
+ }
5424
+
5425
+ @media (prefers-reduced-motion: no-preference) {
5426
+ transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
5427
+ }
5428
+ `;
5429
+ const Component = ({
5430
+ disabled,
5431
+ index,
5432
+ name: name2,
5433
+ mainField = {
5434
+ name: "id",
5435
+ type: "integer"
5436
+ },
5437
+ children,
5438
+ onDeleteComponent,
5439
+ toggleCollapses,
5440
+ __temp_key__,
5441
+ ...dragProps
5442
+ }) => {
5443
+ const { formatMessage } = useIntl();
5444
+ const displayValue = useForm("RepeatableComponent", (state) => {
5445
+ return getIn(state.values, [...name2.split("."), mainField.name]);
5446
+ });
5447
+ const accordionRef = React.useRef(null);
5448
+ const componentKey = name2.split(".").slice(0, -1).join(".");
5449
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
5450
+ type: `${ItemTypes.COMPONENT}_${componentKey}`,
5451
+ index,
5452
+ item: {
5453
+ index,
5454
+ displayedValue: displayValue
5455
+ },
5456
+ onStart() {
5457
+ toggleCollapses();
5458
+ },
5459
+ ...dragProps
5460
+ });
5461
+ React.useEffect(() => {
5462
+ dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
5463
+ }, [dragPreviewRef, index]);
5464
+ const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
5465
+ const composedBoxRefs = useComposedRefs(
5466
+ boxRef,
5467
+ dropRef
5468
+ );
5469
+ return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
5470
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5471
+ /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
5472
+ /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
5473
+ /* @__PURE__ */ jsx(
5474
+ IconButton,
5475
+ {
5476
+ variant: "ghost",
5477
+ onClick: onDeleteComponent,
5478
+ label: formatMessage({
5479
+ id: getTranslation("containers.Edit.delete"),
5480
+ defaultMessage: "Delete"
5481
+ }),
5482
+ children: /* @__PURE__ */ jsx(Trash, {})
5483
+ }
5484
+ ),
5485
+ /* @__PURE__ */ jsx(
5486
+ IconButton,
5487
+ {
5488
+ ref: composedAccordionRefs,
5489
+ variant: "ghost",
5490
+ onClick: (e) => e.stopPropagation(),
5491
+ "data-handler-id": handlerId,
5492
+ label: formatMessage({
5493
+ id: getTranslation("components.DragHandle-label"),
5494
+ defaultMessage: "Drag"
5495
+ }),
5496
+ onKeyDown: handleKeyDown,
5497
+ children: /* @__PURE__ */ jsx(Drag, {})
5498
+ }
5499
+ )
5500
+ ] })
5501
+ ] }),
5502
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
5503
+ Flex,
5467
5504
  {
5468
- dynamicComponentsByCategory,
5469
- isOpen: addComponentIsOpen,
5470
- onClickAddComponent: handleAddComponent
5505
+ direction: "column",
5506
+ alignItems: "stretch",
5507
+ background: "neutral100",
5508
+ padding: 6,
5509
+ gap: 6,
5510
+ children
5471
5511
  }
5472
- )
5512
+ ) })
5473
5513
  ] }) });
5474
5514
  };
5515
+ const Preview = () => {
5516
+ return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
5517
+ };
5518
+ const StyledSpan = styled(Box)`
5519
+ display: block;
5520
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5521
+ outline-offset: -1px;
5522
+ `;
5523
+ const ComponentInput = ({
5524
+ label,
5525
+ required,
5526
+ name: name2,
5527
+ attribute,
5528
+ disabled,
5529
+ labelAction,
5530
+ ...props
5531
+ }) => {
5532
+ const { formatMessage } = useIntl();
5533
+ const field = useField(name2);
5534
+ const showResetComponent = !attribute.repeatable && field.value && !disabled;
5535
+ const { components } = useDoc();
5536
+ const handleInitialisationClick = () => {
5537
+ const schema = components[attribute.component];
5538
+ const form = createDefaultForm(schema, components);
5539
+ const data = transformDocument(schema, components)(form);
5540
+ field.onChange(name2, data);
5541
+ };
5542
+ return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
5543
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
5544
+ /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
5545
+ label,
5546
+ attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
5547
+ " (",
5548
+ Array.isArray(field.value) ? field.value.length : 0,
5549
+ ")"
5550
+ ] })
5551
+ ] }),
5552
+ showResetComponent && /* @__PURE__ */ jsx(
5553
+ IconButton,
5554
+ {
5555
+ label: formatMessage({
5556
+ id: getTranslation("components.reset-entry"),
5557
+ defaultMessage: "Reset Entry"
5558
+ }),
5559
+ variant: "ghost",
5560
+ onClick: () => {
5561
+ field.onChange(name2, null);
5562
+ },
5563
+ children: /* @__PURE__ */ jsx(Trash, {})
5564
+ }
5565
+ )
5566
+ ] }),
5567
+ !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
5568
+ !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
5569
+ attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
5570
+ /* @__PURE__ */ jsx(Field.Error, {})
5571
+ ] });
5572
+ };
5573
+ const MemoizedComponentInput = React.memo(ComponentInput);
5475
5574
  export {
5476
5575
  DynamicZone as D,
5477
- MemoizedInputRenderer as M,
5576
+ FormLayout as F,
5577
+ MemoizedUIDInput as M,
5478
5578
  NotAllowedInput as N,
5479
5579
  useDynamicZone as a,
5480
5580
  useFieldHint as b,
5481
- createDefaultForm as c,
5482
- MemoizedUIDInput as d,
5483
- MemoizedWysiwyg as e,
5484
- MemoizedComponentInput as f,
5485
- MemoizedBlocksInput as g,
5486
- prepareTempKeys as p,
5487
- removeFieldsThatDontExistOnSchema as r,
5488
- transformDocument as t,
5581
+ MemoizedWysiwyg as c,
5582
+ MemoizedComponentInput as d,
5583
+ MemoizedBlocksInput as e,
5489
5584
  useLazyComponents as u
5490
5585
  };
5491
- //# sourceMappingURL=Field-Cs7duwWd.mjs.map
5586
+ //# sourceMappingURL=Input-aV8SSoTa.mjs.map