@strapi/content-manager 0.0.0-next.bec3f8cddf61be32ee5516609a1d4d6032933972 → 0.0.0-next.bffd3c1819cd08304e7d270e88b4973e9fcbc183

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 (168) 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-BUOQFZ08.mjs → ComponentConfigurationPage-9_4yUE9L.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-BUOQFZ08.mjs.map → ComponentConfigurationPage-9_4yUE9L.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-WtZ2yaRP.js → ComponentConfigurationPage-DBSh-kET.js} +4 -5
  6. package/dist/_chunks/{ComponentConfigurationPage-WtZ2yaRP.js.map → ComponentConfigurationPage-DBSh-kET.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-BVrCP5lF.js → EditConfigurationPage-Bl_U2JgH.js} +4 -5
  11. package/dist/_chunks/{EditConfigurationPage-BVrCP5lF.js.map → EditConfigurationPage-Bl_U2JgH.js.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-D7HkxcAN.mjs → EditConfigurationPage-COe6hjPC.mjs} +3 -3
  13. package/dist/_chunks/{EditConfigurationPage-D7HkxcAN.mjs.map → EditConfigurationPage-COe6hjPC.mjs.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-BKQ83NAk.js → EditViewPage-D4yFJET6.js} +23 -57
  15. package/dist/_chunks/EditViewPage-D4yFJET6.js.map +1 -0
  16. package/dist/_chunks/{EditViewPage-zKmMBER4.mjs → EditViewPage-DrmVmYN0.mjs} +21 -54
  17. package/dist/_chunks/EditViewPage-DrmVmYN0.mjs.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-CkbrtNZd.js → Form-C4rSaGsz.js} +5 -6
  21. package/dist/_chunks/{Form-CkbrtNZd.js.map → Form-C4rSaGsz.js.map} +1 -1
  22. package/dist/_chunks/{Form-B-E8l73g.mjs → Form-DamaxNpG.mjs} +3 -3
  23. package/dist/_chunks/{Form-B-E8l73g.mjs.map → Form-DamaxNpG.mjs.map} +1 -1
  24. package/dist/_chunks/{History-C72HQ0-i.mjs → History-D1PreDSY.mjs} +37 -67
  25. package/dist/_chunks/History-D1PreDSY.mjs.map +1 -0
  26. package/dist/_chunks/{History-B2Dg9q7H.js → History-DTm8UCCQ.js} +48 -79
  27. package/dist/_chunks/History-DTm8UCCQ.js.map +1 -0
  28. package/dist/_chunks/{Field-BhN0lyyZ.js → Input-B7sapvBG.js} +1293 -1271
  29. package/dist/_chunks/Input-B7sapvBG.js.map +1 -0
  30. package/dist/_chunks/{Field-BbrX_tUG.mjs → Input-CZ1YvjHR.mjs} +1332 -1310
  31. package/dist/_chunks/Input-CZ1YvjHR.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-BalSo5dp.mjs → ListConfigurationPage-Bbi32isk.mjs} +6 -5
  33. package/dist/_chunks/ListConfigurationPage-Bbi32isk.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-BQCc3BnJ.js → ListConfigurationPage-ysFMjKI3.js} +6 -6
  35. package/dist/_chunks/ListConfigurationPage-ysFMjKI3.js.map +1 -0
  36. package/dist/_chunks/{ListViewPage-Dfue5wQ2.mjs → ListViewPage-Bud_jBDQ.mjs} +68 -53
  37. package/dist/_chunks/ListViewPage-Bud_jBDQ.mjs.map +1 -0
  38. package/dist/_chunks/{ListViewPage-Cu5dZKZe.js → ListViewPage-DTuuxU3n.js} +74 -60
  39. package/dist/_chunks/ListViewPage-DTuuxU3n.js.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-MGzn4JPu.js → NoContentTypePage-CL7VVeYs.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-MGzn4JPu.js.map → NoContentTypePage-CL7VVeYs.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-BLC8M9U0.mjs → NoContentTypePage-DVhkugsf.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-BLC8M9U0.mjs.map → NoContentTypePage-DVhkugsf.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-BpAoEQy_.mjs → NoPermissionsPage-CMdM-dCo.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-BpAoEQy_.mjs.map → NoPermissionsPage-CMdM-dCo.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-DJPwEpOD.js → NoPermissionsPage-v7I599vC.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-DJPwEpOD.js.map → NoPermissionsPage-v7I599vC.js.map} +1 -1
  48. package/dist/_chunks/Preview-BNuU0SuQ.mjs +287 -0
  49. package/dist/_chunks/Preview-BNuU0SuQ.mjs.map +1 -0
  50. package/dist/_chunks/Preview-Cxq-uI6D.js +305 -0
  51. package/dist/_chunks/Preview-Cxq-uI6D.js.map +1 -0
  52. package/dist/_chunks/{Relations-BULOkyWN.mjs → Relations-C2Ahkrdg.mjs} +6 -8
  53. package/dist/_chunks/{Relations-BULOkyWN.mjs.map → Relations-C2Ahkrdg.mjs.map} +1 -1
  54. package/dist/_chunks/{Relations-DTiqnyGx.js → Relations-CWS79QQn.js} +7 -10
  55. package/dist/_chunks/{Relations-DTiqnyGx.js.map → Relations-CWS79QQn.js.map} +1 -1
  56. package/dist/_chunks/{en-C-J4DGEe.js → en-BR48D_RH.js} +20 -3
  57. package/dist/_chunks/{en-C-J4DGEe.js.map → en-BR48D_RH.js.map} +1 -1
  58. package/dist/_chunks/{en-DPfZ6tPQ.mjs → en-D65uIF6Y.mjs} +20 -3
  59. package/dist/_chunks/{en-DPfZ6tPQ.mjs.map → en-D65uIF6Y.mjs.map} +1 -1
  60. package/dist/_chunks/{fr-B2Kyv8Z9.js → fr-C43IbhA_.js} +4 -1
  61. package/dist/_chunks/{fr-B2Kyv8Z9.js.map → fr-C43IbhA_.js.map} +1 -1
  62. package/dist/_chunks/{fr--pg5jUbt.mjs → fr-DBseuRuB.mjs} +4 -1
  63. package/dist/_chunks/{fr--pg5jUbt.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  64. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  65. package/dist/_chunks/{index-76eawJUd.js → index-DQsvBb_N.js} +568 -243
  66. package/dist/_chunks/index-DQsvBb_N.js.map +1 -0
  67. package/dist/_chunks/{index-DW7xp_LG.mjs → index-ZKrsjv-2.mjs} +585 -259
  68. package/dist/_chunks/index-ZKrsjv-2.mjs.map +1 -0
  69. package/dist/_chunks/{layout-CVz8WiDC.js → layout-Cl0NhlQB.js} +5 -6
  70. package/dist/_chunks/{layout-CVz8WiDC.js.map → layout-Cl0NhlQB.js.map} +1 -1
  71. package/dist/_chunks/{layout-DNfLIjbP.mjs → layout-fQk1rMk9.mjs} +4 -4
  72. package/dist/_chunks/{layout-DNfLIjbP.mjs.map → layout-fQk1rMk9.mjs.map} +1 -1
  73. package/dist/_chunks/objects-BcXOv6_9.js.map +1 -1
  74. package/dist/_chunks/objects-D6yBsdmx.mjs.map +1 -1
  75. package/dist/_chunks/{relations-B6K4WRjW.js → relations-BRfBxVbX.js} +6 -3
  76. package/dist/_chunks/relations-BRfBxVbX.js.map +1 -0
  77. package/dist/_chunks/{relations-ByHSIjSe.mjs → relations-BakOFl_1.mjs} +6 -3
  78. package/dist/_chunks/relations-BakOFl_1.mjs.map +1 -0
  79. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  80. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  81. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  82. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  83. package/dist/_chunks/{useDebounce-DmuSJIF3.mjs → usePrev-CZGy2Vjf.mjs} +11 -11
  84. package/dist/_chunks/usePrev-CZGy2Vjf.mjs.map +1 -0
  85. package/dist/_chunks/{useDebounce-CtcjDB3L.js → usePrev-D5J_2fEu.js} +8 -8
  86. package/dist/_chunks/usePrev-D5J_2fEu.js.map +1 -0
  87. package/dist/admin/index.js +2 -1
  88. package/dist/admin/index.js.map +1 -1
  89. package/dist/admin/index.mjs +6 -5
  90. package/dist/admin/src/content-manager.d.ts +3 -2
  91. package/dist/admin/src/exports.d.ts +1 -0
  92. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  93. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  94. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  95. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  96. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  98. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  99. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  100. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  101. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  102. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  103. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  104. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  105. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  106. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  107. package/dist/admin/src/preview/routes.d.ts +3 -0
  108. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  109. package/dist/admin/src/router.d.ts +1 -1
  110. package/dist/admin/src/services/api.d.ts +1 -1
  111. package/dist/admin/src/services/components.d.ts +2 -2
  112. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  113. package/dist/admin/src/services/documents.d.ts +16 -19
  114. package/dist/admin/src/services/init.d.ts +1 -1
  115. package/dist/admin/src/services/relations.d.ts +2 -2
  116. package/dist/admin/src/services/uid.d.ts +3 -3
  117. package/dist/server/index.js +230 -187
  118. package/dist/server/index.js.map +1 -1
  119. package/dist/server/index.mjs +231 -187
  120. package/dist/server/index.mjs.map +1 -1
  121. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  122. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  123. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  124. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  125. package/dist/server/src/history/services/history.d.ts +3 -3
  126. package/dist/server/src/history/services/history.d.ts.map +1 -1
  127. package/dist/server/src/history/services/utils.d.ts +6 -10
  128. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  129. package/dist/server/src/index.d.ts +3 -2
  130. package/dist/server/src/index.d.ts.map +1 -1
  131. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -1
  132. package/dist/server/src/preview/index.d.ts.map +1 -1
  133. package/dist/server/src/preview/services/index.d.ts +1 -0
  134. package/dist/server/src/preview/services/index.d.ts.map +1 -1
  135. package/dist/server/src/preview/services/preview-config.d.ts +2 -0
  136. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
  137. package/dist/server/src/preview/utils.d.ts +1 -0
  138. package/dist/server/src/preview/utils.d.ts.map +1 -1
  139. package/dist/server/src/register.d.ts.map +1 -1
  140. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  141. package/dist/server/src/services/document-metadata.d.ts +4 -2
  142. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  143. package/dist/server/src/services/index.d.ts +3 -2
  144. package/dist/server/src/services/index.d.ts.map +1 -1
  145. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  146. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  147. package/dist/server/src/services/utils/populate.d.ts +2 -2
  148. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  149. package/package.json +12 -11
  150. package/dist/_chunks/EditViewPage-BKQ83NAk.js.map +0 -1
  151. package/dist/_chunks/EditViewPage-zKmMBER4.mjs.map +0 -1
  152. package/dist/_chunks/Field-BbrX_tUG.mjs.map +0 -1
  153. package/dist/_chunks/Field-BhN0lyyZ.js.map +0 -1
  154. package/dist/_chunks/History-B2Dg9q7H.js.map +0 -1
  155. package/dist/_chunks/History-C72HQ0-i.mjs.map +0 -1
  156. package/dist/_chunks/ListConfigurationPage-BQCc3BnJ.js.map +0 -1
  157. package/dist/_chunks/ListConfigurationPage-BalSo5dp.mjs.map +0 -1
  158. package/dist/_chunks/ListViewPage-Cu5dZKZe.js.map +0 -1
  159. package/dist/_chunks/ListViewPage-Dfue5wQ2.mjs.map +0 -1
  160. package/dist/_chunks/index-76eawJUd.js.map +0 -1
  161. package/dist/_chunks/index-DW7xp_LG.mjs.map +0 -1
  162. package/dist/_chunks/relations-B6K4WRjW.js.map +0 -1
  163. package/dist/_chunks/relations-ByHSIjSe.mjs.map +0 -1
  164. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  165. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
  166. package/dist/admin/src/preview/constants.d.ts +0 -1
  167. package/dist/server/src/preview/constants.d.ts +0 -2
  168. package/dist/server/src/preview/constants.d.ts.map +0 -1
@@ -1,25 +1,75 @@
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, 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, n as CLONE_PATH, d as buildValidParams, f as useDocumentRBAC, S as SINGLE_TYPES, o as useDocLayout } from "./index-DW7xp_LG.mjs";
9
- import { generateNKeysBetween } from "fractional-indexing";
10
- import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from "./Relations-BULOkyWN.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-ZKrsjv-2.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-D6yBsdmx.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";
20
- import { p as prefixFileUrlWithBackendUrl, u as usePrev, a as useDebounce } from "./useDebounce-DmuSJIF3.mjs";
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";
64
+ import { p as prefixFileUrlWithBackendUrl, u as useDebounce, a as usePrev } from "./usePrev-CZGy2Vjf.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, useMatch } 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-C2Ahkrdg.mjs";
71
+ import pipe$1 from "lodash/fp/pipe";
72
+ import { C as ComponentIcon, a as COMPONENT_ICONS } from "./ComponentIcon-u4bIXTFY.mjs";
23
73
  import CodeMirror from "codemirror5";
24
74
  import sanitizeHtml from "sanitize-html";
25
75
  import { getLanguage, highlight, highlightAuto } from "highlight.js";
@@ -35,93 +85,6 @@ import sub from "markdown-it-sub";
35
85
  import sup from "markdown-it-sup";
36
86
  import "highlight.js/styles/solarized-dark.css";
37
87
  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
88
  const componentStore = /* @__PURE__ */ new Map();
