@strapi/content-manager 0.0.0-next.8414b837972392b1d362ae53b86b5da1eb2ad05c → 0.0.0-next.926e9af9369b89a571145e3c8fa1ce6bfd6cc0ab

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 (123) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-BTR_hQow.js → ComponentConfigurationPage-DMxUlNOo.js} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-BTR_hQow.js.map → ComponentConfigurationPage-DMxUlNOo.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-bLQr82ce.mjs → ComponentConfigurationPage-baEkO-OV.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-bLQr82ce.mjs.map → ComponentConfigurationPage-baEkO-OV.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-z39Wv3E6.js → EditConfigurationPage-CXxV7mKn.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-z39Wv3E6.js.map → EditConfigurationPage-CXxV7mKn.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-BhRSnUsL.mjs → EditConfigurationPage-YR8-4VCS.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-BhRSnUsL.mjs.map → EditConfigurationPage-YR8-4VCS.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-wujOq90c.js → EditViewPage-BfR6jAR6.js} +13 -76
  10. package/dist/_chunks/EditViewPage-BfR6jAR6.js.map +1 -0
  11. package/dist/_chunks/{EditViewPage-BCjNxNlY.mjs → EditViewPage-DFF7c27p.mjs} +11 -74
  12. package/dist/_chunks/EditViewPage-DFF7c27p.mjs.map +1 -0
  13. package/dist/_chunks/{Form-D7mexvm3.js → Form-CjcMRP5A.js} +2 -2
  14. package/dist/_chunks/{Form-D7mexvm3.js.map → Form-CjcMRP5A.js.map} +1 -1
  15. package/dist/_chunks/{Form-BZgvE8C8.mjs → Form-MSOSfGGN.mjs} +2 -2
  16. package/dist/_chunks/{Form-BZgvE8C8.mjs.map → Form-MSOSfGGN.mjs.map} +1 -1
  17. package/dist/_chunks/{History-DYl2A8Z_.js → History-BgZ7gVuF.js} +43 -19
  18. package/dist/_chunks/History-BgZ7gVuF.js.map +1 -0
  19. package/dist/_chunks/{History-CqNgxkqK.mjs → History-WOQNVho-.mjs} +32 -8
  20. package/dist/_chunks/History-WOQNVho-.mjs.map +1 -0
  21. package/dist/_chunks/{Field-Byr3mPTl.mjs → Input-BkKwZ6Qt.mjs} +1131 -1188
  22. package/dist/_chunks/Input-BkKwZ6Qt.mjs.map +1 -0
  23. package/dist/_chunks/{Field-B5QXnctJ.js → Input-BwOibhc3.js} +1212 -1269
  24. package/dist/_chunks/Input-BwOibhc3.js.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-BbQjzKkQ.mjs → ListConfigurationPage-BeXfr6uW.mjs} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-BbQjzKkQ.mjs.map → ListConfigurationPage-BeXfr6uW.mjs.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-BXnu_OoY.js → ListConfigurationPage-DnJ3nbwL.js} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-BXnu_OoY.js.map → ListConfigurationPage-DnJ3nbwL.js.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-BtSi8C1l.js → ListViewPage-CJFDudKl.js} +13 -10
  30. package/dist/_chunks/{ListViewPage-BtSi8C1l.js.map → ListViewPage-CJFDudKl.js.map} +1 -1
  31. package/dist/_chunks/{ListViewPage-D4ofkbjR.mjs → ListViewPage-VK2v44Q1.mjs} +8 -5
  32. package/dist/_chunks/{ListViewPage-D4ofkbjR.mjs.map → ListViewPage-VK2v44Q1.mjs.map} +1 -1
  33. package/dist/_chunks/{NoContentTypePage-DyUx5mXh.mjs → NoContentTypePage-T8ttty6K.mjs} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-DyUx5mXh.mjs.map → NoContentTypePage-T8ttty6K.mjs.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-CitJeOq4.js → NoContentTypePage-en2PwWgI.js} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-CitJeOq4.js.map → NoContentTypePage-en2PwWgI.js.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-DzgWz0M-.js → NoPermissionsPage-CcjILry3.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-DzgWz0M-.js.map → NoPermissionsPage-CcjILry3.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-DhIiyWkk.mjs → NoPermissionsPage-CokBHhhy.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-DhIiyWkk.mjs.map → NoPermissionsPage-CokBHhhy.mjs.map} +1 -1
  41. package/dist/_chunks/{Preview-BaYGJ0nb.mjs → Preview-BF81YhRj.mjs} +10 -16
  42. package/dist/_chunks/Preview-BF81YhRj.mjs.map +1 -0
  43. package/dist/_chunks/{Preview-DfNx8Ke-.js → Preview-DgzAuzWQ.js} +10 -16
  44. package/dist/_chunks/Preview-DgzAuzWQ.js.map +1 -0
  45. package/dist/_chunks/{Relations-DuKCaXrv.js → Relations-1O-JcM4t.js} +3 -3
  46. package/dist/_chunks/{Relations-DuKCaXrv.js.map → Relations-1O-JcM4t.js.map} +1 -1
  47. package/dist/_chunks/{Relations-DM2yUTST.mjs → Relations-BncdhGCd.mjs} +3 -3
  48. package/dist/_chunks/{Relations-DM2yUTST.mjs.map → Relations-BncdhGCd.mjs.map} +1 -1
  49. package/dist/_chunks/{en-Dtk_ot79.mjs → en-BZaUty0m.mjs} +8 -2
  50. package/dist/_chunks/{en-Dtk_ot79.mjs.map → en-BZaUty0m.mjs.map} +1 -1
  51. package/dist/_chunks/{en-BK8Xyl5I.js → en-CzCnBk4S.js} +8 -2
  52. package/dist/_chunks/{en-BK8Xyl5I.js.map → en-CzCnBk4S.js.map} +1 -1
  53. package/dist/_chunks/{index-DVAIIsOs.mjs → index-DiluOUp6.mjs} +214 -48
  54. package/dist/_chunks/index-DiluOUp6.mjs.map +1 -0
  55. package/dist/_chunks/{index-BUWEmX8m.js → index-EXJvmn4t.js} +197 -31
  56. package/dist/_chunks/index-EXJvmn4t.js.map +1 -0
  57. package/dist/_chunks/{layout-C3fN7Ejz.js → layout-4TbKVax8.js} +3 -3
  58. package/dist/_chunks/{layout-C3fN7Ejz.js.map → layout-4TbKVax8.js.map} +1 -1
  59. package/dist/_chunks/{layout-Bxsv5mP7.mjs → layout-mSwsYzxv.mjs} +3 -3
  60. package/dist/_chunks/{layout-Bxsv5mP7.mjs.map → layout-mSwsYzxv.mjs.map} +1 -1
  61. package/dist/_chunks/{relations-o3pPhzY4.mjs → relations--YOvQBqv.mjs} +2 -2
  62. package/dist/_chunks/{relations-o3pPhzY4.mjs.map → relations--YOvQBqv.mjs.map} +1 -1
  63. package/dist/_chunks/{relations-BPZKAoEY.js → relations-Ai6Izh7h.js} +2 -2
  64. package/dist/_chunks/{relations-BPZKAoEY.js.map → relations-Ai6Izh7h.js.map} +1 -1
  65. package/dist/_chunks/{useDebounce-DmuSJIF3.mjs → usePrev-CZGy2Vjf.mjs} +11 -11
  66. package/dist/_chunks/usePrev-CZGy2Vjf.mjs.map +1 -0
  67. package/dist/_chunks/{useDebounce-CtcjDB3L.js → usePrev-D5J_2fEu.js} +8 -8
  68. package/dist/_chunks/usePrev-D5J_2fEu.js.map +1 -0
  69. package/dist/admin/index.js +2 -1
  70. package/dist/admin/index.js.map +1 -1
  71. package/dist/admin/index.mjs +6 -5
  72. package/dist/admin/src/exports.d.ts +1 -0
  73. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  74. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  75. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +1 -1
  76. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  77. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  78. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  79. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  80. package/dist/admin/src/preview/pages/Preview.d.ts +1 -1
  81. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  82. package/dist/admin/src/services/api.d.ts +1 -1
  83. package/dist/admin/src/services/components.d.ts +2 -2
  84. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  85. package/dist/admin/src/services/documents.d.ts +16 -16
  86. package/dist/admin/src/services/init.d.ts +1 -1
  87. package/dist/admin/src/services/relations.d.ts +2 -2
  88. package/dist/admin/src/services/uid.d.ts +3 -3
  89. package/dist/server/index.js +156 -138
  90. package/dist/server/index.js.map +1 -1
  91. package/dist/server/index.mjs +157 -139
  92. package/dist/server/index.mjs.map +1 -1
  93. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  94. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  95. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  96. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  97. package/dist/server/src/history/services/history.d.ts +3 -3
  98. package/dist/server/src/history/services/history.d.ts.map +1 -1
  99. package/dist/server/src/history/services/utils.d.ts +6 -10
  100. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  101. package/dist/server/src/index.d.ts +3 -2
  102. package/dist/server/src/index.d.ts.map +1 -1
  103. package/dist/server/src/services/document-metadata.d.ts +4 -2
  104. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  105. package/dist/server/src/services/index.d.ts +3 -2
  106. package/dist/server/src/services/index.d.ts.map +1 -1
  107. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  108. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  109. package/dist/server/src/services/utils/populate.d.ts +2 -2
  110. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  111. package/package.json +6 -7
  112. package/dist/_chunks/EditViewPage-BCjNxNlY.mjs.map +0 -1
  113. package/dist/_chunks/EditViewPage-wujOq90c.js.map +0 -1
  114. package/dist/_chunks/Field-B5QXnctJ.js.map +0 -1
  115. package/dist/_chunks/Field-Byr3mPTl.mjs.map +0 -1
  116. package/dist/_chunks/History-CqNgxkqK.mjs.map +0 -1
  117. package/dist/_chunks/History-DYl2A8Z_.js.map +0 -1
  118. package/dist/_chunks/Preview-BaYGJ0nb.mjs.map +0 -1
  119. package/dist/_chunks/Preview-DfNx8Ke-.js.map +0 -1
  120. package/dist/_chunks/index-BUWEmX8m.js.map +0 -1
  121. package/dist/_chunks/index-DVAIIsOs.mjs.map +0 -1
  122. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  123. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
