@strapi/content-manager 0.0.0-experimental.0af49f5c5ec496b0fad61ac9bfd4d0127b89d8d3 → 0.0.0-experimental.0e4ee97541bf8b600fc5272e0fee2b733aaf283b

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 (94) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-CtIa3aa2.mjs → ComponentConfigurationPage-D4H-v0et.mjs} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-CtIa3aa2.mjs.map → ComponentConfigurationPage-D4H-v0et.mjs.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-BLWQy8ru.js → ComponentConfigurationPage-DdkVGfXC.js} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-BLWQy8ru.js.map → ComponentConfigurationPage-DdkVGfXC.js.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-DsPR2DVk.mjs → EditConfigurationPage-D1nvB7Br.mjs} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-DsPR2DVk.mjs.map → EditConfigurationPage-D1nvB7Br.mjs.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-RQkymxCy.js → EditConfigurationPage-LYEvR4fW.js} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-RQkymxCy.js.map → EditConfigurationPage-LYEvR4fW.js.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-BPyVuPfM.mjs → EditViewPage-Bcnff6Vd.mjs} +11 -74
  10. package/dist/_chunks/EditViewPage-Bcnff6Vd.mjs.map +1 -0
  11. package/dist/_chunks/{EditViewPage-B-kExt8C.js → EditViewPage-DqelJ9UK.js} +13 -76
  12. package/dist/_chunks/EditViewPage-DqelJ9UK.js.map +1 -0
  13. package/dist/_chunks/{Form-BFi4MXMT.js → Form-CnHfBeiB.js} +2 -2
  14. package/dist/_chunks/{Form-BFi4MXMT.js.map → Form-CnHfBeiB.js.map} +1 -1
  15. package/dist/_chunks/{Form-C1IcWm1u.mjs → Form-CzPCJi3B.mjs} +2 -2
  16. package/dist/_chunks/{Form-C1IcWm1u.mjs.map → Form-CzPCJi3B.mjs.map} +1 -1
  17. package/dist/_chunks/{History-04ChQ4pl.mjs → History-CcmSn3Mj.mjs} +4 -4
  18. package/dist/_chunks/{History-04ChQ4pl.mjs.map → History-CcmSn3Mj.mjs.map} +1 -1
  19. package/dist/_chunks/{History-wjcK4L0C.js → History-zArjENzj.js} +15 -15
  20. package/dist/_chunks/{History-wjcK4L0C.js.map → History-zArjENzj.js.map} +1 -1
  21. package/dist/_chunks/{Field-DPIsQRre.js → Input-CDHKQd7o.js} +1150 -1182
  22. package/dist/_chunks/Input-CDHKQd7o.js.map +1 -0
  23. package/dist/_chunks/{Field-Dltnt1km.mjs → Input-aV8SSoTa.mjs} +1193 -1225
  24. package/dist/_chunks/Input-aV8SSoTa.mjs.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-BYqPYLSU.mjs → ListConfigurationPage-BPvzENJJ.mjs} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-BYqPYLSU.mjs.map → ListConfigurationPage-BPvzENJJ.mjs.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-CRbxIC3J.js → ListConfigurationPage-ByZAO_9H.js} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-CRbxIC3J.js.map → ListConfigurationPage-ByZAO_9H.js.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-D5NY9183.js → ListViewPage-BVKBeQAA.js} +13 -10
  30. package/dist/_chunks/{ListViewPage-D5NY9183.js.map → ListViewPage-BVKBeQAA.js.map} +1 -1
  31. package/dist/_chunks/{ListViewPage-FU2LBuhl.mjs → ListViewPage-HljQVnFH.mjs} +8 -5
  32. package/dist/_chunks/{ListViewPage-FU2LBuhl.mjs.map → ListViewPage-HljQVnFH.mjs.map} +1 -1
  33. package/dist/_chunks/{NoContentTypePage-BgQVE_Qb.js → NoContentTypePage-BV5zfDxr.js} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-BgQVE_Qb.js.map → NoContentTypePage-BV5zfDxr.js.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-DCKUkwb8.mjs → NoContentTypePage-BfHaSM-K.mjs} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-DCKUkwb8.mjs.map → NoContentTypePage-BfHaSM-K.mjs.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-jqve7C8l.mjs → NoPermissionsPage-D6ze2nQL.mjs} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-jqve7C8l.mjs.map → NoPermissionsPage-D6ze2nQL.mjs.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-C5jwn70o.js → NoPermissionsPage-vdNpc6jb.js} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-C5jwn70o.js.map → NoPermissionsPage-vdNpc6jb.js.map} +1 -1
  41. package/dist/_chunks/{Preview-DaOihysv.js → Preview-DEHdENT1.js} +8 -15
  42. package/dist/_chunks/Preview-DEHdENT1.js.map +1 -0
  43. package/dist/_chunks/{Preview-BMYN548c.mjs → Preview-vfWOtPG5.mjs} +8 -15
  44. package/dist/_chunks/Preview-vfWOtPG5.mjs.map +1 -0
  45. package/dist/_chunks/{Relations-gscPkxjF.mjs → Relations-B7_hbF0w.mjs} +6 -5
  46. package/dist/_chunks/Relations-B7_hbF0w.mjs.map +1 -0
  47. package/dist/_chunks/{Relations-CTGM7Hv5.js → Relations-DcoOBejP.js} +6 -5
  48. package/dist/_chunks/Relations-DcoOBejP.js.map +1 -0
  49. package/dist/_chunks/{en-BzQmavmK.js → en-BR48D_RH.js} +3 -1
  50. package/dist/_chunks/{en-BzQmavmK.js.map → en-BR48D_RH.js.map} +1 -1
  51. package/dist/_chunks/{en-CSxLmrh1.mjs → en-D65uIF6Y.mjs} +3 -1
  52. package/dist/_chunks/{en-CSxLmrh1.mjs.map → en-D65uIF6Y.mjs.map} +1 -1
  53. package/dist/_chunks/{fr-B2Kyv8Z9.js → fr-C43IbhA_.js} +4 -1
  54. package/dist/_chunks/{fr-B2Kyv8Z9.js.map → fr-C43IbhA_.js.map} +1 -1
  55. package/dist/_chunks/{fr--pg5jUbt.mjs → fr-DBseuRuB.mjs} +4 -1
  56. package/dist/_chunks/{fr--pg5jUbt.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  57. package/dist/_chunks/{index-Ca7YWlAA.js → index-CxLSGwnk.js} +254 -57
  58. package/dist/_chunks/index-CxLSGwnk.js.map +1 -0
  59. package/dist/_chunks/{index-DqasUQ6Q.mjs → index-EH8ZtHd5.mjs} +273 -76
  60. package/dist/_chunks/index-EH8ZtHd5.mjs.map +1 -0
  61. package/dist/_chunks/{layout-W3clJSCy.mjs → layout-CxDMdJ13.mjs} +3 -3
  62. package/dist/_chunks/{layout-W3clJSCy.mjs.map → layout-CxDMdJ13.mjs.map} +1 -1
  63. package/dist/_chunks/{layout-BW80JSCd.js → layout-DSeUTfMv.js} +3 -3
  64. package/dist/_chunks/{layout-BW80JSCd.js.map → layout-DSeUTfMv.js.map} +1 -1
  65. package/dist/_chunks/{relations-BlDkoeWh.mjs → relations-B8_Uu38Q.mjs} +17 -3
  66. package/dist/_chunks/relations-B8_Uu38Q.mjs.map +1 -0
  67. package/dist/_chunks/{relations-C9Usz9k5.js → relations-S5nNKdN3.js} +16 -2
  68. package/dist/_chunks/relations-S5nNKdN3.js.map +1 -0
  69. package/dist/_chunks/{useDebounce-CtcjDB3L.js → usePrev-B9w_-eYc.js} +1 -14
  70. package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
  71. package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
  72. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
  73. package/dist/admin/index.js +1 -1
  74. package/dist/admin/index.mjs +5 -5
  75. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  76. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  77. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  78. package/dist/admin/src/preview/pages/Preview.d.ts +1 -1
  79. package/package.json +6 -7
  80. package/dist/_chunks/EditViewPage-B-kExt8C.js.map +0 -1
  81. package/dist/_chunks/EditViewPage-BPyVuPfM.mjs.map +0 -1
  82. package/dist/_chunks/Field-DPIsQRre.js.map +0 -1
  83. package/dist/_chunks/Field-Dltnt1km.mjs.map +0 -1
  84. package/dist/_chunks/Preview-BMYN548c.mjs.map +0 -1
  85. package/dist/_chunks/Preview-DaOihysv.js.map +0 -1
  86. package/dist/_chunks/Relations-CTGM7Hv5.js.map +0 -1
  87. package/dist/_chunks/Relations-gscPkxjF.mjs.map +0 -1
  88. package/dist/_chunks/index-Ca7YWlAA.js.map +0 -1
  89. package/dist/_chunks/index-DqasUQ6Q.mjs.map +0 -1
  90. package/dist/_chunks/relations-BlDkoeWh.mjs.map +0 -1
  91. package/dist/_chunks/relations-C9Usz9k5.js.map +0 -1
  92. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  93. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +0 -29
  94. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
@@ -3,17 +3,10 @@ const jsxRuntime = require("react/jsx-runtime");
3
3
  const React = require("react");
4
4
  const strapiAdmin = require("@strapi/admin/strapi-admin");
5
5
  const designSystem = require("@strapi/design-system");
6
- const pipe$1 = require("lodash/fp/pipe");
7
- const reactIntl = require("react-intl");
8
- const index = require("./index-Ca7YWlAA.js");
9
- const fractionalIndexing = require("fractional-indexing");
10
- const Relations = require("./Relations-CTGM7Hv5.js");
11
6
  const Icons = require("@strapi/icons");
7
+ const reactIntl = require("react-intl");
8
+ const index = require("./index-CxLSGwnk.js");
12
9
  const styledComponents = require("styled-components");
13
- const ComponentIcon = require("./ComponentIcon-CRbtQEUV.js");
14
- const reactDndHtml5Backend = require("react-dnd-html5-backend");
15
- const useDragAndDrop = require("./useDragAndDrop-BMtgCYzL.js");
16
- const objects = require("./objects-BcXOv6_9.js");
17
10
  const slate = require("slate");
18
11
  const slateHistory = require("slate-history");
19
12
  const slateReact = require("slate-react");
@@ -68,9 +61,16 @@ require("prismjs/components/prism-typescript");
68
61
  require("prismjs/components/prism-tsx");
69
62
  require("prismjs/components/prism-vbnet");
70
63
  require("prismjs/components/prism-yaml");
71
- const useDebounce = require("./useDebounce-CtcjDB3L.js");
64
+ const usePrev = require("./usePrev-B9w_-eYc.js");
65
+ const useDragAndDrop = require("./useDragAndDrop-BMtgCYzL.js");
72
66
  const Toolbar = require("@radix-ui/react-toolbar");
67
+ const reactDndHtml5Backend = require("react-dnd-html5-backend");
73
68
  const reactRouterDom = require("react-router-dom");
69
+ const objects = require("./objects-BcXOv6_9.js");
70
+ const Relations = require("./Relations-DcoOBejP.js");
71
+ const pipe$1 = require("lodash/fp/pipe");
72
+ const ComponentIcon = require("./ComponentIcon-CRbtQEUV.js");
73
+ const relations = require("./relations-S5nNKdN3.js");
74
74
  const CodeMirror = require("codemirror5");
75
75
  const sanitizeHtml = require("sanitize-html");
76
76
  const highlight_js = require("highlight.js");
@@ -105,9 +105,9 @@ function _interopNamespace(e) {
105
105
  return Object.freeze(n);
106
106
  }
107
107
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
108
- const pipe__default = /* @__PURE__ */ _interopDefault(pipe$1);
109
108
  const Prism__namespace = /* @__PURE__ */ _interopNamespace(Prism);
110
109
  const Toolbar__namespace = /* @__PURE__ */ _interopNamespace(Toolbar);
110
+ const pipe__default = /* @__PURE__ */ _interopDefault(pipe$1);
111
111
  const CodeMirror__default = /* @__PURE__ */ _interopDefault(CodeMirror);
112
112
  const sanitizeHtml__default = /* @__PURE__ */ _interopDefault(sanitizeHtml);
113
113
  const Markdown__default = /* @__PURE__ */ _interopDefault(Markdown);
@@ -120,93 +120,6 @@ const ins__default = /* @__PURE__ */ _interopDefault(ins);
120
120
  const mark__default = /* @__PURE__ */ _interopDefault(mark);
121
121
  const sub__default = /* @__PURE__ */ _interopDefault(sub);
122
122
  const sup__default = /* @__PURE__ */ _interopDefault(sup);
123
- const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
124
- const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
125
- const traverse = (datum, attributes) => {
126
- return Object.entries(datum).reduce((acc, [key, value]) => {
127
- const attribute = attributes[key];
128
- if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
129
- acc[key] = value;
130
- return acc;
131
- }
132
- if (attribute.type === "component") {
133
- if (attribute.repeatable) {
134
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
135
- acc[key] = componentValue.map(
136
- (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
137
- );
138
- } else {
139
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
140
- acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
141
- }
142
- } else if (attribute.type === "dynamiczone") {
143
- const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
144
- acc[key] = dynamicZoneValue.map(
145
- (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
146
- );
147
- } else if (predicate(attribute, value)) {
148
- acc[key] = transform(value, attribute);
149
- } else {
150
- acc[key] = value;
151
- }
152
- return acc;
153
- }, {});
154
- };
155
- return traverse(data, schema.attributes);
156
- };
157
- const removeProhibitedFields = (prohibitedFields) => traverseData(
158
- (attribute) => prohibitedFields.includes(attribute.type),
159
- () => ""
160
- );
161
- const prepareRelations = traverseData(
162
- (attribute) => attribute.type === "relation",
163
- () => ({
164
- connect: [],
165
- disconnect: []
166
- })
167
- );
168
- const prepareTempKeys = traverseData(
169
- (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
170
- (data) => {
171
- if (Array.isArray(data) && data.length > 0) {
172
- const keys = fractionalIndexing.generateNKeysBetween(void 0, void 0, data.length);
173
- return data.map((datum, index2) => ({
174
- ...datum,
175
- __temp_key__: keys[index2]
176
- }));
177
- }
178
- return data;
179
- }
180
- );
181
- const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
182
- const schemaKeys = Object.keys(schema.attributes);
183
- const dataKeys = Object.keys(data);
184
- const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
185
- const revisedData = [...keysToRemove, ...index.DOCUMENT_META_FIELDS].reduce((acc, key) => {
186
- delete acc[key];
187
- return acc;
188
- }, structuredClone(data));
189
- return revisedData;
190
- };
191
- const removeNullValues = (data) => {
192
- return Object.entries(data).reduce((acc, [key, value]) => {
193
- if (value === null) {
194
- return acc;
195
- }
196
- acc[key] = value;
197
- return acc;
198
- }, {});
199
- };
200
- const transformDocument = (schema, components = {}) => (document2) => {
201
- const transformations = pipe__default.default(
202
- removeFieldsThatDontExistOnSchema(schema),
203
- removeProhibitedFields(["password"])(schema, components),
204
- removeNullValues,
205
- prepareRelations(schema, components),
206
- prepareTempKeys(schema, components)
207
- );
208
- return transformations(document2);
209
- };
210
123
  const componentStore = /* @__PURE__ */ new Map();
211
124
  const useLazyComponents = (componentUids = []) => {
212
125
  const [lazyComponentStore, setLazyComponentStore] = React.useState(Object.fromEntries(componentStore));
@@ -842,7 +755,7 @@ const ImageDialog = () => {
842
755
  const nodeImage = {
843
756
  ...expectedImage,
844
757
  alternativeText: expectedImage.alternativeText || expectedImage.name,
845
- url: useDebounce.prefixFileUrlWithBackendUrl(image.url)
758
+ url: usePrev.prefixFileUrlWithBackendUrl(image.url)
846
759
  };
847
760
  return nodeImage;
848
761
  });
@@ -2699,26 +2612,6 @@ const BlocksInput = React__namespace.forwardRef(
2699
2612
  }
2700
2613
  );