126
89
  const useLazyComponents = (componentUids = []) => {
127
90
  const [lazyComponentStore, setLazyComponentStore] = useState(Object.fromEntries(componentStore));
@@ -163,7 +126,8 @@ const useLazyComponents = (componentUids = []) => {
163
126
  const codeLanguages = [
164
127
  {
165
128
  value: "asm",
166
- label: "Assembly"
129
+ label: "Assembly",
130
+ decorate: "asmatmel"
167
131
  },
168
132
  {
169
133
  value: "bash",
@@ -199,7 +163,8 @@ const codeLanguages = [
199
163
  },
200
164
  {
201
165
  value: "dockerfile",
202
- label: "Dockerfile"
166
+ label: "Dockerfile",
167
+ decorate: "docker"
203
168
  },
204
169
  {
205
170
  value: "elixir",
@@ -355,7 +320,8 @@ const codeLanguages = [
355
320
  },
356
321
  {
357
322
  value: "typescript",
358
- label: "TypeScript"
323
+ label: "TypeScript",
324
+ decorate: "ts"
359
325
  },
360
326
  {
361
327
  value: "tsx",
@@ -371,7 +337,8 @@ const codeLanguages = [
371
337
  },
372
338
  {
373
339
  value: "yaml",
374
- label: "YAML"
340
+ label: "YAML",
341
+ decorate: "yml"
375
342
  }
376
343
  ];
377
344
  const baseHandleConvert = (editor, attributesToSet) => {
@@ -437,6 +404,29 @@ const pressEnterTwiceToExit = (editor) => {
437
404
  });
438
405
  }
439
406
  };
407
+ const decorateCode = ([node, path]) => {
408
+ const ranges = [];
409
+ if (!Element.isElement(node) || node.type !== "code") return ranges;
410
+ const text = Node.string(node);
411
+ const language = codeLanguages.find((lang) => lang.value === node.language);
412
+ const decorateKey = language?.decorate ?? language?.value;
413
+ const selectedLanguage = Prism.languages[decorateKey || "plaintext"];
414
+ const tokens = Prism.tokenize(text, selectedLanguage);
415
+ let start = 0;
416
+ for (const token of tokens) {
417
+ const length = token.length;
418
+ const end = start + length;
419
+ if (typeof token !== "string") {
420
+ ranges.push({
421
+ anchor: { path, offset: start },
422
+ focus: { path, offset: end },
423
+ className: `token ${token.type}`
424
+ });
425
+ }
426
+ start = end;
427
+ }
428
+ return ranges;
429
+ };
440
430
  const CodeBlock = styled.pre`
441
431
  border-radius: ${({ theme }) => theme.borderRadius};
442
432
  background-color: ${({ theme }) => theme.colors.neutral100};
@@ -508,7 +498,7 @@ const CodeEditor = (props) => {
508
498
  const codeBlocks = {
509
499
  code: {
510
500
  renderElement: (props) => /* @__PURE__ */ jsx(CodeEditor, { ...props }),
511
- icon: Code,
501
+ icon: CodeBlock$1,
512
502
  label: {
513
503
  id: "components.Blocks.blocks.code",
514
504
  defaultMessage: "Code block"
@@ -521,8 +511,7 @@ const codeBlocks = {
521
511
  handleEnterKey(editor) {
522
512
  pressEnterTwiceToExit(editor);
523
513
  },
524
- snippets: ["```"],
525
- dragHandleTopMargin: "10px"
514
+ snippets: ["```"]
526
515
  }
527
516
  };
528
517
  const H1 = styled(Typography).attrs({ tag: "h1" })`
@@ -697,8 +686,7 @@ const ImageDialog = () => {
697
686
  const [isOpen, setIsOpen] = React.useState(true);
698
687
  const { editor } = useBlocksEditorContext("ImageDialog");
699
688
  const components = useStrapiApp("ImageDialog", (state) => state.components);
700
- if (!components || !isOpen)
701
- return null;
689
+ if (!components || !isOpen) return null;
702
690
  const MediaLibraryDialog = components["media-library"];
703
691
  const insertImages = (images) => {
704
692
  Transforms.unwrapNodes(editor, {
@@ -707,14 +695,12 @@ const ImageDialog = () => {
707
695
  });
708
696
  const nodeEntryBeingReplaced = Editor$1.above(editor, {
709
697
  match(node) {
710
- if (Editor$1.isEditor(node))
711
- return false;
698
+ if (Editor$1.isEditor(node)) return false;
712
699
  const isInlineNode = ["text", "link"].includes(node.type);
713
700
  return !isInlineNode;
714
701
  }
715
702
  });
716
- if (!nodeEntryBeingReplaced)
717
- return;
703
+ if (!nodeEntryBeingReplaced) return;
718
704
  const [, pathToInsert] = nodeEntryBeingReplaced;
719
705
  Transforms.removeNodes(editor);
720
706
  const nodesToInsert = images.map((image) => {
@@ -892,8 +878,7 @@ const LinkContent = React.forwardRef(
892
878
  ReactEditor.focus(editor);
893
879
  };
894
880
  React.useEffect(() => {
895
- if (popoverOpen)
896
- linkInputRef.current?.focus();
881
+ if (popoverOpen) linkInputRef.current?.focus();
897
882
  }, [popoverOpen]);
898
883
  const inputNotDirty = !linkText || !linkUrl || link.url && link.url === linkUrl && elementText && elementText === linkText;
899
884
  return /* @__PURE__ */ jsxs(Popover.Root, { open: popoverOpen, children: [
@@ -963,11 +948,11 @@ const LinkContent = React.forwardRef(
963
948
  ),
964
949
  /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
965
950
  /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: handleClose, children: formatMessage({
966
- id: "components.Blocks.popover.cancel",
951
+ id: "global.cancel",
967
952
  defaultMessage: "Cancel"
968
953
  }) }),
969
954
  /* @__PURE__ */ jsx(Button, { disabled: Boolean(inputNotDirty) || isSaveDisabled, onClick: handleSave, children: formatMessage({
970
- id: "components.Blocks.popover.save",
955
+ id: "global.save",
971
956
  defaultMessage: "Save"
972
957
  }) })
973
958
  ] })
@@ -1048,8 +1033,7 @@ const isText$1 = (node) => {
1048
1033
  return Node.isNode(node) && !Editor$1.isEditor(node) && node.type === "text";
1049
1034
  };
1050
1035
  const handleBackspaceKeyOnList = (editor, event) => {
1051
- if (!editor.selection)
1052
- return;
1036
+ if (!editor.selection) return;
1053
1037
  const [currentListItem, currentListItemPath] = Editor$1.parent(editor, editor.selection.anchor);
1054
1038
  const [currentList, currentListPath] = Editor$1.parent(editor, currentListItemPath);
1055
1039
  const isListEmpty = currentList.children.length === 1 && isText$1(currentListItem.children[0]) && currentListItem.children[0].text === "";
@@ -1158,8 +1142,7 @@ const handleEnterKeyOnList = (editor) => {
1158
1142
  };
1159
1143
  const handleConvertToList = (editor, format) => {
1160
1144
  const convertedPath = baseHandleConvert(editor, { type: "list-item" });
1161
- if (!convertedPath)
1162
- return;
1145
+ if (!convertedPath) return;
1163
1146
  Transforms.wrapNodes(editor, { type: "list", format, children: [] }, { at: convertedPath });
1164
1147
  };
1165
1148
  const handleTabOnList = (editor) => {
@@ -1171,8 +1154,7 @@ const handleTabOnList = (editor) => {
1171
1154
  }
1172
1155
  const [currentListItem, currentListItemPath] = currentListItemEntry;
1173
1156
  const [currentList] = Editor$1.parent(editor, currentListItemPath);
1174
- if (currentListItem === currentList.children[0])
1175
- return;
1157
+ if (currentListItem === currentList.children[0]) return;
1176
1158
  const currentListItemIndex = currentList.children.findIndex((item) => item === currentListItem);
1177
1159
  const previousNode = currentList.children[currentListItemIndex - 1];
1178
1160
  if (previousNode.type === "list") {
@@ -1308,13 +1290,13 @@ const quoteBlocks = {
1308
1290
  handleEnterKey(editor) {
1309
1291
  pressEnterTwiceToExit(editor);
1310
1292
  },
1311
- snippets: [">"],
1312
- dragHandleTopMargin: "6px"
1293
+ snippets: [">"]
1313
1294
  }
1314
1295
  };
1315
1296
  const ToolbarWrapper = styled(Flex)`
1316
1297
  &[aria-disabled='true'] {
1317
1298
  cursor: not-allowed;
1299
+ background: ${({ theme }) => theme.colors.neutral150};
1318
1300
  }
1319
1301
  `;
1320
1302
  const Separator = styled(Toolbar.Separator)`
@@ -1325,7 +1307,7 @@ const Separator = styled(Toolbar.Separator)`
1325
1307
  const FlexButton = styled(Flex)`
1326
1308
  // Inherit the not-allowed cursor from ToolbarWrapper when disabled
1327
1309
  &[aria-disabled] {
1328
- cursor: inherit;
1310
+ cursor: not-allowed;
1329
1311
  }
1330
1312
 
1331
1313
  &[aria-disabled='false'] {
@@ -1539,8 +1521,7 @@ const isListNode = (node) => {
1539
1521
  const ListButton = ({ block, format }) => {
1540
1522
  const { editor, disabled, blocks } = useBlocksEditorContext("ListButton");
1541
1523
  const isListActive = () => {
1542
- if (!editor.selection)
1543
- return false;
1524
+ if (!editor.selection) return false;
1544
1525
  const currentListEntry = Editor$1.above(editor, {
1545
1526
  match: (node) => !Editor$1.isEditor(node) && node.type === "list",
1546
1527
  at: editor.selection.anchor
@@ -1614,8 +1595,7 @@ const LinkButton = ({ disabled }) => {
1614
1595
  const { editor } = useBlocksEditorContext("LinkButton");
1615
1596
  const isLinkActive = () => {
1616
1597
  const { selection } = editor;
1617
- if (!selection)
1618
- return false;
1598
+ if (!selection) return false;
1619
1599
  const [match] = Array.from(
1620
1600
  Editor$1.nodes(editor, {
1621
1601
  at: Editor$1.unhangRange(editor, selection),
@@ -1679,7 +1659,7 @@ const BlocksToolbar = () => {
1679
1659
  return false;
1680
1660
  };
1681
1661
  const isButtonDisabled = checkButtonDisabled();
1682
- return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, children: [
1662
+ return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, width: "100%", children: [
1683
1663
  /* @__PURE__ */ jsx(BlocksDropdown, {}),
1684
1664
  /* @__PURE__ */ jsx(Separator, {}),
1685
1665
  /* @__PURE__ */ jsx(Toolbar.ToggleGroup, { type: "multiple", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
@@ -1753,30 +1733,32 @@ const DragIconButton = styled(IconButton)`
1753
1733
  display: flex;
1754
1734
  align-items: center;
1755
1735
  justify-content: center;
1736
+ border: none;
1756
1737
  border-radius: ${({ theme }) => theme.borderRadius};
1757
- width: ${({ theme }) => theme.spaces[4]};
1758
- height: ${({ theme }) => theme.spaces[6]};
1738
+ padding-left: ${({ theme }) => theme.spaces[0]};
1739
+ padding-right: ${({ theme }) => theme.spaces[0]};
1740
+ padding-top: ${({ theme }) => theme.spaces[1]};
1741
+ padding-bottom: ${({ theme }) => theme.spaces[1]};
1759
1742
  visibility: hidden;
1760
1743
  cursor: grab;
1761
1744
  opacity: inherit;
1762
1745
  margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};
1763
1746
 
1764
1747
  &:hover {
1765
- background: ${({ theme }) => theme.colors.neutral200};
1748
+ background: ${({ theme }) => theme.colors.neutral100};
1766
1749
  }
1767
1750
  &:active {
1768
1751
  cursor: grabbing;
1752
+ background: ${({ theme }) => theme.colors.neutral150};
1769
1753
  }
1770
1754
  &[aria-disabled='true'] {
1771
- cursor: not-allowed;
1772
- background: transparent;
1755
+ visibility: hidden;
1773
1756
  }
1774
1757
  svg {
1775
- height: auto;
1776
1758
  min-width: ${({ theme }) => theme.spaces[3]};
1777
1759
 
1778
1760
  path {
1779
- fill: ${({ theme }) => theme.colors.neutral700};
1761
+ fill: ${({ theme }) => theme.colors.neutral500};
1780
1762
  }
1781
1763
  }
1782
1764
  `;
@@ -1821,8 +1803,7 @@ const DragAndDropElement = ({
1821
1803
  displayedValue: children
1822
1804
  },
1823
1805
  onDropItem(currentIndex, newIndex) {
1824
- if (newIndex)
1825
- handleMoveBlock(newIndex, currentIndex);
1806
+ if (newIndex) handleMoveBlock(newIndex, currentIndex);
1826
1807
  }
1827
1808
  });
1828
1809
  const composedBoxRefs = useComposedRefs(blockRef, dropRef);
@@ -1928,7 +1909,7 @@ const baseRenderLeaf = (props, modifiers2) => {
1928
1909
  }
1929
1910
  return currentChildren;
1930
1911
  }, props.children);
1931
- return /* @__PURE__ */ jsx("span", { ...props.attributes, children: wrappedChildren });
1912
+ return /* @__PURE__ */ jsx("span", { ...props.attributes, className: props.leaf.className, children: wrappedChildren });
1932
1913
  };
1933
1914
  const baseRenderElement = ({
1934
1915
  props,
@@ -1966,8 +1947,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1966
1947
  [modifiers2]
1967
1948
  );
1968
1949
  const handleMoveBlocks = (editor2, event) => {
1969
- if (!editor2.selection)
1970
- return;
1950
+ if (!editor2.selection) return;
1971
1951
  const start = Range.start(editor2.selection);
1972
1952
  const currentIndex = [start.path[0]];
1973
1953
  let newIndexPosition = 0;
@@ -2104,8 +2084,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2104
2084
  }
2105
2085
  };
2106
2086
  const handleScrollSelectionIntoView = () => {
2107
- if (!editor.selection)
2108
- return;
2087
+ if (!editor.selection) return;
2109
2088
  const domRange = ReactEditor.toDOMRange(editor, editor.selection);
2110
2089
  const domRect = domRange.getBoundingClientRect();
2111
2090
  const blocksInput = blocksRef.current;
@@ -2132,7 +2111,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2132
2111
  background: "neutral0",
2133
2112
  color: "neutral800",
2134
2113
  lineHeight: 6,
2135
- paddingRight: 4,
2114
+ paddingRight: 7,
2136
2115
  paddingTop: 6,
2137
2116
  paddingBottom: 3,
2138
2117
  children: [
@@ -2143,6 +2122,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2143
2122
  readOnly: disabled,
2144
2123
  placeholder,
2145
2124
  isExpandedMode,
2125
+ decorate: decorateCode,
2146
2126
  renderElement,
2147
2127
  renderLeaf,
2148
2128
  onKeyDown: handleKeyDown,
@@ -2299,8 +2279,7 @@ const InlineCode = styled.code`
2299
2279
  `;
2300
2280
  const baseCheckIsActive = (editor, name2) => {
2301
2281
  const marks = Editor$1.marks(editor);
2302
- if (!marks)
2303
- return false;
2282
+ if (!marks) return false;
2304
2283
  return Boolean(marks[name2]);
2305
2284
  };
2306
2285
  const baseHandleToggle = (editor, name2) => {
@@ -2466,6 +2445,7 @@ const ExpandIconButton = styled(IconButton)`
2466
2445
  position: absolute;
2467
2446
  bottom: 1.2rem;
2468
2447
  right: 1.2rem;
2448
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2469
2449
  `;
2470
2450
  function useResetKey(value) {
2471
2451
  const slateUpdatesCount = React.useRef(0);
@@ -2597,26 +2577,6 @@ const BlocksInput = React.forwardRef(
2597
2577
  }
2598
2578
  );
2599
2579
  const MemoizedBlocksInput = React.memo(BlocksInput);
2600
- const createDefaultForm = (contentType, components = {}) => {
2601
- const traverseSchema = (attributes) => {
2602
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2603
- if ("default" in attribute) {
2604
- acc[key] = attribute.default;
2605
- } else if (attribute.type === "component" && attribute.required) {
2606
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2607
- if (attribute.repeatable) {
2608
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2609
- } else {
2610
- acc[key] = defaultComponentForm;
2611
- }
2612
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2613
- acc[key] = [];
2614
- }
2615
- return acc;
2616
- }, {});
2617
- };
2618
- return traverseSchema(contentType.attributes);
2619
- };
2620
2580
  const Initializer = ({ disabled, name: name2, onClick }) => {
2621
2581
  const { formatMessage } = useIntl();
2622
2582
  const field = useField(name2);
@@ -2624,7 +2584,7 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2624
2584
  Box,
2625
2585
  {
2626
2586
  tag: "button",
2627
- background: "neutral100",
2587
+ background: disabled ? "neutral150" : "neutral100",
2628
2588
  borderColor: field.error ? "danger600" : "neutral200",
2629
2589
  hasRadius: true,
2630
2590
  disabled,
@@ -2632,631 +2592,638 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2632
2592
  paddingTop: 9,
2633
2593
  paddingBottom: 9,
2634
2594
  type: "button",
2595
+ style: { cursor: disabled ? "not-allowed" : "pointer" },
2635
2596
  children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2636
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(CircleIcon, {}) }),
2637
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { textColor: "primary600", variant: "pi", fontWeight: "bold", children: formatMessage({
2638
- id: getTranslation("components.empty-repeatable"),
2639
- defaultMessage: "No entry yet. Click to add one."
2640
- }) }) })
2597
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", color: disabled ? "neutral500" : "primary600", children: /* @__PURE__ */ jsx(PlusCircle, { width: "3.2rem", height: "3.2rem" }) }),
2598
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2599
+ Typography,
2600
+ {
2601
+ textColor: disabled ? "neutral600" : "primary600",
2602
+ variant: "pi",
2603
+ fontWeight: "bold",
2604
+ children: formatMessage({
2605
+ id: getTranslation("components.empty-repeatable"),
2606
+ defaultMessage: "No entry yet. Click to add one."
2607
+ })
2608
+ }
2609
+ ) })
2641
2610
  ] })
2642
2611
  }
2643
2612
  ) });