@@ -1,19 +1,12 @@
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-DVAIIsOs.mjs";
9
- import { generateNKeysBetween } from "fractional-indexing";
10
- import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from "./Relations-DM2yUTST.mjs";
11
- 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, 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-DiluOUp6.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-DJ6jqvZN.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";
@@ -68,9 +61,15 @@ import "prismjs/components/prism-typescript";
68
61
  import "prismjs/components/prism-tsx";
69
62
  import "prismjs/components/prism-vbnet";
70
63
  import "prismjs/components/prism-yaml";
71
- import { p as prefixFileUrlWithBackendUrl, u as usePrev, a as useDebounce } from "./useDebounce-DmuSJIF3.mjs";
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";
72
66
  import * as Toolbar from "@radix-ui/react-toolbar";
73
- 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-BncdhGCd.mjs";
71
+ import pipe$1 from "lodash/fp/pipe";
72
+ import { C as ComponentIcon, a as COMPONENT_ICONS } from "./ComponentIcon-u4bIXTFY.mjs";
74
73
  import CodeMirror from "codemirror5";
75
74
  import sanitizeHtml from "sanitize-html";
76
75
  import { getLanguage, highlight, highlightAuto } from "highlight.js";
@@ -86,93 +85,6 @@ import sub from "markdown-it-sub";
86
85
  import sup from "markdown-it-sup";
87
86
  import "highlight.js/styles/solarized-dark.css";
88
87
  import "codemirror5/addon/display/placeholder";
89
- const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
90
- const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
91
- const traverse = (datum, attributes) => {
92
- return Object.entries(datum).reduce((acc, [key, value]) => {
93
- const attribute = attributes[key];
94
- if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
95
- acc[key] = value;
96
- return acc;
97
- }
98
- if (attribute.type === "component") {
99
- if (attribute.repeatable) {
100
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
101
- acc[key] = componentValue.map(
102
- (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
103
- );
104
- } else {
105
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
106
- acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
107
- }
108
- } else if (attribute.type === "dynamiczone") {
109
- const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
110
- acc[key] = dynamicZoneValue.map(
111
- (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
112
- );
113
- } else if (predicate(attribute, value)) {
114
- acc[key] = transform(value, attribute);
115
- } else {
116
- acc[key] = value;
117
- }
118
- return acc;
119
- }, {});
120
- };
121
- return traverse(data, schema.attributes);
122
- };
123
- const removeProhibitedFields = (prohibitedFields) => traverseData(
124
- (attribute) => prohibitedFields.includes(attribute.type),
125
- () => ""
126
- );
127
- const prepareRelations = traverseData(
128
- (attribute) => attribute.type === "relation",
129
- () => ({
130
- connect: [],
131
- disconnect: []
132
- })
133
- );
134
- const prepareTempKeys = traverseData(
135
- (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
136
- (data) => {
137
- if (Array.isArray(data) && data.length > 0) {
138
- const keys = generateNKeysBetween(void 0, void 0, data.length);
139
- return data.map((datum, index) => ({
140
- ...datum,
141
- __temp_key__: keys[index]
142
- }));
143
- }
144
- return data;
145
- }
146
- );
147
- const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
148
- const schemaKeys = Object.keys(schema.attributes);
149
- const dataKeys = Object.keys(data);
150
- const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
151
- const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
152
- delete acc[key];
153
- return acc;
154
- }, structuredClone(data));
155
- return revisedData;
156
- };
157
- const removeNullValues = (data) => {
158
- return Object.entries(data).reduce((acc, [key, value]) => {
159
- if (value === null) {
160
- return acc;
161
- }
162
- acc[key] = value;
163
- return acc;
164
- }, {});
165
- };
166
- const transformDocument = (schema, components = {}) => (document2) => {
167
- const transformations = pipe$1(
168
- removeFieldsThatDontExistOnSchema(schema),
169
- removeProhibitedFields(["password"])(schema, components),
170
- removeNullValues,
171
- prepareRelations(schema, components),
172
- prepareTempKeys(schema, components)
173
- );
174
- return transformations(document2);
175
- };
176
88
  const componentStore = /* @__PURE__ */ new Map();
177
89
  const useLazyComponents = (componentUids = []) => {
178
90
  const [lazyComponentStore, setLazyComponentStore] = useState(Object.fromEntries(componentStore));
@@ -599,8 +511,7 @@ const codeBlocks = {
599
511
  handleEnterKey(editor) {
600
512
  pressEnterTwiceToExit(editor);
601
513
  },
602
- snippets: ["```"],
603
- dragHandleTopMargin: "10px"
514
+ snippets: ["```"]
604
515
  }
605
516
  };
606
517
  const H1 = styled(Typography).attrs({ tag: "h1" })`
@@ -1379,13 +1290,13 @@ const quoteBlocks = {
1379
1290
  handleEnterKey(editor) {
1380
1291
  pressEnterTwiceToExit(editor);
1381
1292
  },
1382
- snippets: [">"],
1383
- dragHandleTopMargin: "6px"
1293
+ snippets: [">"]
1384
1294
  }
1385
1295
  };
1386
1296
  const ToolbarWrapper = styled(Flex)`
1387
1297
  &[aria-disabled='true'] {
1388
1298
  cursor: not-allowed;
1299
+ background: ${({ theme }) => theme.colors.neutral150};
1389
1300
  }