2701
2614
  const MemoizedBlocksInput = React__namespace.memo(BlocksInput);
2702
- const createDefaultForm = (contentType, components = {}) => {
2703
- const traverseSchema = (attributes) => {
2704
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2705
- if ("default" in attribute) {
2706
- acc[key] = attribute.default;
2707
- } else if (attribute.type === "component" && attribute.required) {
2708
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2709
- if (attribute.repeatable) {
2710
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2711
- } else {
2712
- acc[key] = defaultComponentForm;
2713
- }
2714
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2715
- acc[key] = [];
2716
- }
2717
- return acc;
2718
- }, {});
2719
- };
2720
- return traverseSchema(contentType.attributes);
2721
- };
2722
2615
  const Initializer = ({ disabled, name: name2, onClick }) => {
2723
2616
  const { formatMessage } = reactIntl.useIntl();
2724
2617
  const field = strapiAdmin.useField(name2);
@@ -2753,595 +2646,619 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2753
2646
  }
2754
2647
  ) });
2755
2648
  };
2756
- const NonRepeatableComponent = ({
2757
- attribute,
2758
- name: name2,
2649
+ const AddComponentButton = ({
2650
+ hasError,
2651
+ isDisabled,
2652
+ isOpen,
2759
2653
  children,
2760
- layout
2654
+ onClick
2655
+ }) => {
2656
+ return /* @__PURE__ */ jsxRuntime.jsx(
2657
+ StyledButton,
2658
+ {
2659
+ type: "button",
2660
+ onClick,
2661
+ disabled: isDisabled,
2662
+ background: "neutral0",
2663
+ style: { cursor: isDisabled ? "not-allowed" : "pointer" },
2664
+ variant: "tertiary",
2665
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { tag: "span", gap: 2, children: [
2666
+ /* @__PURE__ */ jsxRuntime.jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
2667
+ /* @__PURE__ */ jsxRuntime.jsx(
2668
+ designSystem.Typography,
2669
+ {
2670
+ variant: "pi",
2671
+ fontWeight: "bold",
2672
+ textColor: hasError && !isOpen ? "danger600" : "neutral600",
2673
+ children
2674
+ }
2675
+ )
2676
+ ] })
2677
+ }
2678
+ );
2679
+ };
2680
+ const StyledAddIcon = styledComponents.styled(Icons.PlusCircle)`
2681
+ height: ${({ theme }) => theme.spaces[6]};
2682
+ width: ${({ theme }) => theme.spaces[6]};
2683
+ transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
2684
+
2685
+ > circle {
2686
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2687
+ }
2688
+ > path {
2689
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
2690
+ }
2691
+ `;
2692
+ const StyledButton = styledComponents.styled(designSystem.Button)`
2693
+ padding-left: ${({ theme }) => theme.spaces[3]};
2694
+ border-radius: 26px;
2695
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2696
+ height: 5rem;
2697
+ `;
2698
+ const ComponentCategory = ({
2699
+ category,
2700
+ components = [],
2701
+ variant = "primary",
2702
+ onAddComponent
2761
2703
  }) => {
2762
2704
  const { formatMessage } = reactIntl.useIntl();
2763
- const { value } = strapiAdmin.useField(name2);
2764
- const level = Relations.useComponent("NonRepeatableComponent", (state) => state.level);
2765
- const isNested = level > 0;
2766
- return /* @__PURE__ */ jsxRuntime.jsx(Relations.ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsxRuntime.jsx(
2705
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: category, children: [
2706
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { variant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
2707
+ /* @__PURE__ */ jsxRuntime.jsx(ResponsiveAccordionContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsxRuntime.jsx(
2708
+ ComponentBox,
2709
+ {
2710
+ tag: "button",
2711
+ type: "button",
2712
+ background: "neutral100",
2713
+ justifyContent: "center",
2714
+ onClick: onAddComponent(uid),
2715
+ hasRadius: true,
2716
+ height: "8.4rem",
2717
+ shrink: 0,
2718
+ borderColor: "neutral200",
2719
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
2720
+ /* @__PURE__ */ jsxRuntime.jsx(ComponentIcon.ComponentIcon, { color: "currentColor", background: "primary200", icon }),
2721
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: displayName })
2722
+ ] })
2723
+ },
2724
+ uid
2725
+ )) }) })
2726
+ ] });
2727
+ };
2728
+ const ResponsiveAccordionContent = styledComponents.styled(designSystem.Accordion.Content)`
2729
+ container-type: inline-size;
2730
+ `;
2731
+ const Grid = styledComponents.styled(designSystem.Box)`
2732
+ display: grid;
2733
+ grid-template-columns: repeat(auto-fill, 100%);
2734
+ grid-gap: ${({ theme }) => theme.spaces[1]};
2735
+
2736
+ @container (min-width: ${() => RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
2737
+ grid-template-columns: repeat(auto-fill, 14rem);
2738
+ }
2739
+ `;
2740
+ const ComponentBox = styledComponents.styled(designSystem.Flex)`
2741
+ color: ${({ theme }) => theme.colors.neutral600};
2742
+ cursor: pointer;
2743
+
2744
+ @media (prefers-reduced-motion: no-preference) {
2745
+ transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2746
+ }
2747
+
2748
+ &:focus,
2749
+ &:hover {
2750
+ border: 1px solid ${({ theme }) => theme.colors.primary200};
2751
+ background: ${({ theme }) => theme.colors.primary100};
2752
+ color: ${({ theme }) => theme.colors.primary600};
2753
+ }
2754
+ `;
2755
+ const ComponentPicker = ({
2756
+ dynamicComponentsByCategory = {},
2757
+ isOpen,
2758
+ onClickAddComponent
2759
+ }) => {
2760
+ const { formatMessage } = reactIntl.useIntl();
2761
+ const handleAddComponentToDz = (componentUid) => () => {
2762
+ onClickAddComponent(componentUid);
2763
+ };
2764
+ if (!isOpen) {
2765
+ return null;
2766
+ }
2767
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2767
2768
  designSystem.Box,
2768
2769
  {
2769
- background: "neutral100",
2770
- paddingLeft: 6,
2771
- paddingRight: 6,
2772
2770
  paddingTop: 6,
2773
2771
  paddingBottom: 6,
2774
- hasRadius: isNested,
2775
- borderColor: isNested ? "neutral200" : void 0,
2776
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index2) => {
2777
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2778
- const completeFieldName = `${name2}.${field.name}`;
2779
- const translatedLabel = formatMessage({
2780
- id: `content-manager.components.${attribute.component}.${field.name}`,
2781
- defaultMessage: field.label
2782
- });
2783
- return /* @__PURE__ */ jsxRuntime.jsx(
2784
- designSystem.Grid.Item,
2785
- {
2786
- col: size,
2787
- s: 12,
2788
- xs: 12,
2789
- direction: "column",
2790
- alignItems: "stretch",
2791
- children: children({ ...field, label: translatedLabel, name: completeFieldName })
2792
- },
2793
- completeFieldName
2794
- );
2795
- }) }, index2);
2796
- }) })
2772
+ paddingLeft: 5,
2773
+ paddingRight: 5,
2774
+ background: "neutral0",
2775
+ shadow: "tableShadow",
2776
+ borderColor: "neutral150",
2777
+ hasRadius: true,
2778
+ children: [
2779
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
2780
+ id: index.getTranslation("components.DynamicZone.ComponentPicker-label"),
2781
+ defaultMessage: "Pick one component"
2782
+ }) }) }),
2783
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { defaultValue: Object.keys(dynamicComponentsByCategory)[0], children: Object.entries(dynamicComponentsByCategory).map(([category, components], index2) => /* @__PURE__ */ jsxRuntime.jsx(
2784
+ ComponentCategory,
2785
+ {
2786
+ category,
2787
+ components,
2788
+ onAddComponent: handleAddComponentToDz,
2789
+ variant: index2 % 2 === 1 ? "primary" : "secondary"
2790
+ },
2791
+ category
2792
+ )) }) })
2793
+ ]
2797
2794
  }
2798
- ) });
2795
+ );
2799
2796
  };