2644
2613
  };
2645
- const CircleIcon = styled(PlusCircle)`
2646
- width: 2.4rem;
2647
- height: 2.4rem;
2614
+ const AddComponentButton = ({
2615
+ hasError,
2616
+ isDisabled,
2617
+ isOpen,
2618
+ children,
2619
+ onClick
2620
+ }) => {
2621
+ return /* @__PURE__ */ jsx(
2622
+ StyledButton,
2623
+ {
2624
+ type: "button",
2625
+ onClick,
2626
+ disabled: isDisabled,
2627
+ background: "neutral0",
2628
+ style: { cursor: isDisabled ? "not-allowed" : "pointer" },
2629
+ variant: "tertiary",
2630
+ children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
2631
+ /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
2632
+ /* @__PURE__ */ jsx(
2633
+ Typography,
2634
+ {
2635
+ variant: "pi",
2636
+ fontWeight: "bold",
2637
+ textColor: hasError && !isOpen ? "danger600" : "neutral600",
2638
+ children
2639
+ }
2640
+ )
2641
+ ] })
2642
+ }
2643
+ );
2644
+ };
2645
+ const StyledAddIcon = styled(PlusCircle)`
2646
+ height: ${({ theme }) => theme.spaces[6]};
2647
+ width: ${({ theme }) => theme.spaces[6]};
2648
+ transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
2649
+
2648
2650
  > circle {
2649
- fill: ${({ theme }) => theme.colors.primary200};
2651
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2650
2652
  }
2651
2653
  > path {
2652
- fill: ${({ theme }) => theme.colors.primary600};
2654
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
2653
2655
  }