1390
1301
  `;
1391
1302
  const Separator = styled(Toolbar.Separator)`
@@ -1396,7 +1307,7 @@ const Separator = styled(Toolbar.Separator)`
1396
1307
  const FlexButton = styled(Flex)`
1397
1308
  // Inherit the not-allowed cursor from ToolbarWrapper when disabled
1398
1309
  &[aria-disabled] {
1399
- cursor: inherit;
1310
+ cursor: not-allowed;
1400
1311
  }
1401
1312
 
1402
1313
  &[aria-disabled='false'] {
@@ -1748,7 +1659,7 @@ const BlocksToolbar = () => {
1748
1659
  return false;
1749
1660
  };
1750
1661
  const isButtonDisabled = checkButtonDisabled();
1751
- 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: [
1752
1663
  /* @__PURE__ */ jsx(BlocksDropdown, {}),
1753
1664
  /* @__PURE__ */ jsx(Separator, {}),
1754
1665
  /* @__PURE__ */ jsx(Toolbar.ToggleGroup, { type: "multiple", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
@@ -1822,30 +1733,32 @@ const DragIconButton = styled(IconButton)`
1822
1733
  display: flex;
1823
1734
  align-items: center;
1824
1735
  justify-content: center;
1736
+ border: none;
1825
1737
  border-radius: ${({ theme }) => theme.borderRadius};
1826
- width: ${({ theme }) => theme.spaces[4]};
1827
- 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]};
1828
1742
  visibility: hidden;
1829
1743
  cursor: grab;
1830
1744
  opacity: inherit;
1831
1745
  margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};
1832
1746
 
1833
1747
  &:hover {
1834
- background: ${({ theme }) => theme.colors.neutral200};
1748
+ background: ${({ theme }) => theme.colors.neutral100};
1835
1749
  }
1836
1750
  &:active {
1837
1751
  cursor: grabbing;
1752
+ background: ${({ theme }) => theme.colors.neutral150};
1838
1753
  }
1839
1754
  &[aria-disabled='true'] {
1840
- cursor: not-allowed;
1841
- background: transparent;
1755
+ visibility: hidden;
1842
1756
  }
1843
1757
  svg {
1844
- height: auto;
1845
1758
  min-width: ${({ theme }) => theme.spaces[3]};
1846
1759
 
1847
1760
  path {
1848
- fill: ${({ theme }) => theme.colors.neutral700};
1761
+ fill: ${({ theme }) => theme.colors.neutral500};
1849
1762
  }
1850
1763
  }
1851
1764
  `;
@@ -2198,7 +2111,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2198
2111
  background: "neutral0",
2199
2112
  color: "neutral800",
2200
2113
  lineHeight: 6,
2201
- paddingRight: 4,
2114
+ paddingRight: 7,
2202
2115
  paddingTop: 6,
2203
2116
  paddingBottom: 3,
2204
2117
  children: [
@@ -2532,6 +2445,7 @@ const ExpandIconButton = styled(IconButton)`
2532
2445
  position: absolute;
2533
2446
  bottom: 1.2rem;
2534
2447
  right: 1.2rem;
2448
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2535
2449
  `;
2536
2450
  function useResetKey(value) {
2537
2451
  const slateUpdatesCount = React.useRef(0);
@@ -2663,26 +2577,6 @@ const BlocksInput = React.forwardRef(
2663
2577
  }
2664
2578
  );
2665
2579
  const MemoizedBlocksInput = React.memo(BlocksInput);
2666
- const createDefaultForm = (contentType, components = {}) => {
2667
- const traverseSchema = (attributes) => {
2668
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2669
- if ("default" in attribute) {
2670
- acc[key] = attribute.default;
2671
- } else if (attribute.type === "component" && attribute.required) {
2672
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2673
- if (attribute.repeatable) {
2674
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2675
- } else {
2676
- acc[key] = defaultComponentForm;
2677
- }
2678
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2679
- acc[key] = [];
2680
- }
2681
- return acc;
2682
- }, {});
2683
- };
2684
- return traverseSchema(contentType.attributes);
2685
- };
2686
2580
  const Initializer = ({ disabled, name: name2, onClick }) => {
2687
2581
  const { formatMessage } = useIntl();
2688
2582
  const field = useField(name2);
@@ -2717,126 +2611,451 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2717
2611
  }
2718
2612
  ) });
2719
2613
  };