2800
- const RepeatableComponent = ({
2801
- attribute,
2797
+ const DynamicComponent = ({
2798
+ componentUid,
2802
2799
  disabled,
2800
+ index: index$1,
2803
2801
  name: name2,
2804
- mainField,
2805
- children,
2806
- layout
2802
+ onRemoveComponentClick,
2803
+ onMoveComponent,
2804
+ onGrabItem,
2805
+ onDropItem,
2806
+ onCancel,
2807
+ dynamicComponentsByCategory = {},
2808
+ onAddComponent,
2809
+ children
2807
2810
  }) => {
2808
- const { toggleNotification } = strapiAdmin.useNotification();
2809
2811
  const { formatMessage } = reactIntl.useIntl();
2810
- const { search: searchString } = reactRouterDom.useLocation();
2811
- const search = React__namespace.useMemo(() => new URLSearchParams(searchString), [searchString]);
2812
- const { components } = index.useDoc();
2812
+ const formValues = strapiAdmin.useForm("DynamicComponent", (state) => state.values);
2813
2813
  const {
2814
- value = [],
2815
- error,
2816
- rawError
2817
- } = strapiAdmin.useField(name2);
2818
- const addFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.addFieldRow);
2819
- const moveFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.moveFieldRow);
2820
- const removeFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.removeFieldRow);
2821
- const { max = Infinity } = attribute;
2822
- const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
2823
- const [liveText, setLiveText] = React__namespace.useState("");
2824
- React__namespace.useEffect(() => {
2825
- const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
2826
- const hasNestedValue = value && Array.isArray(value) && value.length > 0;
2827
- if (hasNestedErrors && hasNestedValue) {
2828
- const errorOpenItems = rawError.map((_, idx) => {
2829
- return value[idx] ? value[idx].__temp_key__ : null;
2830
- }).filter((value2) => !!value2);
2831
- if (errorOpenItems && errorOpenItems.length > 0) {
2832
- setCollapseToOpen((collapseToOpen2) => {
2833
- if (!errorOpenItems.includes(collapseToOpen2)) {
2834
- return errorOpenItems[0];
2835
- }
2836
- return collapseToOpen2;
2837
- });
2838
- }
2839
- }
2840
- }, [rawError, value]);
2841
- const componentTmpKeyWithFocussedField = React__namespace.useMemo(() => {
2842
- if (search.has("field")) {
2843
- const fieldParam = search.get("field");
2844
- if (!fieldParam) {
2845
- return void 0;
2846
- }
2847
- const [, path] = fieldParam.split(`${name2}.`);
2848
- if (objects.getIn(value, path, void 0) !== void 0) {
2849
- const [subpath] = path.split(".");
2850
- return objects.getIn(value, subpath, void 0)?.__temp_key__;
2851
- }
2852
- }
2853
- return void 0;
2854
- }, [search, name2, value]);
2855
- const prevValue = useDebounce.usePrev(value);
2814
+ edit: { components }
2815
+ } = index.useDocLayout();
2816
+ const title = React__namespace.useMemo(() => {
2817
+ const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
2818
+ const mainFieldValue = objects.getIn(formValues, `${name2}.${index$1}.${mainField}`);
2819
+ const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
2820
+ const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
2821
+ return mainValue;
2822
+ }, [componentUid, components, formValues, name2, index$1]);
2823
+ const { icon, displayName } = React__namespace.useMemo(() => {
2824
+ const [category] = componentUid.split(".");
2825
+ const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
2826
+ (component) => component.uid === componentUid
2827
+ ) ?? { icon: null, displayName: null };
2828
+ return { icon: icon2, displayName: displayName2 };
2829
+ }, [componentUid, dynamicComponentsByCategory]);
2830
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(!disabled, {
2831
+ type: `${useDragAndDrop.ItemTypes.DYNAMIC_ZONE}_${name2}`,
2832
+ index: index$1,
2833
+ item: {
2834
+ index: index$1,
2835
+ displayedValue: `${displayName} ${title}`,
2836
+ icon
2837
+ },
2838
+ onMoveItem: onMoveComponent,
2839
+ onDropItem,
2840
+ onGrabItem,
2841
+ onCancel
2842
+ });
2856
2843
  React__namespace.useEffect(() => {
2857
- if (prevValue && prevValue.length < value.length) {
2858
- setCollapseToOpen(value[value.length - 1].__temp_key__);
2859
- }
2860
- }, [value, prevValue]);
2844
+ dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
2845
+ }, [dragPreviewRef, index$1]);
2846
+ const accordionValue = React__namespace.useId();
2847
+ const { value = [], rawError } = strapiAdmin.useField(`${name2}.${index$1}`);
2848
+ const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
2861
2849
  React__namespace.useEffect(() => {
2862
- if (typeof componentTmpKeyWithFocussedField === "string") {
2863
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2864
- }
2865
- }, [componentTmpKeyWithFocussedField]);
2866
- const toggleCollapses = () => {
2867
- setCollapseToOpen("");
2868
- };
2869
- const handleClick = () => {
2870
- if (value.length < max) {
2871
- const schema = components[attribute.component];
2872
- const form = createDefaultForm(schema, components);
2873
- const data = transformDocument(schema, components)(form);
2874
- addFieldRow(name2, data);
2875
- } else if (value.length >= max) {
2876
- toggleNotification({
2877
- type: "info",
2878
- message: formatMessage({
2879
- id: index.getTranslation("components.notification.info.maximum-requirement")
2880
- })
2881
- });
2850
+ if (rawError && value) {
2851
+ setCollapseToOpen(accordionValue);
2882
2852
  }
2883
- };
2884
- const handleMoveComponentField = (newIndex, currentIndex) => {
2885
- setLiveText(
2886
- formatMessage(
2887
- {
2888
- id: index.getTranslation("dnd.reorder"),
2889
- defaultMessage: "{item}, moved. New position in list: {position}."
2890
- },
2891
- {
2892
- item: `${name2}.${currentIndex}`,
2893
- position: getItemPos(newIndex)
2894
- }
2895
- )
2896
- );
2897
- moveFieldRow(name2, currentIndex, newIndex);
2898
- };
2899
- const handleValueChange = (key) => {
2900
- setCollapseToOpen(key);
2901
- };
2902
- const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
2903
- const handleCancel = (index$1) => {
2904
- setLiveText(
2905
- formatMessage(
2906
- {
2907
- id: index.getTranslation("dnd.cancel-item"),
2908
- defaultMessage: "{item}, dropped. Re-order cancelled."
2909
- },
2910
- {
2911
- item: `${name2}.${index$1}`
2912
- }
2913
- )
2914
- );
2915
- };
2916
- const handleGrabItem = (index$1) => {
2917
- setLiveText(
2918
- formatMessage(
2919
- {
2920
- id: index.getTranslation("dnd.grab-item"),
2921
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
2922
- },
2853
+ }, [rawError, value, accordionValue]);
2854
+ const composedBoxRefs = designSystem.useComposedRefs(boxRef, dropRef);
2855
+ const accordionActions = disabled ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2856
+ /* @__PURE__ */ jsxRuntime.jsx(
2857
+ designSystem.IconButton,
2858
+ {
2859
+ variant: "ghost",
2860
+ label: formatMessage(
2861
+ {
2862
+ id: index.getTranslation("components.DynamicZone.delete-label"),
2863
+ defaultMessage: "Delete {name}"
2864
+ },
2865
+ { name: title }
2866
+ ),
2867
+ onClick: onRemoveComponentClick,
2868
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
2869
+ }
2870
+ ),
2871
+ /* @__PURE__ */ jsxRuntime.jsx(
2872
+ designSystem.IconButton,
2873
+ {
2874
+ variant: "ghost",
2875
+ onClick: (e) => e.stopPropagation(),
2876
+ "data-handler-id": handlerId,
2877
+ ref: dragRef,
2878
+ label: formatMessage({
2879
+ id: index.getTranslation("components.DragHandle-label"),
2880
+ defaultMessage: "Drag"
2881
+ }),
2882
+ onKeyDown: handleKeyDown,
2883
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
2884
+ }
2885
+ ),
2886
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
2887
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 0, paddingRight: 0, children: /* @__PURE__ */ jsxRuntime.jsx(
2888
+ designSystem.IconButton,
2923
2889
  {
2924
- item: `${name2}.${index$1}`,
2925
- position: getItemPos(index$1)
2890
+ variant: "ghost",
2891
+ label: formatMessage({
2892
+ id: index.getTranslation("components.DynamicZone.more-actions"),
2893
+ defaultMessage: "More actions"
2894
+ }),
2895
+ tag: "span",
2896
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false })
2926
2897
  }
2927
- )
2928
- );
2929
- };
2930
- const handleDropItem = (index$1) => {
2931
- setLiveText(
2932
- formatMessage(
2933
- {
2934
- id: index.getTranslation("dnd.drop-item"),
2935
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
2936
- },
2898
+ ) }),
2899
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { children: [
2900
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
2901
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
2902
+ id: index.getTranslation("components.DynamicZone.add-item-above"),
2903
+ defaultMessage: "Add component above"
2904
+ }) }),
2905
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
2906
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
2907
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1), children: displayName2 }, componentUid))
2908
+ ] }, category)) })
2909
+ ] }),
2910
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
2911
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
2912
+ id: index.getTranslation("components.DynamicZone.add-item-below"),
2913
+ defaultMessage: "Add component below"
2914
+ }) }),
2915
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
2916
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
2917
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1 + 1), children: displayName2 }, componentUid))
2918
+ ] }, category)) })
2919
+ ] })
2920
+ ] })
2921
+ ] })
2922
+ ] });
2923
+ const accordionTitle = title ? `${displayName} ${title}` : displayName;
2924
+ return /* @__PURE__ */ jsxRuntime.jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
2925
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Rectangle, { background: "neutral200" }) }),
2926
+ /* @__PURE__ */ jsxRuntime.jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsxRuntime.jsx(Preview$1, {}) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { value: collapseToOpen, onValueChange: setCollapseToOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: accordionValue, children: [
2927
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
2928
+ /* @__PURE__ */ jsxRuntime.jsx(
2929
+ designSystem.Accordion.Trigger,
2930
+ {
2931
+ icon: icon && ComponentIcon.COMPONENT_ICONS[icon] ? ComponentIcon.COMPONENT_ICONS[icon] : ComponentIcon.COMPONENT_ICONS.dashboard,
2932
+ children: accordionTitle
2933
+ }
2934
+ ),
2935
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Actions, { children: accordionActions })
2936
+ ] }),
2937
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsxRuntime.jsx(
2938
+ designSystem.Grid.Item,
2937
2939
  {
2938
- item: `${name2}.${index$1}`,
2939
- position: getItemPos(index$1)
2940
- }
2941
- )
2942
- );
2943
- };
2944
- const ariaDescriptionId = React__namespace.useId();
2945
- const level = Relations.useComponent("RepeatableComponent", (state) => state.level);
2946
- if (value.length === 0) {
2947
- return /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2948
- }
2949
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { hasRadius: true, children: [
2950
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2951
- id: index.getTranslation("dnd.instructions"),
2952
- defaultMessage: `Press spacebar to grab and re-order`
2953
- }) }),
2954
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2955
- /* @__PURE__ */ jsxRuntime.jsxs(
2956
- AccordionRoot,
2957
- {
2958
- $error: error,
2959
- value: collapseToOpen,
2960
- onValueChange: handleValueChange,
2961
- "aria-describedby": ariaDescriptionId,
2962
- children: [
2963
- value.map(({ __temp_key__: key, id }, index2) => {
2964
- const nameWithIndex = `${name2}.${index2}`;
2940
+ col: 12,
2941
+ s: 12,
2942
+ xs: 12,
2943
+ direction: "column",
2944
+ alignItems: "stretch",
2945
+ children: /* @__PURE__ */ jsxRuntime.jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
2946
+ const fieldName = `${name2}.${index$1}.${field.name}`;
2947
+ const fieldWithTranslatedLabel = {
2948
+ ...field,
2949
+ label: formatMessage({
2950
+ id: `content-manager.components.${componentUid}.${field.name}`,
2951
+ defaultMessage: field.label
2952
+ })
2953
+ };
2965
2954
  return /* @__PURE__ */ jsxRuntime.jsx(
2966
- Relations.ComponentProvider,
2955
+ ResponsiveGridItem,
2967
2956
  {
2968
- id,
2969
- uid: attribute.component,
2970
- level: level + 1,
2971
- type: "repeatable",
2972
- children: /* @__PURE__ */ jsxRuntime.jsx(
2973
- Component,
2974
- {
2975
- disabled,
2976
- name: nameWithIndex,
2977
- attribute,
2978
- index: index2,
2979
- mainField,
2980
- onMoveItem: handleMoveComponentField,
2981
- onDeleteComponent: () => {
2982
- removeFieldRow(name2, index2);
2983
- toggleCollapses();
2984
- },
2985
- toggleCollapses,
2986
- onCancel: handleCancel,
2987
- onDropItem: handleDropItem,
2988
- onGrabItem: handleGrabItem,
2989
- __temp_key__: key,
2990
- children: layout.map((row, index22) => {
2991
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2992
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2993
- const translatedLabel = formatMessage({
2994
- id: `content-manager.components.${attribute.component}.${field.name}`,
2995
- defaultMessage: field.label
2996
- });
2997
- return /* @__PURE__ */ jsxRuntime.jsx(
2998
- designSystem.Grid.Item,
2999
- {
3000
- col: size,
3001
- s: 12,
3002
- xs: 12,
3003
- direction: "column",
3004
- alignItems: "stretch",
3005
- children: children({
3006
- ...field,
3007
- label: translatedLabel,
3008
- name: completeFieldName
3009
- })
3010
- },
3011
- completeFieldName
3012
- );
3013
- }) }, index22);
3014
- })
3015
- }
3016
- )
2957
+ col: size,
2958
+ s: 12,
2959
+ xs: 12,
2960
+ direction: "column",
2961
+ alignItems: "stretch",
2962
+ children: children ? children({ ...fieldWithTranslatedLabel, name: fieldName }) : /* @__PURE__ */ jsxRuntime.jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
3017
2963
  },
3018
- key
2964
+ fieldName
3019
2965
  );
3020
- }),
3021
- /* @__PURE__ */ jsxRuntime.jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Plus, {}), children: formatMessage({
3022
- id: index.getTranslation("containers.EditView.add.new-entry"),
3023
- defaultMessage: "Add an entry"
3024
2966
  }) })
3025
- ]
3026
- }
3027
- )
2967
+ },
2968
+ rowInd
2969
+ )) }) }) }) })
2970
+ ] }) }) })
3028
2971
  ] });
3029
2972
  };