2654
2656
  `;
2655
- const NonRepeatableComponent = ({
2656
- attribute,
2657
- name: name2,
2658
- children,
2659
- layout
2657
+ const StyledButton = styled(Button)`
2658
+ padding-left: ${({ theme }) => theme.spaces[3]};
2659
+ border-radius: 26px;
2660
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2661
+ height: 5rem;
2662
+ `;
2663
+ const ComponentCategory = ({
2664
+ category,
2665
+ components = [],
2666
+ variant = "primary",
2667
+ onAddComponent
2660
2668
  }) => {
2661
- const { value } = useField(name2);
2662
- const level = useComponent("NonRepeatableComponent", (state) => state.level);
2663
- const isNested = level > 0;
2664
- return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
2669
+ const { formatMessage } = useIntl();
2670
+ return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
2671
+ /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
2672
+ /* @__PURE__ */ jsx(ResponsiveAccordionContent, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
2673
+ ComponentBox,
2674
+ {
2675
+ tag: "button",
2676
+ type: "button",
2677
+ background: "neutral100",
2678
+ justifyContent: "center",
2679
+ onClick: onAddComponent(uid),
2680
+ hasRadius: true,
2681
+ height: "8.4rem",
2682
+ shrink: 0,
2683
+ borderColor: "neutral200",
2684
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
2685
+ /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
2686
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
2687
+ ] })
2688
+ },
2689
+ uid
2690
+ )) }) })
2691
+ ] });
2692
+ };
2693
+ const ResponsiveAccordionContent = styled(Accordion.Content)`
2694
+ container-type: inline-size;
2695
+ `;
2696
+ const Grid = styled(Box)`
2697
+ display: grid;
2698
+ grid-template-columns: repeat(auto-fill, 100%);
2699
+ grid-gap: ${({ theme }) => theme.spaces[1]};
2700
+
2701
+ @container (min-width: ${() => RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
2702
+ grid-template-columns: repeat(auto-fill, 14rem);
2703
+ }
2704
+ `;
2705
+ const ComponentBox = styled(Flex)`
2706
+ color: ${({ theme }) => theme.colors.neutral600};
2707
+ cursor: pointer;
2708
+
2709
+ @media (prefers-reduced-motion: no-preference) {
2710
+ transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2711
+ }
2712
+
2713
+ &:focus,
2714
+ &:hover {
2715
+ border: 1px solid ${({ theme }) => theme.colors.primary200};
2716
+ background: ${({ theme }) => theme.colors.primary100};
2717
+ color: ${({ theme }) => theme.colors.primary600};
2718
+ }
2719
+ `;
2720
+ const ComponentPicker = ({
2721
+ dynamicComponentsByCategory = {},
2722
+ isOpen,
2723
+ onClickAddComponent
2724
+ }) => {
2725
+ const { formatMessage } = useIntl();
2726
+ const handleAddComponentToDz = (componentUid) => () => {
2727
+ onClickAddComponent(componentUid);
2728
+ };
2729
+ if (!isOpen) {
2730
+ return null;
2731
+ }
2732
+ return /* @__PURE__ */ jsxs(
2665
2733
  Box,
2666
2734
  {
2667
- background: "neutral100",
2668
- paddingLeft: 6,
2669
- paddingRight: 6,
2670
2735
  paddingTop: 6,
2671
2736
  paddingBottom: 6,
2672
- hasRadius: isNested,
2673
- borderColor: isNested ? "neutral200" : void 0,
2674
- children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
2675
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2676
- const completeFieldName = `${name2}.${field.name}`;
2677
- return /* @__PURE__ */ jsx(
2678
- Grid$1.Item,
2679
- {
2680
- col: size,
2681
- s: 12,
2682
- xs: 12,
2683
- direction: "column",
2684
- alignItems: "stretch",
2685
- children: children({ ...field, name: completeFieldName })
2686
- },
2687
- completeFieldName
2688
- );
2689
- }) }, index);
2690
- }) })
2737
+ paddingLeft: 5,
2738
+ paddingRight: 5,
2739
+ background: "neutral0",
2740
+ shadow: "tableShadow",
2741
+ borderColor: "neutral150",
2742
+ hasRadius: true,
2743
+ children: [
2744
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
2745
+ id: getTranslation("components.DynamicZone.ComponentPicker-label"),
2746
+ defaultMessage: "Pick one component"
2747
+ }) }) }),
2748
+ /* @__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(
2749
+ ComponentCategory,
2750
+ {
2751
+ category,
2752
+ components,
2753
+ onAddComponent: handleAddComponentToDz,
2754
+ variant: index % 2 === 1 ? "primary" : "secondary"
2755
+ },
2756
+ category
2757
+ )) }) })
2758
+ ]
2691
2759
  }
2692
- ) });
2760
+ );
2693
2761
  };
2694
- const RepeatableComponent = ({
2695
- attribute,
2762
+ const DynamicComponent = ({
2763
+ componentUid,
2696
2764
  disabled,
2765
+ index,
2697
2766
  name: name2,
2698
- mainField,
2699
- children,
2700
- layout
2767
+ onRemoveComponentClick,
2768
+ onMoveComponent,
2769
+ onGrabItem,
2770
+ onDropItem,
2771
+ onCancel,
2772
+ dynamicComponentsByCategory = {},
2773
+ onAddComponent,
2774
+ children
2701
2775
  }) => {
2702
- const { toggleNotification } = useNotification();
2703
2776
  const { formatMessage } = useIntl();
2704
- const { search: searchString } = useLocation();
2705
- const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
2706
- const { components } = useDoc();
2777
+ const formValues = useForm("DynamicComponent", (state) => state.values);
2707
2778
  const {
2708
- value = [],
2709
- error,
2710
- rawError
2711
- } = useField(name2);
2712
- const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
2713
- const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
2714
- const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
2715
- const { max = Infinity } = attribute;
2716
- const [collapseToOpen, setCollapseToOpen] = React.useState("");
2717
- const [liveText, setLiveText] = React.useState("");
2779
+ edit: { components }
2780
+ } = useDocLayout();
2781
+ const title = React.useMemo(() => {
2782
+ const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
2783
+ const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
2784
+ const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
2785
+ const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
2786
+ return mainValue;
2787
+ }, [componentUid, components, formValues, name2, index]);
2788
+ const { icon, displayName } = React.useMemo(() => {
2789
+ const [category] = componentUid.split(".");
2790
+ const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
2791
+ (component) => component.uid === componentUid
2792
+ ) ?? { icon: null, displayName: null };
2793
+ return { icon: icon2, displayName: displayName2 };
2794
+ }, [componentUid, dynamicComponentsByCategory]);
2795
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2796
+ type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
2797
+ index,
2798
+ item: {
2799
+ index,
2800
+ displayedValue: `${displayName} ${title}`,
2801
+ icon
2802
+ },
2803
+ onMoveItem: onMoveComponent,
2804
+ onDropItem,
2805
+ onGrabItem,
2806
+ onCancel
2807
+ });
2718
2808
  React.useEffect(() => {
2719
- const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
2720
- const hasNestedValue = value && Array.isArray(value) && value.length > 0;
2721
- if (hasNestedErrors && hasNestedValue) {
2722
- const errorOpenItems = rawError.map((_, idx) => {
2723
- return value[idx] ? value[idx].__temp_key__ : null;
2724
- }).filter((value2) => !!value2);
2725
- if (errorOpenItems && errorOpenItems.length > 0) {
2726
- setCollapseToOpen((collapseToOpen2) => {
2727
- if (!errorOpenItems.includes(collapseToOpen2)) {
2728
- return errorOpenItems[0];
2729
- }
2730
- return collapseToOpen2;
2731
- });
2732
- }
2809
+ dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2810
+ }, [dragPreviewRef, index]);
2811
+ const accordionValue = React.useId();
2812
+ const { value = [], rawError } = useField(`${name2}.${index}`);
2813
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
2814
+ React.useEffect(() => {
2815
+ if (rawError && value) {
2816
+ setCollapseToOpen(accordionValue);
2733
2817
  }
2734
- }, [rawError, value]);
2735
- const componentTmpKeyWithFocussedField = React.useMemo(() => {
2736
- if (search.has("field")) {
2737
- const fieldParam = search.get("field");
2738
- if (!fieldParam) {
2739
- return void 0;
2818
+ }, [rawError, value, accordionValue]);
2819
+ const composedBoxRefs = useComposedRefs(boxRef, dropRef);
2820
+ const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
2821
+ /* @__PURE__ */ jsx(
2822
+ IconButton,
2823
+ {
2824
+ variant: "ghost",
2825
+ label: formatMessage(
2826
+ {
2827
+ id: getTranslation("components.DynamicZone.delete-label"),
2828
+ defaultMessage: "Delete {name}"
2829
+ },
2830
+ { name: title }
2831
+ ),
2832
+ onClick: onRemoveComponentClick,
2833
+ children: /* @__PURE__ */ jsx(Trash, {})
2740
2834
  }
2741
- const [, path] = fieldParam.split(`${name2}.`);
2742
- if (getIn(value, path, void 0) !== void 0) {
2743
- const [subpath] = path.split(".");
2744
- return getIn(value, subpath, void 0)?.__temp_key__;
2835
+ ),
2836
+ /* @__PURE__ */ jsx(
2837
+ IconButton,
2838
+ {
2839
+ variant: "ghost",
2840
+ onClick: (e) => e.stopPropagation(),
2841
+ "data-handler-id": handlerId,
2842
+ ref: dragRef,
2843
+ label: formatMessage({
2844
+ id: getTranslation("components.DragHandle-label"),
2845
+ defaultMessage: "Drag"
2846
+ }),
2847
+ onKeyDown: handleKeyDown,
2848
+ children: /* @__PURE__ */ jsx(Drag, {})
2745
2849
  }
2746
- }
2747
- return void 0;
2748
- }, [search, name2, value]);
2749
- const prevValue = usePrev(value);
2750
- React.useEffect(() => {
2751
- if (prevValue && prevValue.length < value.length) {
2752
- setCollapseToOpen(value[value.length - 1].__temp_key__);
2753
- }
2754
- }, [value, prevValue]);
2755
- React.useEffect(() => {
2756
- if (typeof componentTmpKeyWithFocussedField === "string") {
2757
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2758
- }
2759
- }, [componentTmpKeyWithFocussedField]);
2760
- const toggleCollapses = () => {
2761
- setCollapseToOpen("");
2762
- };
2763
- const handleClick = () => {
2764
- if (value.length < max) {
2765
- const schema = components[attribute.component];
2766
- const form = createDefaultForm(schema, components);
2767
- const data = transformDocument(schema, components)(form);
2768
- addFieldRow(name2, data);
2769
- } else if (value.length >= max) {
2770
- toggleNotification({
2771
- type: "info",
2772
- message: formatMessage({
2773
- id: getTranslation("components.notification.info.maximum-requirement")
2774
- })
2775
- });
2776
- }
2777
- };
2778
- const handleMoveComponentField = (newIndex, currentIndex) => {
2779
- setLiveText(
2780
- formatMessage(
2781
- {
2782
- id: getTranslation("dnd.reorder"),
2783
- defaultMessage: "{item}, moved. New position in list: {position}."
2784
- },
2785
- {
2786
- item: `${name2}.${currentIndex}`,
2787
- position: getItemPos(newIndex)
2788
- }
2789
- )
2790
- );
2791
- moveFieldRow(name2, currentIndex, newIndex);
2792
- };
2793
- const handleValueChange = (key) => {
2794
- setCollapseToOpen(key);
2795
- };
2796
- const getItemPos = (index) => `${index + 1} of ${value.length}`;
2797
- const handleCancel = (index) => {
2798
- setLiveText(
2799
- formatMessage(
2800
- {
2801
- id: getTranslation("dnd.cancel-item"),
2802
- defaultMessage: "{item}, dropped. Re-order cancelled."
2803
- },
2804
- {
2805
- item: `${name2}.${index}`
2806
- }
2807
- )
2808
- );
2809
- };
2810
- const handleGrabItem = (index) => {
2811
- setLiveText(
2812
- formatMessage(
2813
- {
2814
- id: getTranslation("dnd.grab-item"),
2815
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
2816
- },
2850
+ ),
2851
+ /* @__PURE__ */ jsxs(Menu.Root, { children: [
2852
+ /* @__PURE__ */ jsx(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 0, paddingRight: 0, children: /* @__PURE__ */ jsx(
2853
+ IconButton,
2817
2854
  {
2818
- item: `${name2}.${index}`,
2819
- position: getItemPos(index)
2855
+ variant: "ghost",
2856
+ label: formatMessage({
2857
+ id: getTranslation("components.DynamicZone.more-actions"),
2858
+ defaultMessage: "More actions"
2859
+ }),
2860
+ tag: "span",
2861
+ children: /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false })
2820
2862
  }
2821
- )
2822
- );
2823
- };
2824
- const handleDropItem = (index) => {
2825
- setLiveText(
2826
- formatMessage(
2827
- {
2828
- id: getTranslation("dnd.drop-item"),
2829
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
2830
- },
2863
+ ) }),
2864
+ /* @__PURE__ */ jsxs(Menu.Content, { children: [
2865
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2866
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2867
+ id: getTranslation("components.DynamicZone.add-item-above"),
2868
+ defaultMessage: "Add component above"
2869
+ }) }),
2870
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2871
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2872
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
2873
+ ] }, category)) })
2874
+ ] }),
2875
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2876
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2877
+ id: getTranslation("components.DynamicZone.add-item-below"),
2878
+ defaultMessage: "Add component below"
2879
+ }) }),
2880
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2881
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2882
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
2883
+ ] }, category)) })
2884
+ ] })
2885
+ ] })
2886
+ ] })
2887
+ ] });
2888
+ const accordionTitle = title ? `${displayName} ${title}` : displayName;
2889
+ return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
2890
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
2891
+ /* @__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: [
2892
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
2893
+ /* @__PURE__ */ jsx(
2894
+ Accordion.Trigger,
2895
+ {
2896
+ icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
2897
+ children: accordionTitle
2898
+ }
2899
+ ),
2900
+ /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
2901
+ ] }),
2902
+ /* @__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(
2903
+ Grid$1.Item,
2831
2904
  {
2832
- item: `${name2}.${index}`,
2833
- position: getItemPos(index)
2834
- }
2835
- )
2836
- );
2837
- };
2838
- const ariaDescriptionId = React.useId();
2839
- const level = useComponent("RepeatableComponent", (state) => state.level);
2840
- if (value.length === 0) {
2841
- return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2842
- }
2843
- return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
2844
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2845
- id: getTranslation("dnd.instructions"),
2846
- defaultMessage: `Press spacebar to grab and re-order`
2847
- }) }),
2848
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2849
- /* @__PURE__ */ jsxs(
2850
- AccordionRoot,
2851
- {
2852
- $error: error,
2853
- value: collapseToOpen,
2854
- onValueChange: handleValueChange,
2855
- "aria-describedby": ariaDescriptionId,
2856
- children: [
2857
- value.map(({ __temp_key__: key, id }, index) => {
2858
- const nameWithIndex = `${name2}.${index}`;
2905
+ col: 12,
2906
+ s: 12,
2907
+ xs: 12,
2908
+ direction: "column",
2909
+ alignItems: "stretch",
2910
+ children: /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
2911
+ const fieldName = `${name2}.${index}.${field.name}`;
2912
+ const fieldWithTranslatedLabel = {
2913
+ ...field,
2914
+ label: formatMessage({
2915
+ id: `content-manager.components.${componentUid}.${field.name}`,
2916
+ defaultMessage: field.label
2917
+ })
2918
+ };
2859
2919
  return /* @__PURE__ */ jsx(
2860
- ComponentProvider,
2920
+ ResponsiveGridItem,
2861
2921
  {
2862
- id,
2863
- uid: attribute.component,
2864
- level: level + 1,
2865
- type: "repeatable",
2866
- children: /* @__PURE__ */ jsx(
2867
- Component,
2868
- {
2869
- disabled,
2870
- name: nameWithIndex,
2871
- attribute,
2872
- index,
2873
- mainField,
2874
- onMoveItem: handleMoveComponentField,
2875
- onDeleteComponent: () => {
2876
- removeFieldRow(name2, index);
2877
- toggleCollapses();
2878
- },
2879
- toggleCollapses,
2880
- onCancel: handleCancel,
2881
- onDropItem: handleDropItem,
2882
- onGrabItem: handleGrabItem,
2883
- __temp_key__: key,
2884
- children: layout.map((row, index2) => {
2885
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2886
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2887
- return /* @__PURE__ */ jsx(
2888
- Grid$1.Item,
2889
- {
2890
- col: size,
2891
- s: 12,
2892
- xs: 12,
2893
- direction: "column",
2894
- alignItems: "stretch",
2895
- children: children({ ...field, name: completeFieldName })
2896
- },
2897
- completeFieldName
2898
- );
2899
- }) }, index2);
2900
- })
2901
- }
2902
- )
2922
+ col: size,
2923
+ s: 12,
2924
+ xs: 12,
2925
+ direction: "column",
2926
+ alignItems: "stretch",
2927
+ children: children ? children({ ...fieldWithTranslatedLabel, name: fieldName }) : /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
2903
2928
  },
2904
- key
2929
+ fieldName
2905
2930
  );
2906
- }),
2907
- /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
2908
- id: getTranslation("containers.EditView.add.new-entry"),
2909
- defaultMessage: "Add an entry"
2910
2931
  }) })
2911
- ]
2912
- }
2913
- )
2932
+ },
2933
+ rowInd
2934
+ )) }) }) }) })
2935
+ ] }) }) })
2914
2936
  ] });
2915
2937
  };
2916
- const AccordionRoot = styled(Accordion.Root)`
2917
- border: 1px solid
2918
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
2919
- `;
2920
- const TextButtonCustom = styled(TextButton)`
2921
- width: 100%;
2922
- display: flex;
2923
- justify-content: center;
2924
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
2925
- padding-inline: ${(props) => props.theme.spaces[6]};
2926
- padding-block: ${(props) => props.theme.spaces[3]};
2927
-
2928
- &:not([disabled]) {
2929
- cursor: pointer;
2930
-
2931
- &:hover {
2932
- background-color: ${(props) => props.theme.colors.primary100};
2933
- }
2934
- }
2935
-
2936
- span {
2937
- font-weight: 600;
2938
- font-size: 1.4rem;
2939
- line-height: 2.4rem;
2940
- }
2941
-
2942
- @media (prefers-reduced-motion: no-preference) {
2943
- transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2938
+ const StyledBox = styled(Box)`
2939
+ > div:first-child {
2940
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
2944
2941
  }
2945
2942
  `;
2946
- const Component = ({
2947
- disabled,
2948
- index,
2949
- name: name2,
2950
- mainField = {
2951
- name: "id",
2952
- type: "integer"
2953
- },
2954
- children,
2955
- onDeleteComponent,
2956
- toggleCollapses,
2957
- __temp_key__,
2958
- ...dragProps
2959
- }) => {
2960
- const { formatMessage } = useIntl();
2961
- const displayValue = useForm("RepeatableComponent", (state) => {
2962
- return getIn(state.values, [...name2.split("."), mainField.name]);
2963
- });
2964
- const accordionRef = React.useRef(null);
2965
- const componentKey = name2.split(".").slice(0, -1).join(".");
2966
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2967
- type: `${ItemTypes.COMPONENT}_${componentKey}`,
2968
- index,
2969
- item: {
2970
- index,
2971
- displayedValue: displayValue
2972
- },
2973
- onStart() {
2974
- toggleCollapses();
2975
- },
2976
- ...dragProps
2977
- });
2978
- React.useEffect(() => {
2979
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2980
- }, [dragPreviewRef, index]);
2981
- const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
2982
- const composedBoxRefs = useComposedRefs(
2983
- boxRef,
2984
- dropRef
2985
- );
2986
- return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
2987
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
2988
- /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
2989
- /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
2990
- /* @__PURE__ */ jsx(
2991
- IconButton,
2992
- {
2993
- variant: "ghost",
2994
- onClick: onDeleteComponent,
2995
- label: formatMessage({
2996
- id: getTranslation("containers.Edit.delete"),
2997
- defaultMessage: "Delete"
2998
- }),
2999
- children: /* @__PURE__ */ jsx(Trash, {})
3000
- }
3001
- ),
3002
- /* @__PURE__ */ jsx(
3003
- IconButton,
3004
- {
3005
- ref: composedAccordionRefs,
3006
- variant: "ghost",
3007
- onClick: (e) => e.stopPropagation(),
3008
- "data-handler-id": handlerId,
3009
- label: formatMessage({
3010
- id: getTranslation("components.DragHandle-label"),
3011
- defaultMessage: "Drag"
3012
- }),
3013
- onKeyDown: handleKeyDown,
3014
- children: /* @__PURE__ */ jsx(Drag, {})
3015
- }
3016
- )
3017
- ] })
3018
- ] }),
3019
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
3020
- Flex,
3021
- {
3022
- direction: "column",
3023
- alignItems: "stretch",
3024
- background: "neutral100",
3025
- padding: 6,
3026
- gap: 6,
3027
- children
3028
- }
3029
- ) })
3030
- ] }) });
3031
- };
3032
- const Preview$1 = () => {
3033
- return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
3034
- };
3035
- const StyledSpan = styled(Box)`
2943
+ const AccordionContentRadius = styled(Box)`
2944
+ border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
2945
+ `;
2946
+ const Rectangle = styled(Box)`
2947
+ width: ${({ theme }) => theme.spaces[2]};
2948
+ height: ${({ theme }) => theme.spaces[4]};
2949
+ `;
2950
+ const Preview$1 = styled.span`
3036
2951
  display: block;
2952
+ background-color: ${({ theme }) => theme.colors.primary100};
3037
2953
  outline: 1px dashed ${({ theme }) => theme.colors.primary500};
3038
2954
  outline-offset: -1px;