2720
- const NonRepeatableComponent = ({
2721
- attribute,
2722
- name: name2,
2614
+ const AddComponentButton = ({
2615
+ hasError,
2616
+ isDisabled,
2617
+ isOpen,
2723
2618
  children,
2724
- layout
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
+
2650
+ > circle {
2651
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2652
+ }
2653
+ > path {
2654
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
2655
+ }
2656
+ `;
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
2725
2668
  }) => {
2726
2669
  const { formatMessage } = useIntl();
2727
- const { value } = useField(name2);
2728
- const level = useComponent("NonRepeatableComponent", (state) => state.level);
2729
- const isNested = level > 0;
2730
- return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
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(
2731
2733
  Box,
2732
2734
  {
2733
- background: "neutral100",
2734
- paddingLeft: 6,
2735
- paddingRight: 6,
2736
2735
  paddingTop: 6,
2737
2736
  paddingBottom: 6,
2738
- hasRadius: isNested,
2739
- borderColor: isNested ? "neutral200" : void 0,
2740
- children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
2741
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2742
- const completeFieldName = `${name2}.${field.name}`;
2743
- const translatedLabel = formatMessage({
2744
- id: `content-manager.components.${attribute.component}.${field.name}`,
2745
- defaultMessage: field.label
2746
- });
2747
- return /* @__PURE__ */ jsx(
2748
- Grid$1.Item,
2749
- {
2750
- col: size,
2751
- s: 12,
2752
- xs: 12,
2753
- direction: "column",
2754
- alignItems: "stretch",
2755
- children: children({ ...field, label: translatedLabel, name: completeFieldName })
2756
- },
2757
- completeFieldName
2758
- );
2759
- }) }, index);
2760
- }) })
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
+ ]
2761
2759
  }
2762
- ) });
2760
+ );
2763
2761
  };
2764
- const RepeatableComponent = ({
2765
- attribute,
2762
+ const DynamicComponent = ({
2763
+ componentUid,
2766
2764
  disabled,
2765
+ index,
2767
2766
  name: name2,
2768
- mainField,
2769
- children,
2770
- layout
2767
+ onRemoveComponentClick,
2768
+ onMoveComponent,
2769
+ onGrabItem,
2770
+ onDropItem,
2771
+ onCancel,
2772
+ dynamicComponentsByCategory = {},
2773
+ onAddComponent,
2774
+ children
2771
2775
  }) => {
2772
- const { toggleNotification } = useNotification();
2773
2776
  const { formatMessage } = useIntl();
2774
- const { search: searchString } = useLocation();
2775
- const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
2776
- const { components } = useDoc();
2777
+ const formValues = useForm("DynamicComponent", (state) => state.values);
2777
2778
  const {
2778
- value = [],
2779
- error,
2780
- rawError
2781
- } = useField(name2);
2782
- const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
2783
- const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
2784
- const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
2785
- const { max = Infinity } = attribute;
2786
- const [collapseToOpen, setCollapseToOpen] = React.useState("");
2787
- const [liveText, setLiveText] = React.useState("");
2788
- React.useEffect(() => {
2789
- const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
2790
- const hasNestedValue = value && Array.isArray(value) && value.length > 0;
2791
- if (hasNestedErrors && hasNestedValue) {
2792
- const errorOpenItems = rawError.map((_, idx) => {
2793
- return value[idx] ? value[idx].__temp_key__ : null;
2794
- }).filter((value2) => !!value2);
2795
- if (errorOpenItems && errorOpenItems.length > 0) {
2796
- setCollapseToOpen((collapseToOpen2) => {
2797
- if (!errorOpenItems.includes(collapseToOpen2)) {
2798
- return errorOpenItems[0];
2799
- }
2800
- return collapseToOpen2;
2801
- });
2802
- }
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
+ });
2808
+ React.useEffect(() => {
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);
2803
2817
  }
2804
- }, [rawError, value]);
2805
- const componentTmpKeyWithFocussedField = React.useMemo(() => {
2806
- if (search.has("field")) {
2807
- const fieldParam = search.get("field");
2808
- if (!fieldParam) {
2809
- 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, {})
2810
2834
  }
2811
- const [, path] = fieldParam.split(`${name2}.`);
2812
- if (getIn(value, path, void 0) !== void 0) {
2813
- const [subpath] = path.split(".");
2814
- 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, {})
2815
2849
  }
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,
2854
+ {
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 })
2862
+ }
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,
2904
+ {
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
+ };
2919
+ return /* @__PURE__ */ jsx(
2920
+ ResponsiveGridItem,
2921
+ {
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 })
2928
+ },
2929
+ fieldName
2930
+ );
2931
+ }) })
2932
+ },
2933
+ rowInd
2934
+ )) }) }) }) })
2935
+ ] }) }) })
2936
+ ] });
2937
+ };
2938
+ const StyledBox = styled(Box)`
2939
+ > div:first-child {
2940
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
2941
+ }
2942
+ `;
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`
2951
+ display: block;
2952
+ background-color: ${({ theme }) => theme.colors.primary100};
2953
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2954
+ outline-offset: -1px;
2955
+ padding: ${({ theme }) => theme.spaces[6]};
2956
+ `;
2957
+ const ComponentContainer = styled(Box)`
2958
+ list-style: none;
2959
+ padding: 0;
2960
+ margin: 0;
2961
+ `;
2962
+ const DynamicZoneLabel = ({
2963
+ hint,
2964
+ label,
2965
+ labelAction,
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
+ ] })
2816
2997
  }
2817
- return void 0;
2818
- }, [search, name2, value]);
2819
- const prevValue = usePrev(value);
2820
- React.useEffect(() => {
2821
- if (prevValue && prevValue.length < value.length) {
2822
- setCollapseToOpen(value[value.length - 1].__temp_key__);
2823
- }
2824
- }, [value, prevValue]);
2825
- React.useEffect(() => {
2826
- if (typeof componentTmpKeyWithFocussedField === "string") {
2827
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2828
- }
2829
- }, [componentTmpKeyWithFocussedField]);
2830
- const toggleCollapses = () => {
2831
- setCollapseToOpen("");
2998
+ ) });
2999
+ };
3000
+ const [DynamicZoneProvider, useDynamicZone] = createContext(
3001
+ "DynamicZone",
3002
+ {
3003
+ isInDynamicZone: false
3004
+ }
3005
+ );
3006
+ const DynamicZone = ({
3007
+ attribute,
3008
+ disabled: disabledProp,
3009
+ hint,
3010
+ label,
3011
+ labelAction,
3012
+ name: name2,
3013
+ required = false,
3014
+ children
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]);
3041
+ const { formatMessage } = useIntl();
3042
+ const { toggleNotification } = useNotification();
3043
+ const dynamicDisplayedComponentsLength = value.length;
3044
+ const handleAddComponent = (uid, position) => {
3045
+ setAddComponentIsOpen(false);
3046
+ const schema = components[uid];
3047
+ const form = createDefaultForm(schema, components);
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);
2832
3054
  };
2833
- const handleClick = () => {
2834
- if (value.length < max) {
2835
- const schema = components[attribute.component];
2836
- const form = createDefaultForm(schema, components);
2837
- const data = transformDocument(schema, components)(form);
2838
- addFieldRow(name2, data);
2839
- } else if (value.length >= max) {
3055
+ const handleClickOpenPicker = () => {
3056
+ if (dynamicDisplayedComponentsLength < max) {
3057
+ setAddComponentIsOpen((prev) => !prev);
3058
+ } else {
2840
3059
  toggleNotification({
2841
3060
  type: "info",
2842
3061
  message: formatMessage({
@@ -2845,7 +3064,7 @@ const RepeatableComponent = ({
2845
3064
  });
2846
3065
  }
2847
3066
  };
2848
- const handleMoveComponentField = (newIndex, currentIndex) => {
3067
+ const handleMoveComponent = (newIndex, currentIndex) => {
2849
3068
  setLiveText(
2850
3069
  formatMessage(
2851
3070
  {
@@ -2860,9 +3079,6 @@ const RepeatableComponent = ({
2860
3079
  );
2861
3080
  moveFieldRow(name2, currentIndex, newIndex);
2862
3081
  };
2863
- const handleValueChange = (key) => {
2864
- setCollapseToOpen(key);
2865
- };
2866
3082
  const getItemPos = (index) => `${index + 1} of ${value.length}`;
2867
3083
  const handleCancel = (index) => {
2868
3084
  setLiveText(
@@ -2895,446 +3111,119 @@ const RepeatableComponent = ({
2895
3111
  setLiveText(
2896
3112
  formatMessage(
2897
3113
  {
2898
- id: getTranslation("dnd.drop-item"),
2899
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
2900
- },
2901
- {
2902
- item: `${name2}.${index}`,
2903
- position: getItemPos(index)
2904
- }
2905
- )
2906
- );
2907
- };
2908
- const ariaDescriptionId = React.useId();
2909
- const level = useComponent("RepeatableComponent", (state) => state.level);
2910
- if (value.length === 0) {
2911
- return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2912
- }
2913
- return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
2914
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2915
- id: getTranslation("dnd.instructions"),
2916
- defaultMessage: `Press spacebar to grab and re-order`
2917
- }) }),
2918
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2919
- /* @__PURE__ */ jsxs(
2920
- AccordionRoot,
2921
- {
2922
- $error: error,
2923
- value: collapseToOpen,
2924
- onValueChange: handleValueChange,
2925
- "aria-describedby": ariaDescriptionId,
2926
- children: [
2927
- value.map(({ __temp_key__: key, id }, index) => {
2928
- const nameWithIndex = `${name2}.${index}`;
2929
- return /* @__PURE__ */ jsx(
2930
- ComponentProvider,
2931
- {
2932
- id,
2933
- uid: attribute.component,
2934
- level: level + 1,
2935
- type: "repeatable",
2936
- children: /* @__PURE__ */ jsx(
2937
- Component,
2938
- {
2939
- disabled,
2940
- name: nameWithIndex,
2941
- attribute,
2942
- index,
2943
- mainField,
2944
- onMoveItem: handleMoveComponentField,
2945
- onDeleteComponent: () => {
2946
- removeFieldRow(name2, index);
2947
- toggleCollapses();
2948
- },
2949
- toggleCollapses,
2950
- onCancel: handleCancel,
2951
- onDropItem: handleDropItem,
2952
- onGrabItem: handleGrabItem,
2953
- __temp_key__: key,
2954
- children: layout.map((row, index2) => {
2955
- return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2956
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2957
- const translatedLabel = formatMessage({
2958
- id: `content-manager.components.${attribute.component}.${field.name}`,
2959
- defaultMessage: field.label
2960
- });
2961
- return /* @__PURE__ */ jsx(
2962
- Grid$1.Item,
2963
- {
2964
- col: size,
2965
- s: 12,
2966
- xs: 12,
2967
- direction: "column",
2968
- alignItems: "stretch",
2969
- children: children({
2970
- ...field,
2971
- label: translatedLabel,
2972
- name: completeFieldName
2973
- })
2974
- },
2975
- completeFieldName
2976
- );
2977
- }) }, index2);
2978
- })
2979
- }
2980
- )
2981
- },
2982
- key
2983
- );
2984
- }),
2985
- /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
2986
- id: getTranslation("containers.EditView.add.new-entry"),
2987
- defaultMessage: "Add an entry"
2988
- }) })
2989
- ]
2990
- }
2991
- )
2992
- ] });
2993
- };
2994
- const AccordionRoot = styled(Accordion.Root)`
2995
- border: 1px solid
2996
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
2997
- `;
2998
- const TextButtonCustom = styled(TextButton)`
2999
- width: 100%;
3000
- display: flex;
3001
- justify-content: center;
3002
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
3003
- padding-inline: ${(props) => props.theme.spaces[6]};
3004
- padding-block: ${(props) => props.theme.spaces[3]};
3005
-
3006
- &:not([disabled]) {
3007
- cursor: pointer;
3008
-
3009
- &:hover {
3010
- background-color: ${(props) => props.theme.colors.primary100};
3011
- }
3012
- }
3013
-
3014
- span {
3015
- font-weight: 600;
3016
- font-size: 1.4rem;
3017
- line-height: 2.4rem;
3018
- }
3019
-
3020
- @media (prefers-reduced-motion: no-preference) {
3021
- transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3022
- }
3023
- `;
3024
- const Component = ({
3025
- disabled,
3026
- index,
3027
- name: name2,
3028
- mainField = {
3029
- name: "id",
3030
- type: "integer"
3031
- },
3032
- children,
3033
- onDeleteComponent,
3034
- toggleCollapses,
3035
- __temp_key__,
3036
- ...dragProps
3037
- }) => {
3038
- const { formatMessage } = useIntl();
3039
- const displayValue = useForm("RepeatableComponent", (state) => {
3040
- return getIn(state.values, [...name2.split("."), mainField.name]);
3041
- });
3042
- const accordionRef = React.useRef(null);
3043
- const componentKey = name2.split(".").slice(0, -1).join(".");
3044
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
3045
- type: `${ItemTypes.COMPONENT}_${componentKey}`,
3046
- index,
3047
- item: {
3048
- index,
3049
- displayedValue: displayValue
3050
- },
3051
- onStart() {
3052
- toggleCollapses();
3053
- },
3054
- ...dragProps
3055
- });
3056
- React.useEffect(() => {
3057
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
3058
- }, [dragPreviewRef, index]);
3059
- const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
3060
- const composedBoxRefs = useComposedRefs(
3061
- boxRef,
3062
- dropRef
3063
- );
3064
- return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
3065
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
3066
- /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
3067
- /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
3068
- /* @__PURE__ */ jsx(
3069
- IconButton,
3070
- {
3071
- variant: "ghost",
3072
- onClick: onDeleteComponent,
3073
- label: formatMessage({
3074
- id: getTranslation("containers.Edit.delete"),
3075
- defaultMessage: "Delete"
3076
- }),
3077
- children: /* @__PURE__ */ jsx(Trash, {})
3078
- }
3079
- ),
3080
- /* @__PURE__ */ jsx(
3081
- IconButton,
3082
- {
3083
- ref: composedAccordionRefs,
3084
- variant: "ghost",
3085
- onClick: (e) => e.stopPropagation(),
3086
- "data-handler-id": handlerId,
3087
- label: formatMessage({
3088
- id: getTranslation("components.DragHandle-label"),
3089
- defaultMessage: "Drag"
3090
- }),
3091
- onKeyDown: handleKeyDown,
3092
- children: /* @__PURE__ */ jsx(Drag, {})
3093
- }
3094
- )
3095
- ] })
3096
- ] }),
3097
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
3098
- Flex,
3099
- {
3100
- direction: "column",
3101
- alignItems: "stretch",
3102
- background: "neutral100",
3103
- padding: 6,
3104
- gap: 6,
3105
- children
3106
- }
3107
- ) })
3108
- ] }) });
3109
- };
3110
- const Preview$1 = () => {
3111
- return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
3112
- };
3113
- const StyledSpan = styled(Box)`
3114
- display: block;
3115
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
3116
- outline-offset: -1px;
3117
- `;
3118
- const ComponentInput = ({
3119
- label,
3120
- required,
3121
- name: name2,
3122
- attribute,
3123
- disabled,
3124
- labelAction,
3125
- ...props
3126
- }) => {
3127
- const { formatMessage } = useIntl();
3128
- const field = useField(name2);
3129
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
3130
- const { components } = useDoc();
3131
- const handleInitialisationClick = () => {
3132
- const schema = components[attribute.component];
3133
- const form = createDefaultForm(schema, components);
3134
- const data = transformDocument(schema, components)(form);
3135
- field.onChange(name2, data);
3136
- };
3137
- return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
3138
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3139
- /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
3140
- label,
3141
- attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
3142
- " (",
3143
- Array.isArray(field.value) ? field.value.length : 0,
3144
- ")"
3145
- ] })
3146
- ] }),
3147
- showResetComponent && /* @__PURE__ */ jsx(
3148
- IconButton,
3149
- {
3150
- label: formatMessage({
3151
- id: getTranslation("components.reset-entry"),
3152
- defaultMessage: "Reset Entry"
3153
- }),
3154
- variant: "ghost",
3155
- onClick: () => {
3156
- field.onChange(name2, null);
3157
- },
3158
- children: /* @__PURE__ */ jsx(Trash, {})
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)
3159
3120
  }
3160
3121
  )
3161
- ] }),
3162
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
3163
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
3164
- attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
3165
- /* @__PURE__ */ jsx(Field.Error, {})
3166
- ] });
3167
- };
3168
- const MemoizedComponentInput = React.memo(ComponentInput);
3169
- const AddComponentButton = ({
3170
- hasError,
3171
- isDisabled,
3172
- isOpen,
3173
- children,
3174
- onClick
3175
- }) => {
3176
- return /* @__PURE__ */ jsx(
3177
- StyledButton,
3178
- {
3179
- type: "button",
3180
- onClick,
3181
- disabled: isDisabled,
3182
- background: "neutral0",
3183
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
3184
- variant: "tertiary",
3185
- children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
3186
- /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
3187
- /* @__PURE__ */ jsx(
3188
- AddComponentTitle,
3189
- {
3190
- variant: "pi",
3191
- fontWeight: "bold",
3192
- textColor: hasError && !isOpen ? "danger600" : "neutral500",
3193
- children
3194
- }
3195
- )
3196
- ] })
3197
- }
3198
- );
3199
- };
3200
- const StyledAddIcon = styled(PlusCircle)`
3201
- height: ${({ theme }) => theme.spaces[6]};
3202
- width: ${({ theme }) => theme.spaces[6]};
3203
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
3204
-
3205
- > circle {
3206
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
3207
- }
3208
- > path {
3209
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral600};
3210
- }
3211
- `;
3212
- const AddComponentTitle = styled(Typography)``;
3213
- const StyledButton = styled(Button)`
3214
- border-radius: 26px;
3215
- border-color: ${({ theme }) => theme.colors.neutral150};
3216
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
3217
- height: 5rem;
3218
-
3219
- &:hover {
3220
- ${AddComponentTitle} {
3221
- color: ${({ theme }) => theme.colors.primary600};
3222
- }
3223
-
3224
- ${StyledAddIcon} {
3225
- > circle {
3226
- fill: ${({ theme }) => theme.colors.primary600};
3227
- }
3228
- > path {
3229
- fill: ${({ theme }) => theme.colors.primary600};
3230
- }
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" });
3231
3131
  }
3232
- }
3233
- &:active {
3234
- ${AddComponentTitle} {
3235
- 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
+ );
3236
3142
  }
3237
- ${StyledAddIcon} {
3238
- > circle {
3239
- fill: ${({ theme }) => theme.colors.primary600};
3240
- }
3241
- > path {
3242
- fill: ${({ theme }) => theme.colors.neutral100};
3243
- }
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
+ );
3244
3151
  }
3245
- }
3246
- `;
3247
- const ComponentCategory = ({
3248
- category,
3249
- components = [],
3250
- variant = "primary",
3251
- onAddComponent
3252
- }) => {
3253
- const { formatMessage } = useIntl();
3254
- return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
3255
- /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
3256
- /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
3257
- ComponentBox,
3152
+ return formatMessage(
3258
3153
  {
3259
- tag: "button",
3260
- type: "button",
3261
- background: "neutral100",
3262
- justifyContent: "center",
3263
- onClick: onAddComponent(uid),
3264
- hasRadius: true,
3265
- height: "8.4rem",
3266
- shrink: 0,
3267
- borderColor: "neutral200",
3268
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
3269
- /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
3270
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
3271
- ] })
3154
+ id: getTranslation("components.DynamicZone.add-component"),
3155
+ defaultMessage: "Add a component to {componentName}"
3272
3156
  },
3273
- uid
3274
- )) }) })
3275
- ] });
3276
- };
3277
- const Grid = styled(Box)`
3278
- display: grid;
3279
- grid-template-columns: repeat(auto-fit, 14rem);
3280
- grid-gap: ${({ theme }) => theme.spaces[1]};
3281
- `;
3282
- const ComponentBox = styled(Flex)`
3283
- color: ${({ theme }) => theme.colors.neutral600};
3284
- cursor: pointer;
3285
-
3286
- @media (prefers-reduced-motion: no-preference) {
3287
- transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3288
- }
3289
-
3290
- &:focus,
3291
- &:hover {
3292
- border: 1px solid ${({ theme }) => theme.colors.primary200};
3293
- background: ${({ theme }) => theme.colors.primary100};
3294
- color: ${({ theme }) => theme.colors.primary600};
3295
- }
3296
- `;
3297
- const ComponentPicker = ({
3298
- dynamicComponentsByCategory = {},
3299
- isOpen,
3300
- onClickAddComponent
3301
- }) => {
3302
- const { formatMessage } = useIntl();
3303
- const handleAddComponentToDz = (componentUid) => () => {
3304
- onClickAddComponent(componentUid);
3157
+ { componentName: label || name2 }
3158
+ );
3305
3159
  };
3306
- if (!isOpen) {
3307
- return null;
3308
- }
3309
- return /* @__PURE__ */ jsxs(
3310
- Box,
3311
- {
3312
- paddingTop: 6,
3313
- paddingBottom: 6,
3314
- paddingLeft: 5,
3315
- paddingRight: 5,
3316
- background: "neutral0",
3317
- shadow: "tableShadow",
3318
- borderColor: "neutral150",
3319
- hasRadius: true,
3320
- children: [
3321
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
3322
- id: getTranslation("components.DynamicZone.ComponentPicker-label"),
3323
- defaultMessage: "Pick one component"
3324
- }) }) }),
3325
- /* @__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(
3326
- ComponentCategory,
3327
- {
3328
- category,
3329
- components,
3330
- onAddComponent: handleAddComponentToDz,
3331
- variant: index % 2 === 1 ? "primary" : "secondary"
3332
- },
3333
- category
3334
- )) }) })
3335
- ]
3336
- }
3337
- );
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
+ ] }) });
3338
3227
  };
3339
3228
  const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3340
3229
  const { formatMessage } = useIntl();
@@ -5076,567 +4965,621 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
5076
4965
  return /* @__PURE__ */ jsx(
5077
4966
  MemoizedComponentInput,
5078
4967
  {
5079
- ...props,
5080
- hint,
5081
- layout: components[props.attribute.component].layout,
5082
- disabled: fieldIsDisabled,
5083
- children: (inputProps) => /* @__PURE__ */ jsx(InputRenderer, { ...inputProps })
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;
5013
+ }
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
+ }
5042
+ );
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 };
5054
+ }
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};`}
5069
+ }
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);
5086
+ }
5087
+ return /* @__PURE__ */ jsx(
5088
+ Box,
5089
+ {
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__;
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)
5084
5262
  }