3030
- const AccordionRoot = styledComponents.styled(designSystem.Accordion.Root)`
3031
- border: 1px solid
3032
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
3033
- `;
3034
- const TextButtonCustom = styledComponents.styled(designSystem.TextButton)`
3035
- width: 100%;
3036
- display: flex;
3037
- justify-content: center;
3038
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
3039
- padding-inline: ${(props) => props.theme.spaces[6]};
3040
- padding-block: ${(props) => props.theme.spaces[3]};
3041
-
3042
- &:not([disabled]) {
3043
- cursor: pointer;
3044
-
3045
- &:hover {
3046
- background-color: ${(props) => props.theme.colors.primary100};
3047
- }
3048
- }
3049
-
3050
- span {
3051
- font-weight: 600;
3052
- font-size: 1.4rem;
3053
- line-height: 2.4rem;
3054
- }
3055
-
3056
- @media (prefers-reduced-motion: no-preference) {
3057
- transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2973
+ const StyledBox = styledComponents.styled(designSystem.Box)`
2974
+ > div:first-child {
2975
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
3058
2976
  }
3059
2977
  `;
3060
- const Component = ({
3061
- disabled,
3062
- index: index$1,
3063
- name: name2,
3064
- mainField = {
3065
- name: "id",
3066
- type: "integer"
3067
- },
3068
- children,
3069
- onDeleteComponent,
3070
- toggleCollapses,
3071
- __temp_key__,
3072
- ...dragProps
3073
- }) => {
3074
- const { formatMessage } = reactIntl.useIntl();
3075
- const displayValue = strapiAdmin.useForm("RepeatableComponent", (state) => {
3076
- return objects.getIn(state.values, [...name2.split("."), mainField.name]);
3077
- });
3078
- const accordionRef = React__namespace.useRef(null);
3079
- const componentKey = name2.split(".").slice(0, -1).join(".");
3080
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(!disabled, {
3081
- type: `${useDragAndDrop.ItemTypes.COMPONENT}_${componentKey}`,
3082
- index: index$1,
3083
- item: {
3084
- index: index$1,
3085
- displayedValue: displayValue
3086
- },
3087
- onStart() {
3088
- toggleCollapses();
3089
- },
3090
- ...dragProps
3091
- });
3092
- React__namespace.useEffect(() => {
3093
- dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
3094
- }, [dragPreviewRef, index$1]);
3095
- const composedAccordionRefs = designSystem.useComposedRefs(accordionRef, dragRef);
3096
- const composedBoxRefs = designSystem.useComposedRefs(
3097
- boxRef,
3098
- dropRef
3099
- );
3100
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isDragging ? /* @__PURE__ */ jsxRuntime.jsx(Preview$1, {}) : /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
3101
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
3102
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: displayValue }),
3103
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Actions, { children: [
3104
- /* @__PURE__ */ jsxRuntime.jsx(
3105
- designSystem.IconButton,
3106
- {
3107
- variant: "ghost",
3108
- onClick: onDeleteComponent,
3109
- label: formatMessage({
3110
- id: index.getTranslation("containers.Edit.delete"),
3111
- defaultMessage: "Delete"
3112
- }),
3113
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
3114
- }
3115
- ),
3116
- /* @__PURE__ */ jsxRuntime.jsx(
3117
- designSystem.IconButton,
3118
- {
3119
- ref: composedAccordionRefs,
3120
- variant: "ghost",
3121
- onClick: (e) => e.stopPropagation(),
3122
- "data-handler-id": handlerId,
3123
- label: formatMessage({
3124
- id: index.getTranslation("components.DragHandle-label"),
3125
- defaultMessage: "Drag"
3126
- }),
3127
- onKeyDown: handleKeyDown,
3128
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
3129
- }
3130
- )
3131
- ] })
3132
- ] }),
3133
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(
3134
- designSystem.Flex,
3135
- {
3136
- direction: "column",
3137
- alignItems: "stretch",
3138
- background: "neutral100",
3139
- padding: 6,
3140
- gap: 6,
3141
- children
3142
- }
3143
- ) })
3144
- ] }) });
3145
- };
3146
- const Preview$1 = () => {
3147
- return /* @__PURE__ */ jsxRuntime.jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
3148
- };
3149
- const StyledSpan = styledComponents.styled(designSystem.Box)`
2978
+ const AccordionContentRadius = styledComponents.styled(designSystem.Box)`
2979
+ border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
2980
+ `;
2981
+ const Rectangle = styledComponents.styled(designSystem.Box)`
2982
+ width: ${({ theme }) => theme.spaces[2]};
2983
+ height: ${({ theme }) => theme.spaces[4]};
2984
+ `;
2985
+ const Preview$1 = styledComponents.styled.span`
3150
2986
  display: block;
2987
+ background-color: ${({ theme }) => theme.colors.primary100};
3151
2988
  outline: 1px dashed ${({ theme }) => theme.colors.primary500};
3152
2989
  outline-offset: -1px;
2990
+ padding: ${({ theme }) => theme.spaces[6]};
3153
2991
  `;
3154
- const ComponentInput = ({
2992
+ const ComponentContainer = styledComponents.styled(designSystem.Box)`
2993
+ list-style: none;
2994
+ padding: 0;
2995
+ margin: 0;
2996
+ `;
2997
+ const DynamicZoneLabel = ({
2998
+ hint,
3155
2999
  label,
3156
- required,
3000
+ labelAction,
3157
3001
  name: name2,
3002
+ numberOfComponents = 0,
3003
+ required
3004
+ }) => {
3005
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
3006
+ designSystem.Box,
3007
+ {
3008
+ paddingTop: 3,
3009
+ paddingBottom: 3,
3010
+ paddingRight: 4,
3011
+ paddingLeft: 4,
3012
+ borderRadius: "26px",
3013
+ background: "neutral0",
3014
+ shadow: "filterShadow",
3015
+ color: "neutral500",
3016
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", justifyContent: "center", children: [
3017
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { maxWidth: "35.6rem", children: [
3018
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
3019
+ label || name2,
3020
+ " "
3021
+ ] }),
3022
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
3023
+ "(",
3024
+ numberOfComponents,
3025
+ ")"
3026
+ ] }),
3027
+ required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: "*" }),
3028
+ labelAction && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 1, children: labelAction })
3029
+ ] }),
3030
+ hint && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
3031
+ ] })
3032
+ }
3033
+ ) });
3034
+ };
3035
+ const [DynamicZoneProvider, useDynamicZone] = strapiAdmin.createContext(
3036
+ "DynamicZone",
3037
+ {
3038
+ isInDynamicZone: false
3039
+ }
3040
+ );
3041
+ const DynamicZone = ({
3158
3042
  attribute,
3159
- disabled,
3043
+ disabled: disabledProp,
3044
+ hint,
3045
+ label,
3160
3046
  labelAction,
3161
- ...props
3047
+ name: name2,
3048
+ required = false,
3049
+ children
3162
3050
  }) => {
3163
- const { formatMessage } = reactIntl.useIntl();
3164
- const field = strapiAdmin.useField(name2);
3165
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
3166
- const { components } = index.useDoc();
3167
- const handleInitialisationClick = () => {
3168
- const schema = components[attribute.component];
3169
- const form = createDefaultForm(schema, components);
3170
- const data = transformDocument(schema, components)(form);
3171
- field.onChange(name2, data);
3172
- };
3173
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: field.error, required, children: [
3174
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
3175
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { action: labelAction, children: [
3176
- label,
3177
- attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3178
- (",
3179
- Array.isArray(field.value) ? field.value.length : 0,
3180
- ")"
3181
- ] })
3182
- ] }),
3183
- showResetComponent && /* @__PURE__ */ jsxRuntime.jsx(
3184
- designSystem.IconButton,
3051
+ const { max = Infinity, min = -Infinity } = attribute ?? {};
3052
+ const [addComponentIsOpen, setAddComponentIsOpen] = React__namespace.useState(false);
3053
+ const [liveText, setLiveText] = React__namespace.useState("");
3054
+ const { components, isLoading } = index.useDoc();
3055
+ const disabled = disabledProp || isLoading;
3056
+ const { addFieldRow, removeFieldRow, moveFieldRow } = strapiAdmin.useForm(
3057
+ "DynamicZone",
3058
+ ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
3059
+ addFieldRow: addFieldRow2,
3060
+ removeFieldRow: removeFieldRow2,
3061
+ moveFieldRow: moveFieldRow2
3062
+ })
3063
+ );
3064
+ const { value = [], error } = strapiAdmin.useField(name2);
3065
+ const dynamicComponentsByCategory = React__namespace.useMemo(() => {
3066
+ return attribute.components.reduce((acc, componentUid) => {
3067
+ const { category, info } = components[componentUid] ?? { info: {} };
3068
+ const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
3069
+ if (!acc[category]) {
3070
+ acc[category] = [];
3071
+ }
3072
+ acc[category] = [...acc[category], component];
3073
+ return acc;
3074
+ }, {});
3075
+ }, [attribute.components, components]);
3076
+ const { formatMessage } = reactIntl.useIntl();
3077
+ const { toggleNotification } = strapiAdmin.useNotification();
3078
+ const dynamicDisplayedComponentsLength = value.length;
3079
+ const handleAddComponent = (uid, position) => {
3080
+ setAddComponentIsOpen(false);
3081
+ const schema = components[uid];
3082
+ const form = index.createDefaultForm(schema, components);
3083
+ const transformations = pipe__default.default(index.transformDocument(schema, components), (data2) => ({
3084
+ ...data2,
3085
+ __component: uid
3086
+ }));
3087
+ const data = transformations(form);
3088
+ addFieldRow(name2, data, position);
3089
+ };
3090
+ const handleClickOpenPicker = () => {
3091
+ if (dynamicDisplayedComponentsLength < max) {
3092
+ setAddComponentIsOpen((prev) => !prev);
3093
+ } else {
3094
+ toggleNotification({
3095
+ type: "info",
3096
+ message: formatMessage({
3097
+ id: index.getTranslation("components.notification.info.maximum-requirement")
3098
+ })
3099
+ });
3100
+ }
3101
+ };
3102
+ const handleMoveComponent = (newIndex, currentIndex) => {
3103
+ setLiveText(
3104
+ formatMessage(
3185
3105
  {
3186
- label: formatMessage({
3187
- id: index.getTranslation("components.reset-entry"),
3188
- defaultMessage: "Reset Entry"
3189
- }),
3190
- variant: "ghost",
3191
- onClick: () => {
3192
- field.onChange(name2, null);
3193
- },
3194
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
3106
+ id: index.getTranslation("dnd.reorder"),
3107
+ defaultMessage: "{item}, moved. New position in list: {position}."
3108
+ },
3109
+ {
3110
+ item: `${name2}.${currentIndex}`,
3111
+ position: getItemPos(newIndex)
3195
3112
  }
3196
3113
  )
3197
- ] }),
3198
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
3199
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsxRuntime.jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
3200
- attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
3201
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
3202
- ] });
3203
- };
3204
- const MemoizedComponentInput = React__namespace.memo(ComponentInput);
3205
- const AddComponentButton = ({
3206
- hasError,
3207
- isDisabled,
3208
- isOpen,
3209
- children,
3210
- onClick
3211
- }) => {
3212
- return /* @__PURE__ */ jsxRuntime.jsx(
3213
- StyledButton,
3214
- {
3215
- type: "button",
3216
- onClick,
3217
- disabled: isDisabled,
3218
- background: "neutral0",
3219
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
3220
- variant: "tertiary",
3221
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { tag: "span", gap: 2, children: [
3222
- /* @__PURE__ */ jsxRuntime.jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
3223
- /* @__PURE__ */ jsxRuntime.jsx(
3224
- designSystem.Typography,
3225
- {
3226
- variant: "pi",
3227
- fontWeight: "bold",
3228
- textColor: hasError && !isOpen ? "danger600" : "neutral600",
3229
- children
3230
- }
3231
- )
3232
- ] })
3114
+ );
3115
+ moveFieldRow(name2, currentIndex, newIndex);
3116
+ };
3117
+ const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
3118
+ const handleCancel = (index$1) => {
3119
+ setLiveText(
3120
+ formatMessage(
3121
+ {
3122
+ id: index.getTranslation("dnd.cancel-item"),
3123
+ defaultMessage: "{item}, dropped. Re-order cancelled."
3124
+ },
3125
+ {
3126
+ item: `${name2}.${index$1}`
3127
+ }
3128
+ )
3129
+ );
3130
+ };
3131
+ const handleGrabItem = (index$1) => {
3132
+ setLiveText(
3133
+ formatMessage(
3134
+ {
3135
+ id: index.getTranslation("dnd.grab-item"),
3136
+ defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
3137
+ },
3138
+ {
3139
+ item: `${name2}.${index$1}`,
3140
+ position: getItemPos(index$1)
3141
+ }
3142
+ )
3143
+ );
3144
+ };
3145
+ const handleDropItem = (index$1) => {
3146
+ setLiveText(
3147
+ formatMessage(
3148
+ {
3149
+ id: index.getTranslation("dnd.drop-item"),
3150
+ defaultMessage: `{item}, dropped. Final position in list: {position}.`
3151
+ },
3152
+ {
3153
+ item: `${name2}.${index$1}`,
3154
+ position: getItemPos(index$1)
3155
+ }
3156
+ )
3157
+ );
3158
+ };
3159
+ const handleRemoveComponent = (name22, currentIndex) => () => {
3160
+ removeFieldRow(name22, currentIndex);
3161
+ };
3162
+ const hasError = error !== void 0;
3163
+ const renderButtonLabel = () => {
3164
+ if (addComponentIsOpen) {
3165
+ return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
3233
3166
  }
3234
- );
3235
- };
3236
- const StyledAddIcon = styledComponents.styled(Icons.PlusCircle)`
3237
- height: ${({ theme }) => theme.spaces[6]};
3238
- width: ${({ theme }) => theme.spaces[6]};
3239
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
3240
-
3241
- > circle {
3242
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
3243
- }
3244
- > path {
3245
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
3246
- }
3247
- `;
3248
- const StyledButton = styledComponents.styled(designSystem.Button)`
3249
- padding-left: ${({ theme }) => theme.spaces[3]};
3250
- border-radius: 26px;
3251
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
3252
- height: 5rem;
3253
- `;
3254
- const ComponentCategory = ({
3255
- category,
3256
- components = [],
3257
- variant = "primary",
3258
- onAddComponent
3259
- }) => {
3260
- const { formatMessage } = reactIntl.useIntl();
3261
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: category, children: [
3262
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { variant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
3263
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsxRuntime.jsx(
3264
- ComponentBox,
3167
+ if (hasError && dynamicDisplayedComponentsLength > max) {
3168
+ return formatMessage(
3169
+ {
3170
+ id: index.getTranslation(`components.DynamicZone.extra-components`),
3171
+ defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
3172
+ },
3173
+ {
3174
+ number: dynamicDisplayedComponentsLength - max
3175
+ }
3176
+ );
3177
+ }
3178
+ if (hasError && dynamicDisplayedComponentsLength < min) {
3179
+ return formatMessage(
3180
+ {
3181
+ id: index.getTranslation(`components.DynamicZone.missing-components`),
3182
+ defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
3183
+ },
3184
+ { number: min - dynamicDisplayedComponentsLength }
3185
+ );
3186
+ }
3187
+ return formatMessage(
3265
3188
  {
3266
- tag: "button",
3267
- type: "button",
3268
- background: "neutral100",
3269
- justifyContent: "center",
3270
- onClick: onAddComponent(uid),
3271
- hasRadius: true,
3272
- height: "8.4rem",
3273
- shrink: 0,
3274
- borderColor: "neutral200",
3275
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
3276
- /* @__PURE__ */ jsxRuntime.jsx(ComponentIcon.ComponentIcon, { color: "currentColor", background: "primary200", icon }),
3277
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: displayName })
3278
- ] })
3189
+ id: index.getTranslation("components.DynamicZone.add-component"),
3190
+ defaultMessage: "Add a component to {componentName}"
3279
3191
  },