2955
+ padding: ${({ theme }) => theme.spaces[6]};
3039
2956
  `;
3040
- const ComponentInput = ({
2957
+ const ComponentContainer = styled(Box)`
2958
+ list-style: none;
2959
+ padding: 0;
2960
+ margin: 0;
2961
+ `;
2962
+ const DynamicZoneLabel = ({
2963
+ hint,
3041
2964
  label,
3042
- required,
2965
+ labelAction,
3043
2966
  name: name2,
2967
+ numberOfComponents = 0,
2968
+ required
2969
+ }) => {
2970
+ return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2971
+ Box,
2972
+ {
2973
+ paddingTop: 3,
2974
+ paddingBottom: 3,
2975
+ paddingRight: 4,
2976
+ paddingLeft: 4,
2977
+ borderRadius: "26px",
2978
+ background: "neutral0",
2979
+ shadow: "filterShadow",
2980
+ color: "neutral500",
2981
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
2982
+ /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
2983
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
2984
+ label || name2,
2985
+ " "
2986
+ ] }),
2987
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
2988
+ "(",
2989
+ numberOfComponents,
2990
+ ")"
2991
+ ] }),
2992
+ required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
2993
+ labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
2994
+ ] }),
2995
+ hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
2996
+ ] })
2997
+ }
2998
+ ) });
2999
+ };
3000
+ const [DynamicZoneProvider, useDynamicZone] = createContext(
3001
+ "DynamicZone",
3002
+ {
3003
+ isInDynamicZone: false
3004
+ }
3005
+ );
3006
+ const DynamicZone = ({
3044
3007
  attribute,
3045
- disabled,
3008
+ disabled: disabledProp,
3009
+ hint,
3010
+ label,
3046
3011
  labelAction,
3047
- ...props
3012
+ name: name2,
3013
+ required = false,
3014
+ children
3048
3015
  }) => {
3016
+ const { max = Infinity, min = -Infinity } = attribute ?? {};
3017
+ const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
3018
+ const [liveText, setLiveText] = React.useState("");
3019
+ const { components, isLoading } = useDoc();
3020
+ const disabled = disabledProp || isLoading;
3021
+ const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
3022
+ "DynamicZone",
3023
+ ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
3024
+ addFieldRow: addFieldRow2,
3025
+ removeFieldRow: removeFieldRow2,
3026
+ moveFieldRow: moveFieldRow2
3027
+ })
3028
+ );
3029
+ const { value = [], error } = useField(name2);
3030
+ const dynamicComponentsByCategory = React.useMemo(() => {
3031
+ return attribute.components.reduce((acc, componentUid) => {
3032
+ const { category, info } = components[componentUid] ?? { info: {} };
3033
+ const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
3034
+ if (!acc[category]) {
3035
+ acc[category] = [];
3036
+ }
3037
+ acc[category] = [...acc[category], component];
3038
+ return acc;
3039
+ }, {});
3040
+ }, [attribute.components, components]);
3049
3041
  const { formatMessage } = useIntl();
3050
- const field = useField(name2);
3051
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
3052
- const { components } = useDoc();
3053
- const handleInitialisationClick = () => {
3054
- const schema = components[attribute.component];
3042
+ const { toggleNotification } = useNotification();
3043
+ const dynamicDisplayedComponentsLength = value.length;
3044
+ const handleAddComponent = (uid, position) => {
3045
+ setAddComponentIsOpen(false);
3046
+ const schema = components[uid];
3055
3047
  const form = createDefaultForm(schema, components);
3056
- const data = transformDocument(schema, components)(form);
3057
- field.onChange(name2, data);
3048
+ const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
3049
+ ...data2,
3050
+ __component: uid
3051
+ }));
3052
+ const data = transformations(form);
3053
+ addFieldRow(name2, data, position);
3058
3054
  };
3059
- return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
3060
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3061
- /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
3062
- label,
3063
- attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
3064
- " (",
3065
- Array.isArray(field.value) ? field.value.length : 0,
3066
- ")"
3067
- ] })
3068
- ] }),
3069
- showResetComponent && /* @__PURE__ */ jsx(
3070
- IconButton,
3055
+ const handleClickOpenPicker = () => {
3056
+ if (dynamicDisplayedComponentsLength < max) {
3057
+ setAddComponentIsOpen((prev) => !prev);
3058
+ } else {
3059
+ toggleNotification({
3060
+ type: "info",
3061
+ message: formatMessage({
3062
+ id: getTranslation("components.notification.info.maximum-requirement")
3063
+ })
3064
+ });
3065
+ }
3066
+ };
3067
+ const handleMoveComponent = (newIndex, currentIndex) => {
3068
+ setLiveText(
3069
+ formatMessage(
3071
3070
  {
3072
- label: formatMessage({
3073
- id: getTranslation("components.reset-entry"),
3074
- defaultMessage: "Reset Entry"
3075
- }),
3076
- variant: "ghost",
3077
- onClick: () => {
3078
- field.onChange(name2, null);
3079
- },
3080
- children: /* @__PURE__ */ jsx(Trash, {})
3071
+ id: getTranslation("dnd.reorder"),
3072
+ defaultMessage: "{item}, moved. New position in list: {position}."
3073
+ },
3074
+ {
3075
+ item: `${name2}.${currentIndex}`,
3076
+ position: getItemPos(newIndex)
3081
3077
  }
3082
3078
  )
3083
- ] }),
3084
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
3085
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
3086
- attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
3087
- /* @__PURE__ */ jsx(Field.Error, {})
3088
- ] });
3089
- };
3090
- const MemoizedComponentInput = React.memo(ComponentInput);
3091
- const AddComponentButton = ({
3092
- hasError,
3093
- isDisabled,
3094
- isOpen,
3095
- children,
3096
- onClick
3097
- }) => {
3098
- return /* @__PURE__ */ jsx(
3099
- StyledButton,
3100
- {
3101
- type: "button",
3102
- onClick,
3103
- disabled: isDisabled,
3104
- background: "neutral0",
3105
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
3106
- variant: "tertiary",
3107
- children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
3108
- /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
3109
- /* @__PURE__ */ jsx(
3110
- AddComponentTitle,
3111
- {
3112
- variant: "pi",
3113
- fontWeight: "bold",
3114
- textColor: hasError && !isOpen ? "danger600" : "neutral500",
3115
- children
3116
- }
3117
- )
3118
- ] })
3119
- }
3120
- );
3121
- };
3122
- const StyledAddIcon = styled(PlusCircle)`
3123
- height: ${({ theme }) => theme.spaces[6]};
3124
- width: ${({ theme }) => theme.spaces[6]};
3125
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
3126
-
3127
- > circle {
3128
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
3129
- }
3130
- > path {
3131
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral600};
3132
- }
3133
- `;
3134
- const AddComponentTitle = styled(Typography)``;
3135
- const StyledButton = styled(Button)`
3136
- border-radius: 26px;
3137
- border-color: ${({ theme }) => theme.colors.neutral150};
3138
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
3139
- height: 5rem;
3140
-
3141
- &:hover {
3142
- ${AddComponentTitle} {
3143
- color: ${({ theme }) => theme.colors.primary600};
3144
- }
3145
-
3146
- ${StyledAddIcon} {
3147
- > circle {
3148
- fill: ${({ theme }) => theme.colors.primary600};
3149
- }
3150
- > path {
3151
- fill: ${({ theme }) => theme.colors.primary600};
3152
- }
3079
+ );
3080
+ moveFieldRow(name2, currentIndex, newIndex);
3081
+ };
3082
+ const getItemPos = (index) => `${index + 1} of ${value.length}`;
3083
+ const handleCancel = (index) => {
3084
+ setLiveText(
3085
+ formatMessage(
3086
+ {
3087
+ id: getTranslation("dnd.cancel-item"),
3088
+ defaultMessage: "{item}, dropped. Re-order cancelled."
3089
+ },
3090
+ {
3091
+ item: `${name2}.${index}`
3092
+ }
3093
+ )
3094
+ );
3095
+ };
3096
+ const handleGrabItem = (index) => {
3097
+ setLiveText(
3098
+ formatMessage(
3099
+ {
3100
+ id: getTranslation("dnd.grab-item"),
3101
+ defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
3102
+ },
3103
+ {
3104
+ item: `${name2}.${index}`,
3105
+ position: getItemPos(index)
3106
+ }
3107
+ )
3108
+ );
3109
+ };
3110
+ const handleDropItem = (index) => {
3111
+ setLiveText(
3112
+ formatMessage(
3113
+ {
3114
+ id: getTranslation("dnd.drop-item"),
3115
+ defaultMessage: `{item}, dropped. Final position in list: {position}.`
3116
+ },
3117
+ {
3118
+ item: `${name2}.${index}`,
3119
+ position: getItemPos(index)
3120
+ }
3121
+ )
3122
+ );
3123
+ };
3124
+ const handleRemoveComponent = (name22, currentIndex) => () => {
3125
+ removeFieldRow(name22, currentIndex);
3126
+ };
3127
+ const hasError = error !== void 0;
3128
+ const renderButtonLabel = () => {
3129
+ if (addComponentIsOpen) {
3130
+ return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
3153
3131
  }
3154
- }
3155
- &:active {
3156
- ${AddComponentTitle} {
3157
- color: ${({ theme }) => theme.colors.primary600};
3132
+ if (hasError && dynamicDisplayedComponentsLength > max) {
3133
+ return formatMessage(
3134
+ {
3135
+ id: getTranslation(`components.DynamicZone.extra-components`),
3136
+ defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
3137
+ },
3138
+ {
3139
+ number: dynamicDisplayedComponentsLength - max
3140
+ }
3141
+ );
3158
3142
  }
3159
- ${StyledAddIcon} {
3160
- > circle {
3161
- fill: ${({ theme }) => theme.colors.primary600};
3162
- }
3163
- > path {
3164
- fill: ${({ theme }) => theme.colors.neutral100};
3165
- }
3143
+ if (hasError && dynamicDisplayedComponentsLength < min) {
3144
+ return formatMessage(
3145
+ {
3146
+ id: getTranslation(`components.DynamicZone.missing-components`),
3147
+ defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
3148
+ },
3149
+ { number: min - dynamicDisplayedComponentsLength }
3150
+ );
3166
3151
  }
3167
- }
3168
- `;
3169
- const ComponentCategory = ({
3170
- category,
3171
- components = [],
3172
- variant = "primary",
3173
- onAddComponent
3174
- }) => {
3175
- const { formatMessage } = useIntl();
3176
- return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
3177
- /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
3178
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
3179
- ComponentBox,
3152
+ return formatMessage(
3180
3153
  {
3181
- tag: "button",
3182
- type: "button",
3183
- background: "neutral100",
3184
- justifyContent: "center",
3185
- onClick: onAddComponent(uid),
3186
- hasRadius: true,
3187
- height: "8.4rem",
3188
- shrink: 0,
3189
- borderColor: "neutral200",
3190
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
3191
- /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
3192
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
3193
- ] })
3154
+ id: getTranslation("components.DynamicZone.add-component"),
3155
+ defaultMessage: "Add a component to {componentName}"
3194
3156
  },
3195
- uid
3196
- )) }) })
3197
- ] });
3198
- };
3199
- const Grid = styled(Box)`
3200
- display: grid;
3201
- grid-template-columns: repeat(auto-fit, 14rem);
3202
- grid-gap: ${({ theme }) => theme.spaces[1]};
3203
- `;
3204
- const ComponentBox = styled(Flex)`
3205
- color: ${({ theme }) => theme.colors.neutral600};
3206
- cursor: pointer;
3207
-
3208
- @media (prefers-reduced-motion: no-preference) {
3209
- transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3210
- }
3211
-
3212
- &:focus,
3213
- &:hover {
3214
- border: 1px solid ${({ theme }) => theme.colors.primary200};
3215
- background: ${({ theme }) => theme.colors.primary100};
3216
- color: ${({ theme }) => theme.colors.primary600};
3217
- }
3218
- `;
3219
- const ComponentPicker = ({
3220
- dynamicComponentsByCategory = {},
3221
- isOpen,
3222
- onClickAddComponent
3223
- }) => {
3224
- const { formatMessage } = useIntl();
3225
- const handleAddComponentToDz = (componentUid) => () => {
3226
- onClickAddComponent(componentUid);
3157
+ { componentName: label || name2 }
3158
+ );
3227
3159
  };
3228
- if (!isOpen) {
3229
- return null;
3230
- }
3231
- return /* @__PURE__ */ jsxs(
3232
- Box,
3233
- {
3234
- paddingTop: 6,
3235
- paddingBottom: 6,
3236
- paddingLeft: 5,
3237
- paddingRight: 5,
3238
- background: "neutral0",
3239
- shadow: "tableShadow",
3240
- borderColor: "neutral150",
3241
- hasRadius: true,
3242
- children: [
3243
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
3244
- id: getTranslation("components.DynamicZone.ComponentPicker-label"),
3245
- defaultMessage: "Pick one component"
3246
- }) }) }),
3247
- /* @__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(
3248
- ComponentCategory,
3249
- {
3250
- category,
3251
- components,
3252
- onAddComponent: handleAddComponentToDz,
3253
- variant: index % 2 === 1 ? "primary" : "secondary"
3254
- },
3255
- category
3256
- )) }) })
3257
- ]
3258
- }
3259
- );
3160
+ const level = useComponent("DynamicZone", (state) => state.level);
3161
+ const ariaDescriptionId = React.useId();
3162
+ return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
3163
+ dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
3164
+ /* @__PURE__ */ jsx(
3165
+ DynamicZoneLabel,
3166
+ {
3167
+ hint,
3168
+ label,
3169
+ labelAction,
3170
+ name: name2,
3171
+ numberOfComponents: dynamicDisplayedComponentsLength,
3172
+ required
3173
+ }
3174
+ ),
3175
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
3176
+ id: getTranslation("dnd.instructions"),
3177
+ defaultMessage: `Press spacebar to grab and re-order`
3178
+ }) }),
3179
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
3180
+ /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
3181
+ ComponentProvider,
3182
+ {
3183
+ level: level + 1,
3184
+ uid: field.__component,
3185
+ id: field.id,
3186
+ type: "dynamiczone",
3187
+ children: /* @__PURE__ */ jsx(
3188
+ DynamicComponent,
3189
+ {
3190
+ disabled,
3191
+ name: name2,
3192
+ index,
3193
+ componentUid: field.__component,
3194
+ onMoveComponent: handleMoveComponent,
3195
+ onRemoveComponentClick: handleRemoveComponent(name2, index),
3196
+ onCancel: handleCancel,
3197
+ onDropItem: handleDropItem,
3198
+ onGrabItem: handleGrabItem,
3199
+ onAddComponent: handleAddComponent,
3200
+ dynamicComponentsByCategory,
3201
+ children
3202
+ }
3203
+ )
3204
+ },
3205
+ field.__temp_key__
3206
+ )) })
3207
+ ] }),
3208
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
3209
+ AddComponentButton,
3210
+ {
3211
+ hasError,
3212
+ isDisabled: disabled,
3213
+ isOpen: addComponentIsOpen,
3214
+ onClick: handleClickOpenPicker,
3215
+ children: renderButtonLabel()
3216
+ }
3217
+ ) }),
3218
+ /* @__PURE__ */ jsx(
3219
+ ComponentPicker,
3220
+ {
3221
+ dynamicComponentsByCategory,
3222
+ isOpen: addComponentIsOpen,
3223
+ onClickAddComponent: handleAddComponent
3224
+ }
3225
+ )
3226
+ ] }) });
3260
3227
  };
3261
3228
  const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3262
3229
  const { formatMessage } = useIntl();
@@ -3736,8 +3703,7 @@ const Wrapper = styled.div`
3736
3703
  `;
3737
3704
  var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, unorderedListRE = /[*+-]\s/;
3738
3705
  function newlineAndIndentContinueMarkdownList(cm) {
3739
- if (cm.getOption("disableInput"))
3740
- return CodeMirror.Pass;
3706
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
3741
3707
  var ranges = cm.listSelections(), replacements = [];
3742
3708
  for (var i = 0; i < ranges.length; i++) {
3743
3709
  var pos = ranges[i].head;
@@ -3771,8 +3737,7 @@ function newlineAndIndentContinueMarkdownList(cm) {
3771
3737
  var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
3772
3738
  var bullet = numbered ? parseInt(match[3], 10) + 1 + match[4] : match[2].replace("x", " ");
3773
3739
  replacements[i] = "\n" + indent + bullet + after;
3774
- if (numbered)
3775
- incrementRemainingMarkdownListNumbers(cm, pos);
3740
+ if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
3776
3741
  }
3777
3742
  }
3778
3743
  cm.replaceSelections(replacements);
@@ -3790,10 +3755,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3790
3755
  var newNumber = parseInt(startItem[3], 10) + lookAhead - skipCount;
3791
3756
  var nextNumber = parseInt(nextItem[3], 10), itemNumber = nextNumber;
3792
3757
  if (startIndent === nextIndent && !isNaN(nextNumber)) {
3793
- if (newNumber === nextNumber)
3794
- itemNumber = nextNumber + 1;
3795
- if (newNumber > nextNumber)
3796
- itemNumber = newNumber + 1;
3758
+ if (newNumber === nextNumber) itemNumber = nextNumber + 1;
3759
+ if (newNumber > nextNumber) itemNumber = newNumber + 1;
3797
3760
  cm.replaceRange(
3798
3761
  nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
3799
3762
  {
@@ -3806,10 +3769,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3806
3769
  }
3807
3770
  );
3808
3771
  } else {
3809
- if (startIndent.length > nextIndent.length)
3810
- return;
3811
- if (startIndent.length < nextIndent.length && lookAhead === 1)
3812
- return;
3772
+ if (startIndent.length > nextIndent.length) return;
3773
+ if (startIndent.length < nextIndent.length && lookAhead === 1) return;
3813
3774
  skipCount += 1;
3814
3775
  }
3815
3776
  }
@@ -4943,621 +4904,682 @@ const Wysiwyg = React.forwardRef(
4943
4904
  /* @__PURE__ */ jsx(MediaLibraryDialog, { onClose: handleToggleMediaLib, onSelectAssets: handleSelectAssets })
4944
4905
  ] });
4945
4906
  }
4946
- );
4947
- const MemoizedWysiwyg = React.memo(Wysiwyg);
4948
- const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4949
- const { id, document: document2, collectionType } = useDoc();
4950
- const isFormDisabled = useForm("InputRenderer", (state) => state.disabled);
4951
- const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4952
- const canCreateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4953
- const canReadFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4954
- const canUpdateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4955
- const canUserAction = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4956
- let idToCheck = id;
4957
- if (collectionType === SINGLE_TYPES) {
4958
- idToCheck = document2?.documentId;
4907
+ );
4908
+ const MemoizedWysiwyg = React.memo(Wysiwyg);
4909
+ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4910
+ const { id, document: document2, collectionType } = useDoc();
4911
+ const isFormDisabled = useForm("InputRenderer", (state) => state.disabled);
4912
+ const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4913
+ const canCreateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4914
+ const canReadFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4915
+ const canUpdateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4916
+ const canUserAction = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4917
+ let idToCheck = id;
4918
+ if (collectionType === SINGLE_TYPES) {
4919
+ idToCheck = document2?.documentId;
4920
+ }
4921
+ const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4922
+ const readableFields = idToCheck ? canReadFields : canCreateFields;
4923
+ const canUserReadField = canUserAction(props.name, readableFields, props.type);
4924
+ const canUserEditField = canUserAction(props.name, editableFields, props.type);
4925
+ const fields = useStrapiApp("InputRenderer", (app) => app.fields);
4926
+ const { lazyComponentStore } = useLazyComponents(
4927
+ attributeHasCustomFieldProperty(props.attribute) ? [props.attribute.customField] : void 0
4928
+ );
4929
+ const hint = useFieldHint(providedHint, props.attribute);
4930
+ const {
4931
+ edit: { components }
4932
+ } = useDocLayout();
4933
+ const field = useField(props.name);
4934
+ if (!visible) {
4935
+ return null;
4936
+ }
4937
+ if (!canUserReadField && !isInDynamicZone) {
4938
+ return /* @__PURE__ */ jsx(NotAllowedInput, { hint, ...props });
4939
+ }
4940
+ const fieldIsDisabled = !canUserEditField && !isInDynamicZone || props.disabled || isFormDisabled;
4941
+ if (attributeHasCustomFieldProperty(props.attribute)) {
4942
+ const CustomInput = lazyComponentStore[props.attribute.customField];
4943
+ if (CustomInput) {
4944
+ return /* @__PURE__ */ jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
4945
+ }
4946
+ return /* @__PURE__ */ jsx(
4947
+ InputRenderer$1,
4948
+ {
4949
+ ...props,
4950
+ hint,
4951
+ type: props.attribute.customField,
4952
+ disabled: fieldIsDisabled
4953
+ }
4954
+ );
4955
+ }
4956
+ const addedInputTypes = Object.keys(fields);
4957
+ if (!attributeHasCustomFieldProperty(props.attribute) && addedInputTypes.includes(props.type)) {
4958
+ const CustomInput = fields[props.type];
4959
+ return /* @__PURE__ */ jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
4960
+ }
4961
+ switch (props.type) {
4962
+ case "blocks":
4963
+ return /* @__PURE__ */ jsx(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4964
+ case "component":
4965
+ return /* @__PURE__ */ jsx(
4966
+ MemoizedComponentInput,
4967
+ {
4968
+ ...props,
4969
+ hint,
4970
+ layout: components[props.attribute.component].layout,
4971
+ disabled: fieldIsDisabled,
4972
+ children: (inputProps) => /* @__PURE__ */ jsx(InputRenderer, { ...inputProps })
4973
+ }
4974
+ );
4975
+ case "dynamiczone":
4976
+ return /* @__PURE__ */ jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
4977
+ case "relation":
4978
+ return /* @__PURE__ */ jsx(MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
4979
+ case "richtext":
4980
+ return /* @__PURE__ */ jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4981
+ case "uid":
4982
+ return /* @__PURE__ */ jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4983
+ case "enumeration":
4984
+ return /* @__PURE__ */ jsx(
4985
+ InputRenderer$1,
4986
+ {
4987
+ ...props,
4988
+ hint,
4989
+ options: props.attribute.enum.map((value) => ({ value })),
4990
+ type: props.customField ? "custom-field" : props.type,
4991
+ disabled: fieldIsDisabled
4992
+ }
4993
+ );
4994
+ default:
4995
+ const { unique: _unique, mainField: _mainField, ...restProps } = props;
4996
+ return /* @__PURE__ */ jsx(
4997
+ InputRenderer$1,
4998
+ {
4999
+ ...restProps,
5000
+ hint,
5001
+ type: props.customField ? "custom-field" : props.type,
5002
+ disabled: fieldIsDisabled
5003
+ }
5004
+ );
5005
+ }
5006
+ };
5007
+ const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5008
+ const useFieldHint = (hint = void 0, attribute) => {
5009
+ const { formatMessage } = useIntl();
5010
+ const { maximum, minimum } = getMinMax(attribute);
5011
+ if (!maximum && !minimum) {
5012
+ return hint;
4959
5013
  }
4960
- const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4961
- const readableFields = idToCheck ? canReadFields : canCreateFields;
4962
- const canUserReadField = canUserAction(props.name, readableFields, props.type);
4963
- const canUserEditField = canUserAction(props.name, editableFields, props.type);
4964
- const fields = useStrapiApp("InputRenderer", (app) => app.fields);
4965
- const { lazyComponentStore } = useLazyComponents(
4966
- attributeHasCustomFieldProperty(props.attribute) ? [props.attribute.customField] : void 0
5014
+ const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5015
+ attribute.type
5016
+ ) ? formatMessage(
5017
+ {
5018
+ id: "content-manager.form.Input.hint.character.unit",
5019
+ defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5020
+ },
5021
+ {
5022
+ maxValue: Math.max(minimum || 0, maximum || 0)
5023
+ }
5024
+ ) : null;
5025
+ const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5026
+ return formatMessage(
5027
+ {
5028
+ id: "content-manager.form.Input.hint.text",
5029
+ defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5030
+ },
5031
+ {
5032
+ min: minimum,
5033
+ max: maximum,
5034
+ description: hint,
5035
+ unit: units,
5036
+ divider: hasMinAndMax ? formatMessage({
5037
+ id: "content-manager.form.Input.hint.minMaxDivider",
5038
+ defaultMessage: " / "
5039
+ }) : null,
5040
+ br: /* @__PURE__ */ jsx("br", {})
5041
+ }
4967
5042
  );
4968
- const hint = useFieldHint(providedHint, props.attribute);
4969
- const {
4970
- edit: { components }
4971
- } = useDocLayout();
4972
- const field = useField(props.name);
4973
- if (!visible) {
4974
- return null;
5043
+ };
5044
+ const getMinMax = (attribute) => {
5045
+ if ("min" in attribute || "max" in attribute) {
5046
+ return {
5047
+ maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5048
+ minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5049
+ };
5050
+ } else if ("maxLength" in attribute || "minLength" in attribute) {
5051
+ return { maximum: attribute.maxLength, minimum: attribute.minLength };
5052
+ } else {
5053
+ return { maximum: void 0, minimum: void 0 };
4975
5054
  }
4976
- if (!canUserReadField && !isInDynamicZone) {
4977
- return /* @__PURE__ */ jsx(NotAllowedInput, { hint, ...props });
5055
+ };
5056
+ const MemoizedInputRenderer = memo(InputRenderer);
5057
+ const RESPONSIVE_CONTAINER_BREAKPOINTS = {
5058
+ sm: "27.5rem"
5059
+ // 440px
5060
+ };
5061
+ const ResponsiveGridRoot = styled(Grid$1.Root)`
5062
+ container-type: inline-size;
5063
+ `;
5064
+ const ResponsiveGridItem = styled(Grid$1.Item)`
5065
+ grid-column: span 12;
5066
+
5067
+ @container (min-width: ${RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
5068
+ ${({ col }) => col && `grid-column: span ${col};`}
4978
5069
  }
4979
- const fieldIsDisabled = !canUserEditField && !isInDynamicZone || props.disabled || isFormDisabled;
4980
- if (attributeHasCustomFieldProperty(props.attribute)) {
4981
- const CustomInput = lazyComponentStore[props.attribute.customField];
4982
- if (CustomInput) {
4983
- return /* @__PURE__ */ jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
5070
+ `;
5071
+ const FormLayout = ({ layout }) => {
5072
+ const { formatMessage } = useIntl();
5073
+ const { model } = useDoc();
5074
+ return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((panel, index) => {
5075
+ if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) {
5076
+ const [row] = panel;
5077
+ const [field] = row;
5078
+ const fieldWithTranslatedLabel = {
5079
+ ...field,
5080
+ label: formatMessage({
5081
+ id: `content-manager.content-types.${model}.${field.name}`,
5082
+ defaultMessage: field.label
5083
+ })
5084
+ };
5085
+ 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);
4984
5086
  }
4985
5087
  return /* @__PURE__ */ jsx(
4986
- InputRenderer$1,
5088
+ Box,
4987
5089
  {
4988
- ...props,
4989
- hint,
4990
- type: props.attribute.customField,
4991
- disabled: fieldIsDisabled
5090
+ hasRadius: true,
5091
+ background: "neutral0",
5092
+ shadow: "tableShadow",
5093
+ paddingLeft: 6,
5094
+ paddingRight: 6,
5095
+ paddingTop: 6,
5096
+ paddingBottom: 6,
5097
+ borderColor: "neutral150",
5098
+ 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 }) => {
5099
+ const fieldWithTranslatedLabel = {
5100
+ ...field,
5101
+ label: formatMessage({
5102
+ id: `content-manager.content-types.${model}.${field.name}`,
5103
+ defaultMessage: field.label
5104
+ })
5105
+ };
5106
+ return /* @__PURE__ */ jsx(
5107
+ ResponsiveGridItem,
5108
+ {
5109
+ col: size,
5110
+ s: 12,
5111
+ xs: 12,
5112
+ direction: "column",
5113
+ alignItems: "stretch",
5114
+ children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel })
5115
+ },
5116
+ field.name
5117
+ );
5118
+ }) }, gridRowIndex)) })
5119
+ },
5120
+ index
5121
+ );
5122
+ }) });
5123
+ };
5124
+ const NonRepeatableComponent = ({
5125
+ attribute,
5126
+ name: name2,
5127
+ children,
5128
+ layout
5129
+ }) => {
5130
+ const { formatMessage } = useIntl();
5131
+ const { value } = useField(name2);
5132
+ const level = useComponent("NonRepeatableComponent", (state) => state.level);
5133
+ const isNested = level > 0;
5134
+ return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
5135
+ Box,
5136
+ {
5137
+ background: "neutral100",
5138
+ paddingLeft: 6,
5139
+ paddingRight: 6,
5140
+ paddingTop: 6,
5141
+ paddingBottom: 6,
5142
+ hasRadius: isNested,
5143
+ borderColor: isNested ? "neutral200" : void 0,
5144
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
5145
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5146
+ const completeFieldName = `${name2}.${field.name}`;
5147
+ const translatedLabel = formatMessage({
5148
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5149
+ defaultMessage: field.label
5150
+ });
5151
+ return /* @__PURE__ */ jsx(
5152
+ ResponsiveGridItem,
5153
+ {
5154
+ col: size,
5155
+ s: 12,
5156
+ xs: 12,
5157
+ direction: "column",
5158
+ alignItems: "stretch",
5159
+ children: children({ ...field, label: translatedLabel, name: completeFieldName })
5160
+ },
5161
+ completeFieldName
5162
+ );
5163
+ }) }, index);
5164
+ }) })
5165
+ }
5166
+ ) });
5167
+ };
5168
+ const RepeatableComponent = ({
5169
+ attribute,
5170
+ disabled,
5171
+ name: name2,
5172
+ mainField,
5173
+ children,
5174
+ layout
5175
+ }) => {
5176
+ const { toggleNotification } = useNotification();
5177
+ const { formatMessage } = useIntl();
5178
+ const { search: searchString } = useLocation();
5179
+ const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
5180
+ const { components } = useDoc();
5181
+ const {
5182
+ value = [],
5183
+ error,
5184
+ rawError
5185
+ } = useField(name2);
5186
+ const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
5187
+ const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
5188
+ const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
5189
+ const { max = Infinity } = attribute;
5190
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
5191
+ const [liveText, setLiveText] = React.useState("");
5192
+ React.useEffect(() => {
5193
+ const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
5194
+ const hasNestedValue = value && Array.isArray(value) && value.length > 0;
5195
+ if (hasNestedErrors && hasNestedValue) {
5196
+ const errorOpenItems = rawError.map((_, idx) => {
5197
+ return value[idx] ? value[idx].__temp_key__ : null;
5198
+ }).filter((value2) => !!value2);
5199
+ if (errorOpenItems && errorOpenItems.length > 0) {
5200
+ setCollapseToOpen((collapseToOpen2) => {
5201
+ if (!errorOpenItems.includes(collapseToOpen2)) {
5202
+ return errorOpenItems[0];
5203
+ }
5204
+ return collapseToOpen2;
5205
+ });
5206
+ }
5207
+ }
5208
+ }, [rawError, value]);
5209
+ const componentTmpKeyWithFocussedField = React.useMemo(() => {
5210
+ if (search.has("field")) {
5211
+ const fieldParam = search.get("field");
5212
+ if (!fieldParam) {
5213
+ return void 0;
5214
+ }
5215
+ const [, path] = fieldParam.split(`${name2}.`);
5216
+ if (getIn(value, path, void 0) !== void 0) {
5217
+ const [subpath] = path.split(".");
5218
+ return getIn(value, subpath, void 0)?.__temp_key__;
4992
5219
  }
5220
+ }
5221
+ return void 0;
5222
+ }, [search, name2, value]);
5223
+ const prevValue = usePrev(value);
5224
+ React.useEffect(() => {
5225
+ if (prevValue && prevValue.length < value.length) {
5226
+ setCollapseToOpen(value[value.length - 1].__temp_key__);
5227
+ }
5228
+ }, [value, prevValue]);
5229
+ React.useEffect(() => {
5230
+ if (typeof componentTmpKeyWithFocussedField === "string") {
5231
+ setCollapseToOpen(componentTmpKeyWithFocussedField);
5232
+ }
5233
+ }, [componentTmpKeyWithFocussedField]);
5234
+ const toggleCollapses = () => {
5235
+ setCollapseToOpen("");
5236
+ };
5237
+ const handleClick = () => {
5238
+ if (value.length < max) {
5239
+ const schema = components[attribute.component];
5240
+ const form = createDefaultForm(schema, components);
5241
+ const data = transformDocument(schema, components)(form);
5242
+ addFieldRow(name2, data);
5243
+ } else if (value.length >= max) {
5244
+ toggleNotification({
5245
+ type: "info",
5246
+ message: formatMessage({
5247
+ id: getTranslation("components.notification.info.maximum-requirement")
5248
+ })
5249
+ });
5250
+ }
5251
+ };
5252
+ const handleMoveComponentField = (newIndex, currentIndex) => {
5253
+ setLiveText(
5254
+ formatMessage(
5255
+ {
5256
+ id: getTranslation("dnd.reorder"),
5257
+ defaultMessage: "{item}, moved. New position in list: {position}."
5258
+ },
5259
+ {
5260
+ item: `${name2}.${currentIndex}`,
5261
+ position: getItemPos(newIndex)
5262
+ }
5263
+ )
4993
5264
  );
4994
- }
4995
- const addedInputTypes = Object.keys(fields);
4996
- if (!attributeHasCustomFieldProperty(props.attribute) && addedInputTypes.includes(props.type)) {
4997
- const CustomInput = fields[props.type];
4998
- return /* @__PURE__ */ jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
4999
- }
5000
- switch (props.type) {
5001
- case "blocks":
5002
- return /* @__PURE__ */ jsx(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5003
- case "component":
5004
- return /* @__PURE__ */ jsx(
5005
- MemoizedComponentInput,
5265
+ moveFieldRow(name2, currentIndex, newIndex);
5266
+ };
5267
+ const handleValueChange = (key) => {
5268
+ setCollapseToOpen(key);
5269
+ };
5270
+ const getItemPos = (index) => `${index + 1} of ${value.length}`;
5271
+ const handleCancel = (index) => {
5272
+ setLiveText(
5273
+ formatMessage(
5006
5274
  {
5007
- ...props,
5008
- hint,
5009
- layout: components[props.attribute.component].layout,
5010
- disabled: fieldIsDisabled,
5011
- children: (inputProps) => /* @__PURE__ */ jsx(InputRenderer, { ...inputProps })
5275
+ id: getTranslation("dnd.cancel-item"),
5276
+ defaultMessage: "{item}, dropped. Re-order cancelled."
5277
+ },
5278
+ {
5279
+ item: `${name2}.${index}`
5012
5280
  }
5013
- );
5014
- case "dynamiczone":
5015
- return /* @__PURE__ */ jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
5016
- case "relation":
5017
- return /* @__PURE__ */ jsx(MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
5018
- case "richtext":
5019
- return /* @__PURE__ */ jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5020
- case "uid":
5021
- return /* @__PURE__ */ jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5022
- case "enumeration":
5023
- return /* @__PURE__ */ jsx(
5024
- InputRenderer$1,
5281
+ )
5282
+ );
5283
+ };
5284
+ const handleGrabItem = (index) => {
5285
+ setLiveText(
5286
+ formatMessage(
5025
5287
  {
5026
- ...props,
5027
- hint,
5028
- options: props.attribute.enum.map((value) => ({ value })),
5029
- type: props.customField ? "custom-field" : props.type,
5030
- disabled: fieldIsDisabled
5288
+ id: getTranslation("dnd.grab-item"),
5289
+ defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5290
+ },
5291
+ {
5292
+ item: `${name2}.${index}`,
5293
+ position: getItemPos(index)
5031
5294
  }
5032
- );
5033
- default:
5034
- const { unique: _unique, mainField: _mainField, ...restProps } = props;
5035
- return /* @__PURE__ */ jsx(
5036
- InputRenderer$1,
5295
+ )
5296
+ );
5297
+ };
5298
+ const handleDropItem = (index) => {
5299
+ setLiveText(
5300
+ formatMessage(
5037
5301
  {
5038
- ...restProps,
5039
- hint,
5040
- type: props.customField ? "custom-field" : props.type,
5041
- disabled: fieldIsDisabled
5302
+ id: getTranslation("dnd.drop-item"),
5303
+ defaultMessage: `{item}, dropped. Final position in list: {position}.`
5304
+ },
5305
+ {
5306
+ item: `${name2}.${index}`,
5307
+ position: getItemPos(index)
5042
5308
  }
5043
- );
5309
+ )
5310
+ );
5311
+ };
5312
+ const ariaDescriptionId = React.useId();
5313
+ const level = useComponent("RepeatableComponent", (state) => state.level);
5314
+ if (value.length === 0) {
5315
+ return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
5044
5316
  }
5317
+ return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
5318
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5319
+ id: getTranslation("dnd.instructions"),
5320
+ defaultMessage: `Press spacebar to grab and re-order`
5321
+ }) }),
5322
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5323
+ /* @__PURE__ */ jsxs(
5324
+ AccordionRoot,
5325
+ {
5326
+ $error: error,
5327
+ value: collapseToOpen,
5328
+ onValueChange: handleValueChange,
5329
+ "aria-describedby": ariaDescriptionId,
5330
+ children: [
5331
+ value.map(({ __temp_key__: key, id }, index) => {
5332
+ const nameWithIndex = `${name2}.${index}`;
5333
+ return /* @__PURE__ */ jsx(
5334
+ ComponentProvider,
5335
+ {
5336
+ id,
5337
+ uid: attribute.component,
5338
+ level: level + 1,
5339
+ type: "repeatable",
5340
+ children: /* @__PURE__ */ jsx(
5341
+ Component,
5342
+ {
5343
+ disabled,
5344
+ name: nameWithIndex,
5345
+ attribute,
5346
+ index,
5347
+ mainField,
5348
+ onMoveItem: handleMoveComponentField,
5349
+ onDeleteComponent: () => {
5350
+ removeFieldRow(name2, index);
5351
+ toggleCollapses();
5352
+ },
5353
+ toggleCollapses,
5354
+ onCancel: handleCancel,
5355
+ onDropItem: handleDropItem,
5356
+ onGrabItem: handleGrabItem,
5357
+ __temp_key__: key,
5358
+ children: layout.map((row, index2) => {
5359
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5360
+ const completeFieldName = `${nameWithIndex}.${field.name}`;
5361
+ const translatedLabel = formatMessage({
5362
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5363
+ defaultMessage: field.label
5364
+ });
5365
+ return /* @__PURE__ */ jsx(
5366
+ ResponsiveGridItem,
5367
+ {
5368
+ col: size,
5369
+ s: 12,
5370
+ xs: 12,
5371
+ direction: "column",
5372
+ alignItems: "stretch",
5373
+ children: children({
5374
+ ...field,
5375
+ label: translatedLabel,
5376
+ name: completeFieldName
5377
+ })
5378
+ },
5379
+ completeFieldName
5380
+ );
5381
+ }) }, index2);
5382
+ })
5383
+ }
5384
+ )
5385
+ },
5386
+ key
5387
+ );
5388
+ }),
5389
+ /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
5390
+ id: getTranslation("containers.EditView.add.new-entry"),
5391
+ defaultMessage: "Add an entry"
5392
+ }) })
5393
+ ]
5394
+ }
5395
+ )
5396
+ ] });
5045
5397
  };
5046
- const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5047
- const useFieldHint = (hint = void 0, attribute) => {
5048
- const { formatMessage } = useIntl();
5049
- const { maximum, minimum } = getMinMax(attribute);
5050
- if (!maximum && !minimum) {
5051
- return hint;
5052
- }
5053
- const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5054
- attribute.type
5055
- ) ? formatMessage(
5056
- {
5057
- id: "content-manager.form.Input.hint.character.unit",
5058
- defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5059
- },
5060
- {
5061
- maxValue: Math.max(minimum || 0, maximum || 0)
5062
- }
5063
- ) : null;
5064
- const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5065
- return formatMessage(
5066
- {
5067
- id: "content-manager.form.Input.hint.text",
5068
- defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5069
- },
5070
- {
5071
- min: minimum,
5072
- max: maximum,
5073
- description: hint,
5074
- unit: units,
5075
- divider: hasMinAndMax ? formatMessage({
5076
- id: "content-manager.form.Input.hint.minMaxDivider",
5077
- defaultMessage: " / "
5078
- }) : null,
5079
- br: /* @__PURE__ */ jsx("br", {})
5398
+ const AccordionRoot = styled(Accordion.Root)`
5399
+ border: 1px solid
5400
+ ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
5401
+ `;
5402
+ const TextButtonCustom = styled(TextButton)`
5403
+ width: 100%;
5404
+ display: flex;
5405
+ justify-content: center;
5406
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
5407
+ padding-inline: ${(props) => props.theme.spaces[6]};
5408
+ padding-block: ${(props) => props.theme.spaces[3]};
5409
+
5410
+ &:not([disabled]) {
5411
+ cursor: pointer;
5412
+
5413
+ &:hover {
5414
+ background-color: ${(props) => props.theme.colors.primary100};
5080
5415
  }
5081
- );
5082
- };
5083
- const getMinMax = (attribute) => {
5084
- if ("min" in attribute || "max" in attribute) {
5085
- return {
5086
- maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5087
- minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5088
- };
5089
- } else if ("maxLength" in attribute || "minLength" in attribute) {
5090
- return { maximum: attribute.maxLength, minimum: attribute.minLength };
5091
- } else {
5092
- return { maximum: void 0, minimum: void 0 };
5093
5416
  }
5094
- };
5095
- const MemoizedInputRenderer = memo(InputRenderer);
5096
- const DynamicComponent = ({
5097
- componentUid,
5417
+
5418
+ span {
5419
+ font-weight: 600;
5420
+ font-size: 1.4rem;
5421
+ line-height: 2.4rem;
5422
+ }
5423
+
5424
+ @media (prefers-reduced-motion: no-preference) {
5425
+ transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
5426
+ }
5427
+ `;
5428
+ const Component = ({
5098
5429
  disabled,
5099
- index,
5100
- name: name2,
5101
- onRemoveComponentClick,
5102
- onMoveComponent,
5103
- onGrabItem,
5104
- onDropItem,
5105
- onCancel,
5106
- dynamicComponentsByCategory = {},
5107
- onAddComponent
5430
+ index,
5431
+ name: name2,
5432
+ mainField = {
5433
+ name: "id",
5434
+ type: "integer"
5435
+ },
5436
+ children,
5437
+ onDeleteComponent,
5438
+ toggleCollapses,
5439
+ __temp_key__,
5440
+ ...dragProps
5108
5441
  }) => {
5109
5442
  const { formatMessage } = useIntl();
5110
- const formValues = useForm("DynamicComponent", (state) => state.values);
5111
- const {
5112
- edit: { components }
5113
- } = useDocLayout();
5114
- const title = React.useMemo(() => {
5115
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
5116
- const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
5117
- const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
5118
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
5119
- return mainValue;
5120
- }, [componentUid, components, formValues, name2, index]);
5121
- const { icon, displayName } = React.useMemo(() => {
5122
- const [category] = componentUid.split(".");
5123
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
5124
- (component) => component.uid === componentUid
5125
- ) ?? { icon: null, displayName: null };
5126
- return { icon: icon2, displayName: displayName2 };
5127
- }, [componentUid, dynamicComponentsByCategory]);
5443
+ const displayValue = useForm("RepeatableComponent", (state) => {
5444
+ return getIn(state.values, [...name2.split("."), mainField.name]);
5445
+ });
5446
+ const accordionRef = React.useRef(null);
5447
+ const componentKey = name2.split(".").slice(0, -1).join(".");
5128
5448
  const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
5129
- type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
5449
+ type: `${ItemTypes.COMPONENT}_${componentKey}`,
5130
5450
  index,
5131
5451
  item: {
5132
5452
  index,
5133
- displayedValue: `${displayName} ${title}`,
5134
- icon
5453
+ displayedValue: displayValue
5135
5454
  },
5136
- onMoveItem: onMoveComponent,
5137
- onDropItem,
5138
- onGrabItem,
5139
- onCancel
5455
+ onStart() {
5456
+ toggleCollapses();
5457
+ },
5458
+ ...dragProps
5140
5459
  });
5141
5460
  React.useEffect(() => {
5142
5461
  dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
5143
5462
  }, [dragPreviewRef, index]);
5144
- const accordionValue = React.useId();
5145
- const { value = [], rawError } = useField(`${name2}.${index}`);
5146
- const [collapseToOpen, setCollapseToOpen] = React.useState("");
5147
- React.useEffect(() => {
5148
- if (rawError && value) {
5149
- setCollapseToOpen(accordionValue);
5150
- }
5151
- }, [rawError, value, accordionValue]);
5152
- const composedBoxRefs = useComposedRefs(boxRef, dropRef);
5153
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
5154
- /* @__PURE__ */ jsx(
5155
- IconButton,
5156
- {
5157
- variant: "ghost",
5158
- label: formatMessage(
5463
+ const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
5464
+ const composedBoxRefs = useComposedRefs(
5465
+ boxRef,
5466
+ dropRef
5467
+ );
5468
+ return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
5469
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5470
+ /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
5471
+ /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
5472
+ /* @__PURE__ */ jsx(
5473
+ IconButton,
5159
5474
  {
5160
- id: getTranslation("components.DynamicZone.delete-label"),
5161
- defaultMessage: "Delete {name}"
5162
- },
5163
- { name: title }
5475
+ variant: "ghost",
5476
+ onClick: onDeleteComponent,
5477
+ label: formatMessage({
5478
+ id: getTranslation("containers.Edit.delete"),
5479
+ defaultMessage: "Delete"
5480
+ }),
5481
+ children: /* @__PURE__ */ jsx(Trash, {})
5482
+ }
5164
5483
  ),
5165
- onClick: onRemoveComponentClick,
5166
- children: /* @__PURE__ */ jsx(Trash, {})
5167
- }
5168
- ),
5169
- /* @__PURE__ */ jsx(
5170
- IconButton,
5171
- {
5172
- variant: "ghost",
5173
- onClick: (e) => e.stopPropagation(),
5174
- "data-handler-id": handlerId,
5175
- ref: dragRef,
5176
- label: formatMessage({
5177
- id: getTranslation("components.DragHandle-label"),
5178
- defaultMessage: "Drag"
5179
- }),
5180
- onKeyDown: handleKeyDown,
5181
- children: /* @__PURE__ */ jsx(Drag, {})
5182
- }
5183
- ),
5184
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
5185
- /* @__PURE__ */ jsxs(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
5186
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
5187
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage({
5188
- id: getTranslation("components.DynamicZone.more-actions"),
5189
- defaultMessage: "More actions"
5190
- }) })
5191
- ] }),
5192
- /* @__PURE__ */ jsxs(Menu.Content, { children: [
5193
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5194
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5195
- id: getTranslation("components.DynamicZone.add-item-above"),
5196
- defaultMessage: "Add component above"
5197
- }) }),
5198
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5199
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5200
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
5201
- ] }, category)) })
5202
- ] }),
5203
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5204
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5205
- id: getTranslation("components.DynamicZone.add-item-below"),
5206
- defaultMessage: "Add component below"
5207
- }) }),
5208
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5209
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5210
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
5211
- ] }, category)) })
5212
- ] })
5213
- ] })
5214
- ] })
5215
- ] });
5216
- const accordionTitle = title ? `${displayName} ${title}` : displayName;
5217
- return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
5218
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
5219
- /* @__PURE__ */ jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsx(Accordion.Root, { value: collapseToOpen, onValueChange: setCollapseToOpen, children: /* @__PURE__ */ jsxs(Accordion.Item, { value: accordionValue, children: [
5220
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5221
5484
  /* @__PURE__ */ jsx(
5222
- Accordion.Trigger,
5485
+ IconButton,
5223
5486
  {
5224
- icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
5225
- children: accordionTitle
5487
+ ref: composedAccordionRefs,
5488
+ variant: "ghost",
5489
+ onClick: (e) => e.stopPropagation(),
5490
+ "data-handler-id": handlerId,
5491
+ label: formatMessage({
5492
+ id: getTranslation("components.DragHandle-label"),
5493
+ defaultMessage: "Drag"
5494
+ }),
5495
+ onKeyDown: handleKeyDown,
5496
+ children: /* @__PURE__ */ jsx(Drag, {})
5226
5497
  }
5227
- ),
5228
- /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
5229
- ] }),
5230
- /* @__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(
5231
- Grid$1.Item,
5232
- {
5233
- col: 12,
5234
- s: 12,
5235
- xs: 12,
5236
- direction: "column",
5237
- alignItems: "stretch",
5238
- children: /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
5239
- const fieldName = `${name2}.${index}.${field.name}`;
5240
- return /* @__PURE__ */ jsx(
5241
- Grid$1.Item,
5242
- {
5243
- col: size,
5244
- s: 12,
5245
- xs: 12,
5246
- direction: "column",
5247
- alignItems: "stretch",
5248
- children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...field, name: fieldName })
5249
- },
5250
- fieldName
5251
- );
5252
- }) })
5253
- },
5254
- rowInd
5255
- )) }) }) }) })
5256
- ] }) }) })
5257
- ] });
5258
- };
5259
- const StyledBox = styled(Box)`
5260
- > div:first-child {
5261
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5262
- }
5263
- `;
5264
- const AccordionContentRadius = styled(Box)`
5265
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5266
- `;
5267
- const Rectangle = styled(Box)`
5268
- width: ${({ theme }) => theme.spaces[2]};
5269
- height: ${({ theme }) => theme.spaces[4]};
5270
- `;
5271
- const Preview = styled.span`
5272
- display: block;
5273
- background-color: ${({ theme }) => theme.colors.primary100};
5274
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5275
- outline-offset: -1px;
5276
- padding: ${({ theme }) => theme.spaces[6]};
5277
- `;
5278
- const ComponentContainer = styled(Box)`
5279
- list-style: none;
5280
- padding: 0;
5281
- margin: 0;
5282
- `;
5283
- const DynamicZoneLabel = ({
5284
- hint,
5285
- label,
5286
- labelAction,
5287
- name: name2,
5288
- numberOfComponents = 0,
5289
- required
5290
- }) => {
5291
- return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5292
- Box,
5293
- {
5294
- paddingTop: 3,
5295
- paddingBottom: 3,
5296
- paddingRight: 4,
5297
- paddingLeft: 4,
5298
- borderRadius: "26px",
5299
- background: "neutral0",
5300
- shadow: "filterShadow",
5301
- color: "neutral500",
5302
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
5303
- /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
5304
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5305
- label || name2,
5306
- " "
5307
- ] }),
5308
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5309
- "(",
5310
- numberOfComponents,
5311
- ")"
5312
- ] }),
5313
- required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
5314
- labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
5315
- ] }),
5316
- hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
5498
+ )
5317
5499
  ] })
5318
- }
5319
- ) });
5320
- };
5321
- const [DynamicZoneProvider, useDynamicZone] = createContext(
5322
- "DynamicZone",
5323
- {
5324
- isInDynamicZone: false
5325
- }
5326
- );
5327
- const DynamicZone = ({
5328
- attribute,
5329
- disabled: disabledProp,
5330
- hint,
5500
+ ] }),
5501
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
5502
+ Flex,
5503
+ {
5504
+ direction: "column",
5505
+ alignItems: "stretch",
5506
+ background: "neutral100",
5507
+ padding: 6,
5508
+ gap: 6,
5509
+ children
5510
+ }
5511
+ ) })
5512
+ ] }) });
5513
+ };
5514
+ const Preview = () => {
5515
+ return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
5516
+ };
5517
+ const StyledSpan = styled(Box)`
5518
+ display: block;
5519
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5520
+ outline-offset: -1px;
5521
+ `;
5522
+ const ComponentInput = ({
5331
5523
  label,
5332
- labelAction,
5524
+ required,
5333
5525
  name: name2,
5334
- required = false
5526
+ attribute,
5527
+ disabled,
5528
+ labelAction,
5529
+ ...props
5335
5530
  }) => {
5336
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5337
- const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
5338
- const [liveText, setLiveText] = React.useState("");
5339
- const { components, isLoading } = useDoc();
5340
- const disabled = disabledProp || isLoading;
5341
- const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
5342
- "DynamicZone",
5343
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5344
- addFieldRow: addFieldRow2,
5345
- removeFieldRow: removeFieldRow2,
5346
- moveFieldRow: moveFieldRow2
5347
- })
5348
- );
5349
- const { value = [], error } = useField(name2);
5350
- const dynamicComponentsByCategory = React.useMemo(() => {
5351
- return attribute.components.reduce((acc, componentUid) => {
5352
- const { category, info } = components[componentUid] ?? { info: {} };
5353
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5354
- if (!acc[category]) {
5355
- acc[category] = [];
5356
- }
5357
- acc[category] = [...acc[category], component];
5358
- return acc;
5359
- }, {});
5360
- }, [attribute.components, components]);
5361
5531
  const { formatMessage } = useIntl();
5362
- const { toggleNotification } = useNotification();
5363
- const dynamicDisplayedComponentsLength = value.length;
5364
- const handleAddComponent = (uid, position) => {
5365
- setAddComponentIsOpen(false);
5366
- const schema = components[uid];
5532
+ const field = useField(name2);
5533
+ const showResetComponent = !attribute.repeatable && field.value && !disabled;
5534
+ const { components } = useDoc();
5535
+ const handleInitialisationClick = () => {
5536
+ const schema = components[attribute.component];
5367
5537
  const form = createDefaultForm(schema, components);
5368
- const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
5369
- ...data2,
5370
- __component: uid
5371
- }));
5372
- const data = transformations(form);
5373
- addFieldRow(name2, data, position);
5374
- };
5375
- const handleClickOpenPicker = () => {
5376
- if (dynamicDisplayedComponentsLength < max) {
5377
- setAddComponentIsOpen((prev) => !prev);
5378
- } else {
5379
- toggleNotification({
5380
- type: "info",
5381
- message: formatMessage({
5382
- id: getTranslation("components.notification.info.maximum-requirement")
5383
- })
5384
- });
5385
- }
5386
- };
5387
- const handleMoveComponent = (newIndex, currentIndex) => {
5388
- setLiveText(
5389
- formatMessage(
5390
- {
5391
- id: getTranslation("dnd.reorder"),
5392
- defaultMessage: "{item}, moved. New position in list: {position}."
5393
- },
5394
- {
5395
- item: `${name2}.${currentIndex}`,
5396
- position: getItemPos(newIndex)
5397
- }
5398
- )
5399
- );
5400
- moveFieldRow(name2, currentIndex, newIndex);
5401
- };
5402
- const getItemPos = (index) => `${index + 1} of ${value.length}`;
5403
- const handleCancel = (index) => {
5404
- setLiveText(
5405
- formatMessage(
5406
- {
5407
- id: getTranslation("dnd.cancel-item"),
5408
- defaultMessage: "{item}, dropped. Re-order cancelled."
5409
- },
5410
- {
5411
- item: `${name2}.${index}`
5412
- }
5413
- )
5414
- );
5415
- };
5416
- const handleGrabItem = (index) => {
5417
- setLiveText(
5418
- formatMessage(
5419
- {
5420
- id: getTranslation("dnd.grab-item"),
5421
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5422
- },
5423
- {
5424
- item: `${name2}.${index}`,
5425
- position: getItemPos(index)
5426
- }
5427
- )
5428
- );
5538
+ const data = transformDocument(schema, components)(form);
5539
+ field.onChange(name2, data);
5429
5540
  };
5430
- const handleDropItem = (index) => {
5431
- setLiveText(
5432
- formatMessage(
5433
- {
5434
- id: getTranslation("dnd.drop-item"),
5435
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
5436
- },
5541
+ return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
5542
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
5543
+ /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
5544
+ label,
5545
+ attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
5546
+ " (",
5547
+ Array.isArray(field.value) ? field.value.length : 0,
5548
+ ")"
5549
+ ] })
5550
+ ] }),
5551
+ showResetComponent && /* @__PURE__ */ jsx(
5552
+ IconButton,
5437
5553
  {
5438
- item: `${name2}.${index}`,
5439
- position: getItemPos(index)
5554
+ label: formatMessage({
5555
+ id: getTranslation("components.reset-entry"),
5556
+ defaultMessage: "Reset Entry"
5557
+ }),
5558
+ variant: "ghost",
5559
+ onClick: () => {
5560
+ field.onChange(name2, null);
5561
+ },
5562
+ children: /* @__PURE__ */ jsx(Trash, {})
5440
5563
  }
5441
5564
  )
5442
- );
5443
- };
5444
- const handleRemoveComponent = (name22, currentIndex) => () => {
5445
- removeFieldRow(name22, currentIndex);
5446
- };
5447
- const hasError = error !== void 0;
5448
- const renderButtonLabel = () => {
5449
- if (addComponentIsOpen) {
5450
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5451
- }
5452
- if (hasError && dynamicDisplayedComponentsLength > max) {
5453
- return formatMessage(
5454
- {
5455
- id: getTranslation(`components.DynamicZone.extra-components`),
5456
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5457
- },
5458
- {
5459
- number: dynamicDisplayedComponentsLength - max
5460
- }
5461
- );
5462
- }
5463
- if (hasError && dynamicDisplayedComponentsLength < min) {
5464
- return formatMessage(
5465
- {
5466
- id: getTranslation(`components.DynamicZone.missing-components`),
5467
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5468
- },
5469
- { number: min - dynamicDisplayedComponentsLength }
5470
- );
5471
- }
5472
- return formatMessage(
5473
- {
5474
- id: getTranslation("components.DynamicZone.add-component"),
5475
- defaultMessage: "Add a component to {componentName}"
5476
- },
5477
- { componentName: label || name2 }
5478
- );
5479
- };
5480
- const level = useComponent("DynamicZone", (state) => state.level);
5481
- const ariaDescriptionId = React.useId();
5482
- return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5483
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
5484
- /* @__PURE__ */ jsx(
5485
- DynamicZoneLabel,
5486
- {
5487
- hint,
5488
- label,
5489
- labelAction,
5490
- name: name2,
5491
- numberOfComponents: dynamicDisplayedComponentsLength,
5492
- required
5493
- }
5494
- ),
5495
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5496
- id: getTranslation("dnd.instructions"),
5497
- defaultMessage: `Press spacebar to grab and re-order`
5498
- }) }),
5499
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5500
- /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
5501
- ComponentProvider,
5502
- {
5503
- level: level + 1,
5504
- uid: field.__component,
5505
- id: field.id,
5506
- type: "dynamiczone",
5507
- children: /* @__PURE__ */ jsx(
5508
- DynamicComponent,
5509
- {
5510
- disabled,
5511
- name: name2,
5512
- index,
5513
- componentUid: field.__component,
5514
- onMoveComponent: handleMoveComponent,
5515
- onRemoveComponentClick: handleRemoveComponent(name2, index),
5516
- onCancel: handleCancel,
5517
- onDropItem: handleDropItem,
5518
- onGrabItem: handleGrabItem,
5519
- onAddComponent: handleAddComponent,
5520
- dynamicComponentsByCategory
5521
- }
5522
- )
5523
- },
5524
- field.__temp_key__
5525
- )) })
5526
5565
  ] }),
5527
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5528
- AddComponentButton,
5529
- {
5530
- hasError,
5531
- isDisabled: disabled,
5532
- isOpen: addComponentIsOpen,
5533
- onClick: handleClickOpenPicker,
5534
- children: renderButtonLabel()
5535
- }
5536
- ) }),
5537
- /* @__PURE__ */ jsx(
5538
- ComponentPicker,
5539
- {
5540
- dynamicComponentsByCategory,
5541
- isOpen: addComponentIsOpen,
5542
- onClickAddComponent: handleAddComponent
5543
- }
5544
- )
5545
- ] }) });
5566
+ !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
5567
+ !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
5568
+ attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
5569
+ /* @__PURE__ */ jsx(Field.Error, {})
5570
+ ] });
5546
5571
  };
5572
+ const MemoizedComponentInput = React.memo(ComponentInput);
5547
5573
  export {
5548
5574
  DynamicZone as D,
5549
- MemoizedInputRenderer as M,
5575
+ FormLayout as F,
5576
+ MemoizedUIDInput as M,
5550
5577
  NotAllowedInput as N,
5551
5578
  useDynamicZone as a,
5552
5579
  useFieldHint as b,
5553
- createDefaultForm as c,
5554
- MemoizedUIDInput as d,
5555
- MemoizedWysiwyg as e,
5556
- MemoizedComponentInput as f,
5557
- MemoizedBlocksInput as g,
5558
- prepareTempKeys as p,
5559
- removeFieldsThatDontExistOnSchema as r,
5560
- transformDocument as t,
5580
+ MemoizedWysiwyg as c,
5581
+ MemoizedComponentInput as d,
5582
+ MemoizedBlocksInput as e,
5561
5583
  useLazyComponents as u
5562
5584
  };
5563
- //# sourceMappingURL=Field-BbrX_tUG.mjs.map
5585
+ //# sourceMappingURL=Input-CZ1YvjHR.mjs.map