5085
- );
5086
- case "dynamiczone":
5087
- return /* @__PURE__ */ jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
5088
- case "relation":
5089
- return /* @__PURE__ */ jsx(MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
5090
- case "richtext":
5091
- return /* @__PURE__ */ jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5092
- case "uid":
5093
- return /* @__PURE__ */ jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5094
- case "enumeration":
5095
- return /* @__PURE__ */ jsx(
5096
- InputRenderer$1,
5263
+ )
5264
+ );
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(
5097
5274
  {
5098
- ...props,
5099
- hint,
5100
- options: props.attribute.enum.map((value) => ({ value })),
5101
- type: props.customField ? "custom-field" : props.type,
5102
- disabled: fieldIsDisabled
5275
+ id: getTranslation("dnd.cancel-item"),
5276
+ defaultMessage: "{item}, dropped. Re-order cancelled."
5277
+ },
5278
+ {
5279
+ item: `${name2}.${index}`
5103
5280
  }
5104
- );
5105
- default:
5106
- const { unique: _unique, mainField: _mainField, ...restProps } = props;
5107
- return /* @__PURE__ */ jsx(
5108
- InputRenderer$1,
5281
+ )
5282
+ );
5283
+ };
5284
+ const handleGrabItem = (index) => {
5285
+ setLiveText(
5286
+ formatMessage(
5109
5287
  {
5110
- ...restProps,
5111
- hint,
5112
- type: props.customField ? "custom-field" : props.type,
5113
- 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)
5114
5294
  }
5115
- );
5295
+ )
5296
+ );
5297
+ };
5298
+ const handleDropItem = (index) => {
5299
+ setLiveText(
5300
+ formatMessage(
5301
+ {
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)
5308
+ }
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 });
5116
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
+ ] });
5117
5397
  };