3280
- uid
3281
- )) }) })
3282
- ] });
3283
- };
3284
- const Grid = styledComponents.styled(designSystem.Box)`
3285
- display: grid;
3286
- grid-template-columns: repeat(auto-fit, 14rem);
3287
- grid-gap: ${({ theme }) => theme.spaces[1]};
3288
- `;
3289
- const ComponentBox = styledComponents.styled(designSystem.Flex)`
3290
- color: ${({ theme }) => theme.colors.neutral600};
3291
- cursor: pointer;
3292
-
3293
- @media (prefers-reduced-motion: no-preference) {
3294
- transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3295
- }
3296
-
3297
- &:focus,
3298
- &:hover {
3299
- border: 1px solid ${({ theme }) => theme.colors.primary200};
3300
- background: ${({ theme }) => theme.colors.primary100};
3301
- color: ${({ theme }) => theme.colors.primary600};
3302
- }
3303
- `;
3304
- const ComponentPicker = ({
3305
- dynamicComponentsByCategory = {},
3306
- isOpen,
3307
- onClickAddComponent
3308
- }) => {
3309
- const { formatMessage } = reactIntl.useIntl();
3310
- const handleAddComponentToDz = (componentUid) => () => {
3311
- onClickAddComponent(componentUid);
3192
+ { componentName: label || name2 }
3193
+ );
3312
3194
  };
3313
- if (!isOpen) {
3314
- return null;
3315
- }
3316
- return /* @__PURE__ */ jsxRuntime.jsxs(
3317
- designSystem.Box,
3318
- {
3319
- paddingTop: 6,
3320
- paddingBottom: 6,
3321
- paddingLeft: 5,
3322
- paddingRight: 5,
3323
- background: "neutral0",
3324
- shadow: "tableShadow",
3325
- borderColor: "neutral150",
3326
- hasRadius: true,
3327
- children: [
3328
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
3329
- id: index.getTranslation("components.DynamicZone.ComponentPicker-label"),
3330
- defaultMessage: "Pick one component"
3331
- }) }) }),
3332
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { defaultValue: Object.keys(dynamicComponentsByCategory)[0], children: Object.entries(dynamicComponentsByCategory).map(([category, components], index2) => /* @__PURE__ */ jsxRuntime.jsx(
3333
- ComponentCategory,
3334
- {
3335
- category,
3336
- components,
3337
- onAddComponent: handleAddComponentToDz,
3338
- variant: index2 % 2 === 1 ? "primary" : "secondary"
3339
- },
3340
- category
3341
- )) }) })
3342
- ]
3343
- }
3344
- );
3195
+ const level = Relations.useComponent("DynamicZone", (state) => state.level);
3196
+ const ariaDescriptionId = React__namespace.useId();
3197
+ return /* @__PURE__ */ jsxRuntime.jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
3198
+ dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
3199
+ /* @__PURE__ */ jsxRuntime.jsx(
3200
+ DynamicZoneLabel,
3201
+ {
3202
+ hint,
3203
+ label,
3204
+ labelAction,
3205
+ name: name2,
3206
+ numberOfComponents: dynamicDisplayedComponentsLength,
3207
+ required
3208
+ }
3209
+ ),
3210
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
3211
+ id: index.getTranslation("dnd.instructions"),
3212
+ defaultMessage: `Press spacebar to grab and re-order`
3213
+ }) }),
3214
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
3215
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index2) => /* @__PURE__ */ jsxRuntime.jsx(
3216
+ Relations.ComponentProvider,
3217
+ {
3218
+ level: level + 1,
3219
+ uid: field.__component,
3220
+ id: field.id,
3221
+ type: "dynamiczone",
3222
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3223
+ DynamicComponent,
3224
+ {
3225
+ disabled,
3226
+ name: name2,
3227
+ index: index2,
3228
+ componentUid: field.__component,
3229
+ onMoveComponent: handleMoveComponent,
3230
+ onRemoveComponentClick: handleRemoveComponent(name2, index2),
3231
+ onCancel: handleCancel,
3232
+ onDropItem: handleDropItem,
3233
+ onGrabItem: handleGrabItem,
3234
+ onAddComponent: handleAddComponent,
3235
+ dynamicComponentsByCategory,
3236
+ children
3237
+ }
3238
+ )
3239
+ },
3240
+ field.__temp_key__
3241
+ )) })
3242
+ ] }),
3243
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
3244
+ AddComponentButton,
3245
+ {
3246
+ hasError,
3247
+ isDisabled: disabled,
3248
+ isOpen: addComponentIsOpen,
3249
+ onClick: handleClickOpenPicker,
3250
+ children: renderButtonLabel()
3251
+ }
3252
+ ) }),
3253
+ /* @__PURE__ */ jsxRuntime.jsx(
3254
+ ComponentPicker,
3255
+ {
3256
+ dynamicComponentsByCategory,
3257
+ isOpen: addComponentIsOpen,
3258
+ onClickAddComponent: handleAddComponent
3259
+ }
3260
+ )
3261
+ ] }) });
3345
3262
  };
3346
3263
  const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3347
3264
  const { formatMessage } = reactIntl.useIntl();
@@ -3415,7 +3332,7 @@ const UIDInput = React__namespace.forwardRef(
3415
3332
  const [showRegenerate, setShowRegenerate] = React__namespace.useState(false);
3416
3333
  const isCloning = reactRouterDom.useMatch(index.CLONE_PATH) !== null;
3417
3334
  const field = strapiAdmin.useField(name2);
3418
- const debouncedValue = useDebounce.useDebounce(field.value, 300);
3335
+ const debouncedValue = relations.useDebounce(field.value, 300);
3419
3336
  const hasChanged = debouncedValue !== field.initialValue;
3420
3337
  const { toggleNotification } = strapiAdmin.useNotification();
3421
3338
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
@@ -4966,7 +4883,7 @@ const Wysiwyg = React__namespace.forwardRef(
4966
4883
  const handleSelectAssets = (files) => {
4967
4884
  const formattedFiles = files.map((f) => ({
4968
4885
  alt: f.alternativeText || f.name,
4969
- url: useDebounce.prefixFileUrlWithBackendUrl(f.url),
4886
+ url: usePrev.prefixFileUrlWithBackendUrl(f.url),
4970
4887
  mime: f.mime
4971
4888
  }));
4972
4889
  insertFile(editorRef, formattedFiles);
@@ -5083,568 +5000,619 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
5083
5000
  return /* @__PURE__ */ jsxRuntime.jsx(
5084
5001
  MemoizedComponentInput,
5085
5002
  {
5086
- ...props,
5087
- hint,
5088
- layout: components[props.attribute.component].layout,
5089
- disabled: fieldIsDisabled,
5090
- children: (inputProps) => /* @__PURE__ */ jsxRuntime.jsx(InputRenderer, { ...inputProps })
5003
+ ...props,
5004
+ hint,
5005
+ layout: components[props.attribute.component].layout,
5006
+ disabled: fieldIsDisabled,
5007
+ children: (inputProps) => /* @__PURE__ */ jsxRuntime.jsx(InputRenderer, { ...inputProps })
5008
+ }
5009
+ );
5010
+ case "dynamiczone":
5011
+ return /* @__PURE__ */ jsxRuntime.jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
5012
+ case "relation":
5013
+ return /* @__PURE__ */ jsxRuntime.jsx(Relations.MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
5014
+ case "richtext":
5015
+ return /* @__PURE__ */ jsxRuntime.jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5016
+ case "uid":
5017
+ return /* @__PURE__ */ jsxRuntime.jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5018
+ case "enumeration":
5019
+ return /* @__PURE__ */ jsxRuntime.jsx(
5020
+ strapiAdmin.InputRenderer,
5021
+ {
5022
+ ...props,
5023
+ hint,
5024
+ options: props.attribute.enum.map((value) => ({ value })),
5025
+ type: props.customField ? "custom-field" : props.type,
5026
+ disabled: fieldIsDisabled
5027
+ }
5028
+ );
5029
+ default:
5030
+ const { unique: _unique, mainField: _mainField, ...restProps } = props;
5031
+ return /* @__PURE__ */ jsxRuntime.jsx(
5032
+ strapiAdmin.InputRenderer,
5033
+ {
5034
+ ...restProps,
5035
+ hint,
5036
+ type: props.customField ? "custom-field" : props.type,
5037
+ disabled: fieldIsDisabled
5038
+ }
5039
+ );
5040
+ }
5041
+ };
5042
+ const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5043
+ const useFieldHint = (hint = void 0, attribute) => {
5044
+ const { formatMessage } = reactIntl.useIntl();
5045
+ const { maximum, minimum } = getMinMax(attribute);
5046
+ if (!maximum && !minimum) {
5047
+ return hint;
5048
+ }
5049
+ const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5050
+ attribute.type
5051
+ ) ? formatMessage(
5052
+ {
5053
+ id: "content-manager.form.Input.hint.character.unit",
5054
+ defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5055
+ },
5056
+ {
5057
+ maxValue: Math.max(minimum || 0, maximum || 0)
5058
+ }
5059
+ ) : null;
5060
+ const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5061
+ return formatMessage(
5062
+ {
5063
+ id: "content-manager.form.Input.hint.text",
5064
+ defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5065
+ },
5066
+ {
5067
+ min: minimum,
5068
+ max: maximum,
5069
+ description: hint,
5070
+ unit: units,
5071
+ divider: hasMinAndMax ? formatMessage({
5072
+ id: "content-manager.form.Input.hint.minMaxDivider",
5073
+ defaultMessage: " / "
5074
+ }) : null,
5075
+ br: /* @__PURE__ */ jsxRuntime.jsx("br", {})
5076
+ }
5077
+ );
5078
+ };
5079
+ const getMinMax = (attribute) => {
5080
+ if ("min" in attribute || "max" in attribute) {
5081
+ return {
5082
+ maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5083
+ minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5084
+ };
5085
+ } else if ("maxLength" in attribute || "minLength" in attribute) {
5086
+ return { maximum: attribute.maxLength, minimum: attribute.minLength };
5087
+ } else {
5088
+ return { maximum: void 0, minimum: void 0 };
5089
+ }
5090
+ };
5091
+ const MemoizedInputRenderer = React.memo(InputRenderer);
5092
+ const RESPONSIVE_CONTAINER_BREAKPOINTS = {
5093
+ sm: "27.5rem"
5094
+ // 440px
5095
+ };
5096
+ const ResponsiveGridRoot = styledComponents.styled(designSystem.Grid.Root)`
5097
+ container-type: inline-size;
5098
+ `;
5099
+ const ResponsiveGridItem = styledComponents.styled(designSystem.Grid.Item)`
5100
+ grid-column: span 12;
5101
+
5102
+ @container (min-width: ${RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
5103
+ ${({ col }) => col && `grid-column: span ${col};`}
5104
+ }
5105
+ `;
5106
+ const FormLayout = ({ layout }) => {
5107
+ const { formatMessage } = reactIntl.useIntl();
5108
+ const { model } = index.useDoc();
5109
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((panel, index2) => {
5110
+ if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) {
5111
+ const [row] = panel;
5112
+ const [field] = row;
5113
+ const fieldWithTranslatedLabel = {
5114
+ ...field,
5115
+ label: formatMessage({
5116
+ id: `content-manager.content-types.${model}.${field.name}`,
5117
+ defaultMessage: field.label
5118
+ })
5119
+ };
5120
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsxRuntime.jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel }) }) }, field.name);
5121
+ }
5122
+ return /* @__PURE__ */ jsxRuntime.jsx(
5123
+ designSystem.Box,
5124
+ {
5125
+ hasRadius: true,
5126
+ background: "neutral0",
5127
+ shadow: "tableShadow",
5128
+ paddingLeft: 6,
5129
+ paddingRight: 6,
5130
+ paddingTop: 6,
5131
+ paddingBottom: 6,
5132
+ borderColor: "neutral150",
5133
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: panel.map((row, gridRowIndex) => /* @__PURE__ */ jsxRuntime.jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5134
+ const fieldWithTranslatedLabel = {
5135
+ ...field,
5136
+ label: formatMessage({
5137
+ id: `content-manager.content-types.${model}.${field.name}`,
5138
+ defaultMessage: field.label
5139
+ })
5140
+ };
5141
+ return /* @__PURE__ */ jsxRuntime.jsx(
5142
+ ResponsiveGridItem,
5143
+ {
5144
+ col: size,
5145
+ s: 12,
5146
+ xs: 12,
5147
+ direction: "column",
5148
+ alignItems: "stretch",
5149
+ children: /* @__PURE__ */ jsxRuntime.jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel })
5150
+ },
5151
+ field.name
5152
+ );
5153
+ }) }, gridRowIndex)) })
5154
+ },
5155
+ index2
5156
+ );
5157
+ }) });
5158
+ };
5159
+ const NonRepeatableComponent = ({
5160
+ attribute,
5161
+ name: name2,
5162
+ children,
5163
+ layout
5164
+ }) => {
5165
+ const { formatMessage } = reactIntl.useIntl();
5166
+ const { value } = strapiAdmin.useField(name2);
5167
+ const level = Relations.useComponent("NonRepeatableComponent", (state) => state.level);
5168
+ const isNested = level > 0;
5169
+ return /* @__PURE__ */ jsxRuntime.jsx(Relations.ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsxRuntime.jsx(
5170
+ designSystem.Box,
5171
+ {
5172
+ background: "neutral100",
5173
+ paddingLeft: 6,
5174
+ paddingRight: 6,
5175
+ paddingTop: 6,
5176
+ paddingBottom: 6,
5177
+ hasRadius: isNested,
5178
+ borderColor: isNested ? "neutral200" : void 0,
5179
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index2) => {
5180
+ return /* @__PURE__ */ jsxRuntime.jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5181
+ const completeFieldName = `${name2}.${field.name}`;
5182
+ const translatedLabel = formatMessage({
5183
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5184
+ defaultMessage: field.label
5185
+ });
5186
+ return /* @__PURE__ */ jsxRuntime.jsx(
5187
+ ResponsiveGridItem,
5188
+ {
5189
+ col: size,
5190
+ s: 12,
5191
+ xs: 12,
5192
+ direction: "column",
5193
+ alignItems: "stretch",
5194
+ children: children({ ...field, label: translatedLabel, name: completeFieldName })
5195
+ },
5196
+ completeFieldName
5197
+ );
5198
+ }) }, index2);
5199
+ }) })
5200
+ }
5201
+ ) });
5202
+ };
5203
+ const RepeatableComponent = ({
5204
+ attribute,
5205
+ disabled,
5206
+ name: name2,
5207
+ mainField,
5208
+ children,
5209
+ layout
5210
+ }) => {
5211
+ const { toggleNotification } = strapiAdmin.useNotification();
5212
+ const { formatMessage } = reactIntl.useIntl();
5213
+ const { search: searchString } = reactRouterDom.useLocation();
5214
+ const search = React__namespace.useMemo(() => new URLSearchParams(searchString), [searchString]);
5215
+ const { components } = index.useDoc();
5216
+ const {
5217
+ value = [],
5218
+ error,
5219
+ rawError
5220
+ } = strapiAdmin.useField(name2);
5221
+ const addFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.addFieldRow);
5222
+ const moveFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.moveFieldRow);
5223
+ const removeFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.removeFieldRow);
5224
+ const { max = Infinity } = attribute;
5225
+ const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
5226
+ const [liveText, setLiveText] = React__namespace.useState("");
5227
+ React__namespace.useEffect(() => {
5228
+ const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
5229
+ const hasNestedValue = value && Array.isArray(value) && value.length > 0;
5230
+ if (hasNestedErrors && hasNestedValue) {
5231
+ const errorOpenItems = rawError.map((_, idx) => {
5232
+ return value[idx] ? value[idx].__temp_key__ : null;
5233
+ }).filter((value2) => !!value2);
5234
+ if (errorOpenItems && errorOpenItems.length > 0) {
5235
+ setCollapseToOpen((collapseToOpen2) => {
5236
+ if (!errorOpenItems.includes(collapseToOpen2)) {
5237
+ return errorOpenItems[0];
5238
+ }
5239
+ return collapseToOpen2;
5240
+ });
5241
+ }
5242
+ }
5243
+ }, [rawError, value]);
5244
+ const componentTmpKeyWithFocussedField = React__namespace.useMemo(() => {
5245
+ if (search.has("field")) {
5246
+ const fieldParam = search.get("field");
5247
+ if (!fieldParam) {
5248
+ return void 0;
5249
+ }
5250
+ const [, path] = fieldParam.split(`${name2}.`);
5251
+ if (objects.getIn(value, path, void 0) !== void 0) {
5252
+ const [subpath] = path.split(".");
5253
+ return objects.getIn(value, subpath, void 0)?.__temp_key__;
5254
+ }
5255
+ }
5256
+ return void 0;
5257
+ }, [search, name2, value]);
5258
+ const prevValue = usePrev.usePrev(value);
5259
+ React__namespace.useEffect(() => {
5260
+ if (prevValue && prevValue.length < value.length) {
5261
+ setCollapseToOpen(value[value.length - 1].__temp_key__);
5262
+ }
5263
+ }, [value, prevValue]);
5264
+ React__namespace.useEffect(() => {
5265
+ if (typeof componentTmpKeyWithFocussedField === "string") {
5266
+ setCollapseToOpen(componentTmpKeyWithFocussedField);
5267
+ }
5268
+ }, [componentTmpKeyWithFocussedField]);
5269
+ const toggleCollapses = () => {
5270
+ setCollapseToOpen("");
5271
+ };
5272
+ const handleClick = () => {
5273
+ if (value.length < max) {
5274
+ const schema = components[attribute.component];
5275
+ const form = index.createDefaultForm(schema, components);
5276
+ const data = index.transformDocument(schema, components)(form);
5277
+ addFieldRow(name2, data);
5278
+ } else if (value.length >= max) {
5279
+ toggleNotification({
5280
+ type: "info",
5281
+ message: formatMessage({
5282
+ id: index.getTranslation("components.notification.info.maximum-requirement")
5283
+ })
5284
+ });
5285
+ }
5286
+ };
5287
+ const handleMoveComponentField = (newIndex, currentIndex) => {
5288
+ setLiveText(
5289
+ formatMessage(
5290
+ {
5291
+ id: index.getTranslation("dnd.reorder"),
5292
+ defaultMessage: "{item}, moved. New position in list: {position}."
5293
+ },
5294
+ {
5295
+ item: `${name2}.${currentIndex}`,
5296
+ position: getItemPos(newIndex)
5091
5297
  }
5092
- );
5093
- case "dynamiczone":
5094
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
5095
- case "relation":
5096
- return /* @__PURE__ */ jsxRuntime.jsx(Relations.MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
5097
- case "richtext":
5098
- return /* @__PURE__ */ jsxRuntime.jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5099
- case "uid":
5100
- return /* @__PURE__ */ jsxRuntime.jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5101
- case "enumeration":
5102
- return /* @__PURE__ */ jsxRuntime.jsx(
5103
- strapiAdmin.InputRenderer,
5298
+ )
5299
+ );
5300
+ moveFieldRow(name2, currentIndex, newIndex);
5301
+ };
5302
+ const handleValueChange = (key) => {
5303
+ setCollapseToOpen(key);
5304
+ };
5305
+ const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
5306
+ const handleCancel = (index$1) => {
5307
+ setLiveText(
5308
+ formatMessage(
5104
5309
  {
5105
- ...props,
5106
- hint,
5107
- options: props.attribute.enum.map((value) => ({ value })),
5108
- type: props.customField ? "custom-field" : props.type,
5109
- disabled: fieldIsDisabled
5310
+ id: index.getTranslation("dnd.cancel-item"),
5311
+ defaultMessage: "{item}, dropped. Re-order cancelled."
5312
+ },
5313
+ {
5314
+ item: `${name2}.${index$1}`
5110
5315
  }
5111
- );
5112
- default:
5113
- const { unique: _unique, mainField: _mainField, ...restProps } = props;
5114
- return /* @__PURE__ */ jsxRuntime.jsx(
5115
- strapiAdmin.InputRenderer,
5316
+ )
5317
+ );
5318
+ };
5319
+ const handleGrabItem = (index$1) => {
5320
+ setLiveText(
5321
+ formatMessage(
5116
5322
  {
5117
- ...restProps,
5118
- hint,
5119
- type: props.customField ? "custom-field" : props.type,
5120
- disabled: fieldIsDisabled
5323
+ id: index.getTranslation("dnd.grab-item"),
5324
+ defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5325
+ },
5326
+ {
5327
+ item: `${name2}.${index$1}`,
5328
+ position: getItemPos(index$1)
5121
5329
  }
5122
- );
5330
+ )
5331
+ );
5332
+ };
5333
+ const handleDropItem = (index$1) => {
5334
+ setLiveText(
5335
+ formatMessage(
5336
+ {
5337
+ id: index.getTranslation("dnd.drop-item"),
5338
+ defaultMessage: `{item}, dropped. Final position in list: {position}.`
5339
+ },
5340
+ {
5341
+ item: `${name2}.${index$1}`,
5342
+ position: getItemPos(index$1)
5343
+ }
5344
+ )
5345
+ );
5346
+ };
5347
+ const ariaDescriptionId = React__namespace.useId();
5348
+ const level = Relations.useComponent("RepeatableComponent", (state) => state.level);
5349
+ if (value.length === 0) {
5350
+ return /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleClick });
5123
5351
  }