5118
- const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5119
- const useFieldHint = (hint = void 0, attribute) => {
5120
- const { formatMessage } = useIntl();
5121
- const { maximum, minimum } = getMinMax(attribute);
5122
- if (!maximum && !minimum) {
5123
- return hint;
5124
- }
5125
- const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5126
- attribute.type
5127
- ) ? formatMessage(
5128
- {
5129
- id: "content-manager.form.Input.hint.character.unit",
5130
- defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5131
- },
5132
- {
5133
- maxValue: Math.max(minimum || 0, maximum || 0)
5134
- }
5135
- ) : null;
5136
- const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5137
- return formatMessage(
5138
- {
5139
- id: "content-manager.form.Input.hint.text",
5140
- defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5141
- },
5142
- {
5143
- min: minimum,
5144
- max: maximum,
5145
- description: hint,
5146
- unit: units,
5147
- divider: hasMinAndMax ? formatMessage({
5148
- id: "content-manager.form.Input.hint.minMaxDivider",
5149
- defaultMessage: " / "
5150
- }) : null,
5151
- 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};
5152
5415
  }
5153
- );
5154
- };
5155
- const getMinMax = (attribute) => {
5156
- if ("min" in attribute || "max" in attribute) {
5157
- return {
5158
- maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5159
- minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5160
- };
5161
- } else if ("maxLength" in attribute || "minLength" in attribute) {
5162
- return { maximum: attribute.maxLength, minimum: attribute.minLength };
5163
- } else {
5164
- return { maximum: void 0, minimum: void 0 };
5165
5416
  }
5166
- };
5167
- const MemoizedInputRenderer = memo(InputRenderer);
5168
- const DynamicComponent = ({
5169
- 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 = ({
5170
5429
  disabled,
5171
5430
  index,
5172
5431
  name: name2,
5173
- onRemoveComponentClick,
5174
- onMoveComponent,
5175
- onGrabItem,
5176
- onDropItem,
5177
- onCancel,
5178
- dynamicComponentsByCategory = {},
5179
- onAddComponent
5432
+ mainField = {
5433
+ name: "id",
5434
+ type: "integer"
5435
+ },
5436
+ children,
5437
+ onDeleteComponent,
5438
+ toggleCollapses,
5439
+ __temp_key__,
5440
+ ...dragProps
5180
5441
  }) => {
5181
5442
  const { formatMessage } = useIntl();
5182
- const formValues = useForm("DynamicComponent", (state) => state.values);
5183
- const {
5184
- edit: { components }
5185
- } = useDocLayout();
5186
- const title = React.useMemo(() => {
5187
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
5188
- const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
5189
- const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
5190
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
5191
- return mainValue;
5192
- }, [componentUid, components, formValues, name2, index]);
5193
- const { icon, displayName } = React.useMemo(() => {
5194
- const [category] = componentUid.split(".");
5195
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
5196
- (component) => component.uid === componentUid
5197
- ) ?? { icon: null, displayName: null };
5198
- return { icon: icon2, displayName: displayName2 };
5199
- }, [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(".");
5200
5448
  const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
5201
- type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
5449
+ type: `${ItemTypes.COMPONENT}_${componentKey}`,
5202
5450
  index,
5203
5451
  item: {
5204
5452
  index,
5205
- displayedValue: `${displayName} ${title}`,
5206
- icon
5453
+ displayedValue: displayValue
5207
5454
  },
5208
- onMoveItem: onMoveComponent,
5209
- onDropItem,
5210
- onGrabItem,
5211
- onCancel
5455
+ onStart() {
5456
+ toggleCollapses();
5457
+ },
5458
+ ...dragProps
5212
5459
  });
5213
5460
  React.useEffect(() => {
5214
5461
  dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
5215
5462
  }, [dragPreviewRef, index]);
5216
- const accordionValue = React.useId();
5217
- const { value = [], rawError } = useField(`${name2}.${index}`);
5218
- const [collapseToOpen, setCollapseToOpen] = React.useState("");
5219
- React.useEffect(() => {
5220
- if (rawError && value) {
5221
- setCollapseToOpen(accordionValue);
5222
- }
5223
- }, [rawError, value, accordionValue]);
5224
- const composedBoxRefs = useComposedRefs(boxRef, dropRef);
5225
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
5226
- /* @__PURE__ */ jsx(
5227
- IconButton,
5228
- {
5229
- variant: "ghost",
5230
- 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,
5231
5474
  {
5232
- id: getTranslation("components.DynamicZone.delete-label"),
5233
- defaultMessage: "Delete {name}"
5234
- },
5235
- { 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
+ }
5236
5483
  ),
5237
- onClick: onRemoveComponentClick,
5238
- children: /* @__PURE__ */ jsx(Trash, {})
5239
- }
5240
- ),
5241
- /* @__PURE__ */ jsx(
5242
- IconButton,
5243
- {
5244
- variant: "ghost",
5245
- onClick: (e) => e.stopPropagation(),
5246
- "data-handler-id": handlerId,
5247
- ref: dragRef,
5248
- label: formatMessage({
5249
- id: getTranslation("components.DragHandle-label"),
5250
- defaultMessage: "Drag"
5251
- }),
5252
- onKeyDown: handleKeyDown,
5253
- children: /* @__PURE__ */ jsx(Drag, {})
5254
- }
5255
- ),
5256
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
5257
- /* @__PURE__ */ jsxs(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
5258
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
5259
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage({
5260
- id: getTranslation("components.DynamicZone.more-actions"),
5261
- defaultMessage: "More actions"
5262
- }) })
5263
- ] }),
5264
- /* @__PURE__ */ jsxs(Menu.Content, { children: [
5265
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5266
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5267
- id: getTranslation("components.DynamicZone.add-item-above"),
5268
- defaultMessage: "Add component above"
5269
- }) }),
5270
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5271
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5272
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
5273
- ] }, category)) })
5274
- ] }),
5275
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
5276
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
5277
- id: getTranslation("components.DynamicZone.add-item-below"),
5278
- defaultMessage: "Add component below"
5279
- }) }),
5280
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
5281
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
5282
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
5283
- ] }, category)) })
5284
- ] })
5285
- ] })
5286
- ] })
5287
- ] });
5288
- const accordionTitle = title ? `${displayName} ${title}` : displayName;
5289
- return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
5290
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
5291
- /* @__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: [
5292
- /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5293
5484
  /* @__PURE__ */ jsx(
5294
- Accordion.Trigger,
5485
+ IconButton,
5295
5486
  {
5296
- icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
5297
- 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, {})
5298
5497
  }
5299
- ),
5300
- /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
5301
- ] }),
5302
- /* @__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(
5303
- Grid$1.Item,
5304
- {
5305
- col: 12,
5306
- s: 12,
5307
- xs: 12,
5308
- direction: "column",
5309
- alignItems: "stretch",
5310
- children: /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: row.map(({ size, ...field }) => {
5311
- const fieldName = `${name2}.${index}.${field.name}`;
5312
- const fieldWithTranslatedLabel = {
5313
- ...field,
5314
- label: formatMessage({
5315
- id: `content-manager.components.${componentUid}.${field.name}`,
5316
- defaultMessage: field.label
5317
- })
5318
- };
5319
- return /* @__PURE__ */ jsx(
5320
- Grid$1.Item,
5321
- {
5322
- col: size,
5323
- s: 12,
5324
- xs: 12,
5325
- direction: "column",
5326
- alignItems: "stretch",
5327
- children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
5328
- },
5329
- fieldName
5330
- );
5331
- }) })
5332
- },
5333
- rowInd
5334
- )) }) }) }) })
5335
- ] }) }) })
5336
- ] });
5337
- };
5338
- const StyledBox = styled(Box)`
5339
- > div:first-child {
5340
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5341
- }
5342
- `;
5343
- const AccordionContentRadius = styled(Box)`
5344
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5345
- `;
5346
- const Rectangle = styled(Box)`
5347
- width: ${({ theme }) => theme.spaces[2]};
5348
- height: ${({ theme }) => theme.spaces[4]};
5349
- `;
5350
- const Preview = styled.span`
5351
- display: block;
5352
- background-color: ${({ theme }) => theme.colors.primary100};
5353
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5354
- outline-offset: -1px;
5355
- padding: ${({ theme }) => theme.spaces[6]};
5356
- `;
5357
- const ComponentContainer = styled(Box)`
5358
- list-style: none;
5359
- padding: 0;
5360
- margin: 0;
5361
- `;
5362
- const DynamicZoneLabel = ({
5363
- hint,
5364
- label,
5365
- labelAction,
5366
- name: name2,
5367
- numberOfComponents = 0,
5368
- required
5369
- }) => {
5370
- return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5371
- Box,
5372
- {
5373
- paddingTop: 3,
5374
- paddingBottom: 3,
5375
- paddingRight: 4,
5376
- paddingLeft: 4,
5377
- borderRadius: "26px",
5378
- background: "neutral0",
5379
- shadow: "filterShadow",
5380
- color: "neutral500",
5381
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
5382
- /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
5383
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5384
- label || name2,
5385
- " "
5386
- ] }),
5387
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5388
- "(",
5389
- numberOfComponents,
5390
- ")"
5391
- ] }),
5392
- required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
5393
- labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
5394
- ] }),
5395
- hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
5498
+ )
5396
5499
  ] })
5397
- }
5398
- ) });
5399
- };
5400
- const [DynamicZoneProvider, useDynamicZone] = createContext(
5401
- "DynamicZone",
5402
- {
5403
- isInDynamicZone: false
5404
- }
5405
- );
5406
- const DynamicZone = ({
5407
- attribute,
5408
- disabled: disabledProp,
5409
- 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 = ({
5410
5523
  label,
5411
- labelAction,
5524
+ required,
5412
5525
  name: name2,
5413
- required = false
5526
+ attribute,
5527
+ disabled,
5528
+ labelAction,
5529
+ ...props
5414
5530
  }) => {
5415
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5416
- const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
5417
- const [liveText, setLiveText] = React.useState("");
5418
- const { components, isLoading } = useDoc();
5419
- const disabled = disabledProp || isLoading;
5420
- const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
5421
- "DynamicZone",
5422
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5423
- addFieldRow: addFieldRow2,
5424
- removeFieldRow: removeFieldRow2,
5425
- moveFieldRow: moveFieldRow2
5426
- })
5427
- );
5428
- const { value = [], error } = useField(name2);
5429
- const dynamicComponentsByCategory = React.useMemo(() => {
5430
- return attribute.components.reduce((acc, componentUid) => {
5431
- const { category, info } = components[componentUid] ?? { info: {} };
5432
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5433
- if (!acc[category]) {
5434
- acc[category] = [];
5435
- }
5436
- acc[category] = [...acc[category], component];
5437
- return acc;
5438
- }, {});
5439
- }, [attribute.components, components]);
5440
5531
  const { formatMessage } = useIntl();