5352
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { hasRadius: true, children: [
5353
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5354
+ id: index.getTranslation("dnd.instructions"),
5355
+ defaultMessage: `Press spacebar to grab and re-order`
5356
+ }) }),
5357
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5358
+ /* @__PURE__ */ jsxRuntime.jsxs(
5359
+ AccordionRoot,
5360
+ {
5361
+ $error: error,
5362
+ value: collapseToOpen,
5363
+ onValueChange: handleValueChange,
5364
+ "aria-describedby": ariaDescriptionId,
5365
+ children: [
5366
+ value.map(({ __temp_key__: key, id }, index2) => {
5367
+ const nameWithIndex = `${name2}.${index2}`;
5368
+ return /* @__PURE__ */ jsxRuntime.jsx(
5369
+ Relations.ComponentProvider,
5370
+ {
5371
+ id,
5372
+ uid: attribute.component,
5373
+ level: level + 1,
5374
+ type: "repeatable",
5375
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5376
+ Component,
5377
+ {
5378
+ disabled,
5379
+ name: nameWithIndex,
5380
+ attribute,
5381
+ index: index2,
5382
+ mainField,
5383
+ onMoveItem: handleMoveComponentField,
5384
+ onDeleteComponent: () => {
5385
+ removeFieldRow(name2, index2);
5386
+ toggleCollapses();
5387
+ },
5388
+ toggleCollapses,
5389
+ onCancel: handleCancel,
5390
+ onDropItem: handleDropItem,
5391
+ onGrabItem: handleGrabItem,
5392
+ __temp_key__: key,
5393
+ children: layout.map((row, index22) => {
5394
+ return /* @__PURE__ */ jsxRuntime.jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5395
+ const completeFieldName = `${nameWithIndex}.${field.name}`;
5396
+ const translatedLabel = formatMessage({
5397
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5398
+ defaultMessage: field.label
5399
+ });
5400
+ return /* @__PURE__ */ jsxRuntime.jsx(
5401
+ ResponsiveGridItem,
5402
+ {
5403
+ col: size,
5404
+ s: 12,
5405
+ xs: 12,
5406
+ direction: "column",
5407
+ alignItems: "stretch",
5408
+ children: children({
5409
+ ...field,
5410
+ label: translatedLabel,
5411
+ name: completeFieldName
5412
+ })
5413
+ },
5414
+ completeFieldName
5415
+ );
5416
+ }) }, index22);
5417
+ })
5418
+ }
5419
+ )
5420
+ },
5421
+ key
5422
+ );
5423
+ }),
5424
+ /* @__PURE__ */ jsxRuntime.jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Plus, {}), children: formatMessage({
5425
+ id: index.getTranslation("containers.EditView.add.new-entry"),
5426
+ defaultMessage: "Add an entry"
5427
+ }) })
5428
+ ]
5429
+ }
5430
+ )
5431
+ ] });
5124
5432
  };
5125
- const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5126
- const useFieldHint = (hint = void 0, attribute) => {
5127
- const { formatMessage } = reactIntl.useIntl();
5128
- const { maximum, minimum } = getMinMax(attribute);
5129
- if (!maximum && !minimum) {
5130
- return hint;
5131
- }
5132
- const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5133
- attribute.type
5134
- ) ? formatMessage(
5135
- {
5136
- id: "content-manager.form.Input.hint.character.unit",
5137
- defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5138
- },
5139
- {
5140
- maxValue: Math.max(minimum || 0, maximum || 0)
5141
- }
5142
- ) : null;
5143
- const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5144
- return formatMessage(
5145
- {
5146
- id: "content-manager.form.Input.hint.text",
5147
- defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5148
- },
5149
- {
5150
- min: minimum,
5151
- max: maximum,
5152
- description: hint,
5153
- unit: units,
5154
- divider: hasMinAndMax ? formatMessage({
5155
- id: "content-manager.form.Input.hint.minMaxDivider",
5156
- defaultMessage: " / "
5157
- }) : null,
5158
- br: /* @__PURE__ */ jsxRuntime.jsx("br", {})
5433
+ const AccordionRoot = styledComponents.styled(designSystem.Accordion.Root)`
5434
+ border: 1px solid
5435
+ ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
5436
+ `;
5437
+ const TextButtonCustom = styledComponents.styled(designSystem.TextButton)`
5438
+ width: 100%;
5439
+ display: flex;
5440
+ justify-content: center;
5441
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
5442
+ padding-inline: ${(props) => props.theme.spaces[6]};
5443
+ padding-block: ${(props) => props.theme.spaces[3]};
5444
+
5445
+ &:not([disabled]) {
5446
+ cursor: pointer;
5447
+
5448
+ &:hover {
5449
+ background-color: ${(props) => props.theme.colors.primary100};
5159
5450
  }
5160
- );
5161
- };
5162
- const getMinMax = (attribute) => {
5163
- if ("min" in attribute || "max" in attribute) {
5164
- return {
5165
- maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5166
- minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5167
- };
5168
- } else if ("maxLength" in attribute || "minLength" in attribute) {
5169
- return { maximum: attribute.maxLength, minimum: attribute.minLength };
5170
- } else {
5171
- return { maximum: void 0, minimum: void 0 };
5172
5451
  }
5173
- };
5174
- const MemoizedInputRenderer = React.memo(InputRenderer);
5175
- const DynamicComponent = ({
5176
- componentUid,
5452
+
5453
+ span {
5454
+ font-weight: 600;
5455
+ font-size: 1.4rem;
5456
+ line-height: 2.4rem;
5457
+ }
5458
+
5459
+ @media (prefers-reduced-motion: no-preference) {
5460
+ transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
5461
+ }
5462
+ `;
5463
+ const Component = ({
5177
5464
  disabled,
5178
5465
  index: index$1,
5179
5466
  name: name2,
5180
- onRemoveComponentClick,
5181
- onMoveComponent,
5182
- onGrabItem,
5183
- onDropItem,
5184
- onCancel,
5185
- dynamicComponentsByCategory = {},
5186
- onAddComponent,
5187
- children
5467
+ mainField = {
5468
+ name: "id",
5469
+ type: "integer"
5470
+ },
5471
+ children,
5472
+ onDeleteComponent,
5473
+ toggleCollapses,
5474
+ __temp_key__,
5475
+ ...dragProps
5188
5476
  }) => {
5189
5477
  const { formatMessage } = reactIntl.useIntl();
5190
- const formValues = strapiAdmin.useForm("DynamicComponent", (state) => state.values);
5191
- const {
5192
- edit: { components }
5193
- } = index.useDocLayout();
5194
- const title = React__namespace.useMemo(() => {
5195
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
5196
- const mainFieldValue = objects.getIn(formValues, `${name2}.${index$1}.${mainField}`);
5197
- const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
5198
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
5199
- return mainValue;
5200
- }, [componentUid, components, formValues, name2, index$1]);
5201
- const { icon, displayName } = React__namespace.useMemo(() => {
5202
- const [category] = componentUid.split(".");
5203
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
5204
- (component) => component.uid === componentUid
5205
- ) ?? { icon: null, displayName: null };
5206
- return { icon: icon2, displayName: displayName2 };
5207
- }, [componentUid, dynamicComponentsByCategory]);
5478
+ const displayValue = strapiAdmin.useForm("RepeatableComponent", (state) => {
5479
+ return objects.getIn(state.values, [...name2.split("."), mainField.name]);
5480
+ });
5481
+ const accordionRef = React__namespace.useRef(null);
5482
+ const componentKey = name2.split(".").slice(0, -1).join(".");
5208
5483
  const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(!disabled, {
5209
- type: `${useDragAndDrop.ItemTypes.DYNAMIC_ZONE}_${name2}`,
5484
+ type: `${useDragAndDrop.ItemTypes.COMPONENT}_${componentKey}`,
5210
5485
  index: index$1,
5211
5486
  item: {
5212
5487
  index: index$1,
5213
- displayedValue: `${displayName} ${title}`,
5214
- icon
5488
+ displayedValue: displayValue
5215
5489
  },
5216
- onMoveItem: onMoveComponent,
5217
- onDropItem,
5218
- onGrabItem,
5219
- onCancel
5490
+ onStart() {
5491
+ toggleCollapses();
5492
+ },
5493
+ ...dragProps
5220
5494
  });
5221
5495
  React__namespace.useEffect(() => {
5222
5496
  dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
5223
5497
  }, [dragPreviewRef, index$1]);
5224
- const accordionValue = React__namespace.useId();
5225
- const { value = [], rawError } = strapiAdmin.useField(`${name2}.${index$1}`);
5226
- const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
5227
- React__namespace.useEffect(() => {
5228
- if (rawError && value) {
5229
- setCollapseToOpen(accordionValue);
5230
- }
5231
- }, [rawError, value, accordionValue]);
5232
- const composedBoxRefs = designSystem.useComposedRefs(boxRef, dropRef);
5233
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5234
- /* @__PURE__ */ jsxRuntime.jsx(
5235
- designSystem.IconButton,
5236
- {
5237
- variant: "ghost",
5238
- label: formatMessage(
5498
+ const composedAccordionRefs = designSystem.useComposedRefs(accordionRef, dragRef);
5499
+ const composedBoxRefs = designSystem.useComposedRefs(
5500
+ boxRef,
5501
+ dropRef
5502
+ );
5503
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isDragging ? /* @__PURE__ */ jsxRuntime.jsx(Preview, {}) : /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
5504
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
5505
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: displayValue }),
5506
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Actions, { children: [
5507
+ /* @__PURE__ */ jsxRuntime.jsx(
5508
+ designSystem.IconButton,
5239
5509
  {
5240
- id: index.getTranslation("components.DynamicZone.delete-label"),
5241
- defaultMessage: "Delete {name}"
5242
- },
5243
- { name: title }
5510
+ variant: "ghost",
5511
+ onClick: onDeleteComponent,
5512
+ label: formatMessage({
5513
+ id: index.getTranslation("containers.Edit.delete"),
5514
+ defaultMessage: "Delete"
5515
+ }),
5516
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
5517
+ }
5244
5518
  ),
5245
- onClick: onRemoveComponentClick,
5246
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
5247
- }
5248
- ),
5249
- /* @__PURE__ */ jsxRuntime.jsx(
5250
- designSystem.IconButton,
5251
- {
5252
- variant: "ghost",
5253
- onClick: (e) => e.stopPropagation(),
5254
- "data-handler-id": handlerId,
5255
- ref: dragRef,
5256
- label: formatMessage({
5257
- id: index.getTranslation("components.DragHandle-label"),
5258
- defaultMessage: "Drag"
5259
- }),
5260
- onKeyDown: handleKeyDown,
5261
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
5262
- }
5263
- ),
5264
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
5265
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
5266
- /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
5267
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage({
5268
- id: index.getTranslation("components.DynamicZone.more-actions"),
5269
- defaultMessage: "More actions"
5270
- }) })
5271
- ] }),
5272
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { children: [
5273
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
5274
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
5275
- id: index.getTranslation("components.DynamicZone.add-item-above"),
5276
- defaultMessage: "Add component above"
5277
- }) }),
5278
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
5279
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
5280
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1), children: displayName2 }, componentUid))
5281
- ] }, category)) })
5282
- ] }),
5283
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
5284
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
5285
- id: index.getTranslation("components.DynamicZone.add-item-below"),
5286
- defaultMessage: "Add component below"
5287
- }) }),
5288
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
5289
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
5290
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1 + 1), children: displayName2 }, componentUid))
5291
- ] }, category)) })
5292
- ] })
5293
- ] })
5294
- ] })
5295
- ] });
5296
- const accordionTitle = title ? `${displayName} ${title}` : displayName;
5297
- return /* @__PURE__ */ jsxRuntime.jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
5298
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Rectangle, { background: "neutral200" }) }),
5299
- /* @__PURE__ */ jsxRuntime.jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsxRuntime.jsx(Preview, {}) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { value: collapseToOpen, onValueChange: setCollapseToOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: accordionValue, children: [
5300
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
5301
5519
  /* @__PURE__ */ jsxRuntime.jsx(
5302
- designSystem.Accordion.Trigger,
5520
+ designSystem.IconButton,
5303
5521
  {
5304
- icon: icon && ComponentIcon.COMPONENT_ICONS[icon] ? ComponentIcon.COMPONENT_ICONS[icon] : ComponentIcon.COMPONENT_ICONS.dashboard,
5305
- children: accordionTitle
5522
+ ref: composedAccordionRefs,
5523
+ variant: "ghost",
5524
+ onClick: (e) => e.stopPropagation(),
5525
+ "data-handler-id": handlerId,
5526
+ label: formatMessage({
5527
+ id: index.getTranslation("components.DragHandle-label"),
5528
+ defaultMessage: "Drag"
5529
+ }),
5530
+ onKeyDown: handleKeyDown,
5531
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
5306
5532
  }
5307
- ),
5308
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Actions, { children: accordionActions })
5309
- ] }),
5310
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsxRuntime.jsx(
5311
- designSystem.Grid.Item,
5312
- {
5313
- col: 12,
5314
- s: 12,
5315
- xs: 12,
5316
- direction: "column",
5317
- alignItems: "stretch",
5318
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
5319
- const fieldName = `${name2}.${index$1}.${field.name}`;
5320
- const fieldWithTranslatedLabel = {
5321
- ...field,
5322
- label: formatMessage({
5323
- id: `content-manager.components.${componentUid}.${field.name}`,
5324
- defaultMessage: field.label
5325
- })
5326
- };
5327
- return /* @__PURE__ */ jsxRuntime.jsx(
5328
- designSystem.Grid.Item,
5329
- {
5330
- col: size,
5331
- s: 12,
5332
- xs: 12,
5333
- direction: "column",
5334
- alignItems: "stretch",
5335
- children: children ? children({ ...fieldWithTranslatedLabel, name: fieldName }) : /* @__PURE__ */ jsxRuntime.jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
5336
- },
5337
- fieldName
5338
- );
5339
- }) })
5340
- },
5341
- rowInd
5342
- )) }) }) }) })
5343
- ] }) }) })
5344
- ] });
5345
- };
5346
- const StyledBox = styledComponents.styled(designSystem.Box)`
5347
- > div:first-child {
5348
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5349
- }
5350
- `;
5351
- const AccordionContentRadius = styledComponents.styled(designSystem.Box)`
5352
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5353
- `;
5354
- const Rectangle = styledComponents.styled(designSystem.Box)`
5355
- width: ${({ theme }) => theme.spaces[2]};
5356
- height: ${({ theme }) => theme.spaces[4]};
5357
- `;
5358
- const Preview = styledComponents.styled.span`
5359
- display: block;
5360
- background-color: ${({ theme }) => theme.colors.primary100};
5361
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5362
- outline-offset: -1px;
5363
- padding: ${({ theme }) => theme.spaces[6]};
5364
- `;
5365
- const ComponentContainer = styledComponents.styled(designSystem.Box)`
5366
- list-style: none;
5367
- padding: 0;
5368
- margin: 0;
5369
- `;
5370
- const DynamicZoneLabel = ({
5371
- hint,
5372
- label,
5373
- labelAction,
5374
- name: name2,
5375
- numberOfComponents = 0,
5376
- required
5377
- }) => {
5378
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
5379
- designSystem.Box,
5380
- {
5381
- paddingTop: 3,
5382
- paddingBottom: 3,
5383
- paddingRight: 4,
5384
- paddingLeft: 4,
5385
- borderRadius: "26px",
5386
- background: "neutral0",
5387
- shadow: "filterShadow",
5388
- color: "neutral500",
5389
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", justifyContent: "center", children: [
5390
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { maxWidth: "35.6rem", children: [
5391
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5392
- label || name2,
5393
- " "
5394
- ] }),
5395
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5396
- "(",
5397
- numberOfComponents,
5398
- ")"
5399
- ] }),
5400
- required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: "*" }),
5401
- labelAction && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 1, children: labelAction })
5402
- ] }),
5403
- hint && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
5533
+ )
5404
5534
  ] })