5441
- const { toggleNotification } = useNotification();
5442
- const dynamicDisplayedComponentsLength = value.length;
5443
- const handleAddComponent = (uid, position) => {
5444
- setAddComponentIsOpen(false);
5445
- 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];
5446
5537
  const form = createDefaultForm(schema, components);
5447
- const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
5448
- ...data2,
5449
- __component: uid
5450
- }));
5451
- const data = transformations(form);
5452
- addFieldRow(name2, data, position);
5453
- };
5454
- const handleClickOpenPicker = () => {
5455
- if (dynamicDisplayedComponentsLength < max) {
5456
- setAddComponentIsOpen((prev) => !prev);
5457
- } else {
5458
- toggleNotification({
5459
- type: "info",
5460
- message: formatMessage({
5461
- id: getTranslation("components.notification.info.maximum-requirement")
5462
- })
5463
- });
5464
- }
5465
- };
5466
- const handleMoveComponent = (newIndex, currentIndex) => {
5467
- setLiveText(
5468
- formatMessage(
5469
- {
5470
- id: getTranslation("dnd.reorder"),
5471
- defaultMessage: "{item}, moved. New position in list: {position}."
5472
- },
5473
- {
5474
- item: `${name2}.${currentIndex}`,
5475
- position: getItemPos(newIndex)
5476
- }
5477
- )
5478
- );
5479
- moveFieldRow(name2, currentIndex, newIndex);
5480
- };
5481
- const getItemPos = (index) => `${index + 1} of ${value.length}`;
5482
- const handleCancel = (index) => {
5483
- setLiveText(
5484
- formatMessage(
5485
- {
5486
- id: getTranslation("dnd.cancel-item"),
5487
- defaultMessage: "{item}, dropped. Re-order cancelled."
5488
- },
5489
- {
5490
- item: `${name2}.${index}`
5491
- }
5492
- )
5493
- );
5494
- };
5495
- const handleGrabItem = (index) => {
5496
- setLiveText(
5497
- formatMessage(
5498
- {
5499
- id: getTranslation("dnd.grab-item"),
5500
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5501
- },
5502
- {
5503
- item: `${name2}.${index}`,
5504
- position: getItemPos(index)
5505
- }
5506
- )
5507
- );
5538
+ const data = transformDocument(schema, components)(form);
5539
+ field.onChange(name2, data);
5508
5540
  };
5509
- const handleDropItem = (index) => {
5510
- setLiveText(
5511
- formatMessage(
5512
- {
5513
- id: getTranslation("dnd.drop-item"),
5514
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
5515
- },
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,
5516
5553
  {
5517
- item: `${name2}.${index}`,
5518
- 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, {})
5519
5563
  }
5520
5564
  )
5521
- );
5522
- };
5523
- const handleRemoveComponent = (name22, currentIndex) => () => {
5524
- removeFieldRow(name22, currentIndex);
5525
- };
5526
- const hasError = error !== void 0;
5527
- const renderButtonLabel = () => {
5528
- if (addComponentIsOpen) {
5529
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5530
- }
5531
- if (hasError && dynamicDisplayedComponentsLength > max) {
5532
- return formatMessage(
5533
- {
5534
- id: getTranslation(`components.DynamicZone.extra-components`),
5535
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5536
- },
5537
- {
5538
- number: dynamicDisplayedComponentsLength - max
5539
- }
5540
- );
5541
- }
5542
- if (hasError && dynamicDisplayedComponentsLength < min) {
5543
- return formatMessage(
5544
- {
5545
- id: getTranslation(`components.DynamicZone.missing-components`),
5546
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5547
- },
5548
- { number: min - dynamicDisplayedComponentsLength }
5549
- );
5550
- }
5551
- return formatMessage(
5552
- {
5553
- id: getTranslation("components.DynamicZone.add-component"),
5554
- defaultMessage: "Add a component to {componentName}"
5555
- },
5556
- { componentName: label || name2 }
5557
- );
5558
- };
5559
- const level = useComponent("DynamicZone", (state) => state.level);
5560
- const ariaDescriptionId = React.useId();
5561
- return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5562
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
5563
- /* @__PURE__ */ jsx(
5564
- DynamicZoneLabel,
5565
- {
5566
- hint,
5567
- label,
5568
- labelAction,
5569
- name: name2,
5570
- numberOfComponents: dynamicDisplayedComponentsLength,
5571
- required
5572
- }
5573
- ),
5574
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5575
- id: getTranslation("dnd.instructions"),
5576
- defaultMessage: `Press spacebar to grab and re-order`
5577
- }) }),
5578
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5579
- /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
5580
- ComponentProvider,
5581
- {
5582
- level: level + 1,
5583
- uid: field.__component,
5584
- id: field.id,
5585
- type: "dynamiczone",
5586
- children: /* @__PURE__ */ jsx(
5587
- DynamicComponent,
5588
- {
5589
- disabled,
5590
- name: name2,
5591
- index,
5592
- componentUid: field.__component,
5593
- onMoveComponent: handleMoveComponent,
5594
- onRemoveComponentClick: handleRemoveComponent(name2, index),
5595
- onCancel: handleCancel,
5596
- onDropItem: handleDropItem,
5597
- onGrabItem: handleGrabItem,
5598
- onAddComponent: handleAddComponent,
5599
- dynamicComponentsByCategory
5600
- }
5601
- )
5602
- },
5603
- field.__temp_key__
5604
- )) })
5605
5565
  ] }),
5606
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5607
- AddComponentButton,
5608
- {
5609
- hasError,
5610
- isDisabled: disabled,
5611
- isOpen: addComponentIsOpen,
5612
- onClick: handleClickOpenPicker,
5613
- children: renderButtonLabel()
5614
- }
5615
- ) }),
5616
- /* @__PURE__ */ jsx(
5617
- ComponentPicker,
5618
- {
5619
- dynamicComponentsByCategory,
5620
- isOpen: addComponentIsOpen,
5621
- onClickAddComponent: handleAddComponent
5622
- }
5623
- )
5624
- ] }) });
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
+ ] });
5625
5571
  };
5572
+ const MemoizedComponentInput = React.memo(ComponentInput);
5626
5573
  export {
5627
5574
  DynamicZone as D,
5628
- MemoizedInputRenderer as M,
5575
+ FormLayout as F,
5576
+ MemoizedUIDInput as M,
5629
5577
  NotAllowedInput as N,
5630
5578
  useDynamicZone as a,
5631
5579
  useFieldHint as b,
5632
- createDefaultForm as c,
5633
- MemoizedUIDInput as d,
5634
- MemoizedWysiwyg as e,
5635
- MemoizedComponentInput as f,
5636
- MemoizedBlocksInput as g,
5637
- prepareTempKeys as p,
5638
- removeFieldsThatDontExistOnSchema as r,
5639
- transformDocument as t,
5580
+ MemoizedWysiwyg as c,
5581
+ MemoizedComponentInput as d,
5582
+ MemoizedBlocksInput as e,
5640
5583
  useLazyComponents as u
5641
5584
  };
5642
- //# sourceMappingURL=Field-Byr3mPTl.mjs.map
5585
+ //# sourceMappingURL=Input-BkKwZ6Qt.mjs.map