5405
- }
5406
- ) });
5407
- };
5408
- const [DynamicZoneProvider, useDynamicZone] = strapiAdmin.createContext(
5409
- "DynamicZone",
5410
- {
5411
- isInDynamicZone: false
5412
- }
5413
- );
5414
- const DynamicZone = ({
5415
- attribute,
5416
- disabled: disabledProp,
5417
- hint,
5535
+ ] }),
5536
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(
5537
+ designSystem.Flex,
5538
+ {
5539
+ direction: "column",
5540
+ alignItems: "stretch",
5541
+ background: "neutral100",
5542
+ padding: 6,
5543
+ gap: 6,
5544
+ children
5545
+ }
5546
+ ) })
5547
+ ] }) });
5548
+ };
5549
+ const Preview = () => {
5550
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
5551
+ };
5552
+ const StyledSpan = styledComponents.styled(designSystem.Box)`
5553
+ display: block;
5554
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5555
+ outline-offset: -1px;
5556
+ `;
5557
+ const ComponentInput = ({
5418
5558
  label,
5419
- labelAction,
5559
+ required,
5420
5560
  name: name2,
5421
- required = false,
5422
- children
5561
+ attribute,
5562
+ disabled,
5563
+ labelAction,
5564
+ ...props
5423
5565
  }) => {
5424
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5425
- const [addComponentIsOpen, setAddComponentIsOpen] = React__namespace.useState(false);
5426
- const [liveText, setLiveText] = React__namespace.useState("");
5427
- const { components, isLoading } = index.useDoc();
5428
- const disabled = disabledProp || isLoading;
5429
- const { addFieldRow, removeFieldRow, moveFieldRow } = strapiAdmin.useForm(
5430
- "DynamicZone",
5431
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5432
- addFieldRow: addFieldRow2,
5433
- removeFieldRow: removeFieldRow2,
5434
- moveFieldRow: moveFieldRow2
5435
- })
5436
- );
5437
- const { value = [], error } = strapiAdmin.useField(name2);
5438
- const dynamicComponentsByCategory = React__namespace.useMemo(() => {
5439
- return attribute.components.reduce((acc, componentUid) => {
5440
- const { category, info } = components[componentUid] ?? { info: {} };
5441
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5442
- if (!acc[category]) {
5443
- acc[category] = [];
5444
- }
5445
- acc[category] = [...acc[category], component];
5446
- return acc;
5447
- }, {});
5448
- }, [attribute.components, components]);
5449
5566
  const { formatMessage } = reactIntl.useIntl();
5450
- const { toggleNotification } = strapiAdmin.useNotification();
5451
- const dynamicDisplayedComponentsLength = value.length;
5452
- const handleAddComponent = (uid, position) => {
5453
- setAddComponentIsOpen(false);
5454
- const schema = components[uid];
5455
- const form = createDefaultForm(schema, components);
5456
- const transformations = pipe__default.default(transformDocument(schema, components), (data2) => ({
5457
- ...data2,
5458
- __component: uid
5459
- }));
5460
- const data = transformations(form);
5461
- addFieldRow(name2, data, position);
5462
- };
5463
- const handleClickOpenPicker = () => {
5464
- if (dynamicDisplayedComponentsLength < max) {
5465
- setAddComponentIsOpen((prev) => !prev);
5466
- } else {
5467
- toggleNotification({
5468
- type: "info",
5469
- message: formatMessage({
5470
- id: index.getTranslation("components.notification.info.maximum-requirement")
5471
- })
5472
- });
5473
- }
5474
- };
5475
- const handleMoveComponent = (newIndex, currentIndex) => {
5476
- setLiveText(
5477
- formatMessage(
5478
- {
5479
- id: index.getTranslation("dnd.reorder"),
5480
- defaultMessage: "{item}, moved. New position in list: {position}."
5481
- },
5482
- {
5483
- item: `${name2}.${currentIndex}`,
5484
- position: getItemPos(newIndex)
5485
- }
5486
- )
5487
- );
5488
- moveFieldRow(name2, currentIndex, newIndex);
5489
- };
5490
- const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
5491
- const handleCancel = (index$1) => {
5492
- setLiveText(
5493
- formatMessage(
5494
- {
5495
- id: index.getTranslation("dnd.cancel-item"),
5496
- defaultMessage: "{item}, dropped. Re-order cancelled."
5497
- },
5498
- {
5499
- item: `${name2}.${index$1}`
5500
- }
5501
- )
5502
- );
5503
- };
5504
- const handleGrabItem = (index$1) => {
5505
- setLiveText(
5506
- formatMessage(
5507
- {
5508
- id: index.getTranslation("dnd.grab-item"),
5509
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5510
- },
5511
- {
5512
- item: `${name2}.${index$1}`,
5513
- position: getItemPos(index$1)
5514
- }
5515
- )
5516
- );
5567
+ const field = strapiAdmin.useField(name2);
5568
+ const showResetComponent = !attribute.repeatable && field.value && !disabled;
5569
+ const { components } = index.useDoc();
5570
+ const handleInitialisationClick = () => {
5571
+ const schema = components[attribute.component];
5572
+ const form = index.createDefaultForm(schema, components);
5573
+ const data = index.transformDocument(schema, components)(form);
5574
+ field.onChange(name2, data);
5517
5575
  };
5518
- const handleDropItem = (index$1) => {
5519
- setLiveText(
5520
- formatMessage(
5521
- {
5522
- id: index.getTranslation("dnd.drop-item"),
5523
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
5524
- },
5576
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: field.error, required, children: [
5577
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
5578
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { action: labelAction, children: [
5579
+ label,
5580
+ attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5581
+ " (",
5582
+ Array.isArray(field.value) ? field.value.length : 0,
5583
+ ")"
5584
+ ] })
5585
+ ] }),
5586
+ showResetComponent && /* @__PURE__ */ jsxRuntime.jsx(
5587
+ designSystem.IconButton,
5525
5588
  {
5526
- item: `${name2}.${index$1}`,
5527
- position: getItemPos(index$1)
5589
+ label: formatMessage({
5590
+ id: index.getTranslation("components.reset-entry"),
5591
+ defaultMessage: "Reset Entry"
5592
+ }),
5593
+ variant: "ghost",
5594
+ onClick: () => {
5595
+ field.onChange(name2, null);
5596
+ },
5597
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
5528
5598
  }
5529
5599
  )
5530
- );
5531
- };
5532
- const handleRemoveComponent = (name22, currentIndex) => () => {
5533
- removeFieldRow(name22, currentIndex);
5534
- };
5535
- const hasError = error !== void 0;
5536
- const renderButtonLabel = () => {
5537
- if (addComponentIsOpen) {
5538
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5539
- }
5540
- if (hasError && dynamicDisplayedComponentsLength > max) {
5541
- return formatMessage(
5542
- {
5543
- id: index.getTranslation(`components.DynamicZone.extra-components`),
5544
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5545
- },
5546
- {
5547
- number: dynamicDisplayedComponentsLength - max
5548
- }
5549
- );
5550
- }
5551
- if (hasError && dynamicDisplayedComponentsLength < min) {
5552
- return formatMessage(
5553
- {
5554
- id: index.getTranslation(`components.DynamicZone.missing-components`),
5555
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5556
- },
5557
- { number: min - dynamicDisplayedComponentsLength }
5558
- );
5559
- }
5560
- return formatMessage(
5561
- {
5562
- id: index.getTranslation("components.DynamicZone.add-component"),
5563
- defaultMessage: "Add a component to {componentName}"
5564
- },
5565
- { componentName: label || name2 }
5566
- );
5567
- };
5568
- const level = Relations.useComponent("DynamicZone", (state) => state.level);
5569
- const ariaDescriptionId = React__namespace.useId();
5570
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5571
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
5572
- /* @__PURE__ */ jsxRuntime.jsx(
5573
- DynamicZoneLabel,
5574
- {
5575
- hint,
5576
- label,
5577
- labelAction,
5578
- name: name2,
5579
- numberOfComponents: dynamicDisplayedComponentsLength,
5580
- required
5581
- }
5582
- ),
5583
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5584
- id: index.getTranslation("dnd.instructions"),
5585
- defaultMessage: `Press spacebar to grab and re-order`
5586
- }) }),
5587
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5588
- /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index2) => /* @__PURE__ */ jsxRuntime.jsx(
5589
- Relations.ComponentProvider,
5590
- {
5591
- level: level + 1,
5592
- uid: field.__component,
5593
- id: field.id,
5594
- type: "dynamiczone",
5595
- children: /* @__PURE__ */ jsxRuntime.jsx(
5596
- DynamicComponent,
5597
- {
5598
- disabled,
5599
- name: name2,
5600
- index: index2,
5601
- componentUid: field.__component,
5602
- onMoveComponent: handleMoveComponent,
5603
- onRemoveComponentClick: handleRemoveComponent(name2, index2),
5604
- onCancel: handleCancel,
5605
- onDropItem: handleDropItem,
5606
- onGrabItem: handleGrabItem,
5607
- onAddComponent: handleAddComponent,
5608
- dynamicComponentsByCategory,
5609
- children
5610
- }
5611
- )
5612
- },
5613
- field.__temp_key__
5614
- )) })
5615
5600
  ] }),
5616
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
5617
- AddComponentButton,
5618
- {
5619
- hasError,
5620
- isDisabled: disabled,
5621
- isOpen: addComponentIsOpen,
5622
- onClick: handleClickOpenPicker,
5623
- children: renderButtonLabel()
5624
- }
5625
- ) }),
5626
- /* @__PURE__ */ jsxRuntime.jsx(
5627
- ComponentPicker,
5628
- {
5629
- dynamicComponentsByCategory,
5630
- isOpen: addComponentIsOpen,
5631
- onClickAddComponent: handleAddComponent
5632
- }
5633
- )
5634
- ] }) });
5601
+ !attribute.repeatable && !field.value && /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
5602
+ !attribute.repeatable && field.value ? /* @__PURE__ */ jsxRuntime.jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
5603
+ attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
5604
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
5605
+ ] });
5635
5606
  };
5607
+ const MemoizedComponentInput = React__namespace.memo(ComponentInput);
5636
5608
  exports.DynamicZone = DynamicZone;
5609
+ exports.FormLayout = FormLayout;
5637
5610
  exports.MemoizedBlocksInput = MemoizedBlocksInput;
5638
5611
  exports.MemoizedComponentInput = MemoizedComponentInput;
5639
- exports.MemoizedInputRenderer = MemoizedInputRenderer;
5640
5612
  exports.MemoizedUIDInput = MemoizedUIDInput;
5641
5613
  exports.MemoizedWysiwyg = MemoizedWysiwyg;
5642
5614
  exports.NotAllowedInput = NotAllowedInput;
5643
- exports.createDefaultForm = createDefaultForm;
5644
- exports.prepareTempKeys = prepareTempKeys;
5645
- exports.removeFieldsThatDontExistOnSchema = removeFieldsThatDontExistOnSchema;
5646
- exports.transformDocument = transformDocument;
5647
5615
  exports.useDynamicZone = useDynamicZone;
5648
5616
  exports.useFieldHint = useFieldHint;
5649
5617
  exports.useLazyComponents = useLazyComponents;
5650
- //# sourceMappingURL=Field-DPIsQRre.js.map
5618
+ //# sourceMappingURL=Input-CDHKQd7o.js.map