@strapi/content-manager 0.0.0-experimental.8c83c87960f2f5ddf95ae2f0acf849052f4a9ab4 → 0.0.0-experimental.8e4302929d7fe147203ed0266450d0a565c69660

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 (141) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-BgCLcjXO.mjs → ComponentConfigurationPage-D4H-v0et.mjs} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-BgCLcjXO.mjs.map → ComponentConfigurationPage-D4H-v0et.mjs.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-DywpTZeV.js → ComponentConfigurationPage-DdkVGfXC.js} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-DywpTZeV.js.map → ComponentConfigurationPage-DdkVGfXC.js.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-BNjOAHNS.mjs → EditConfigurationPage-D1nvB7Br.mjs} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-BNjOAHNS.mjs.map → EditConfigurationPage-D1nvB7Br.mjs.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-CxRlP5if.js → EditConfigurationPage-LYEvR4fW.js} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-CxRlP5if.js.map → EditConfigurationPage-LYEvR4fW.js.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-CD_hqc1J.mjs → EditViewPage-Bcnff6Vd.mjs} +11 -74
  10. package/dist/_chunks/EditViewPage-Bcnff6Vd.mjs.map +1 -0
  11. package/dist/_chunks/{EditViewPage-BRewdTqE.js → EditViewPage-DqelJ9UK.js} +13 -76
  12. package/dist/_chunks/EditViewPage-DqelJ9UK.js.map +1 -0
  13. package/dist/_chunks/{Form-C_Gwv8P_.js → Form-CnHfBeiB.js} +2 -2
  14. package/dist/_chunks/{Form-C_Gwv8P_.js.map → Form-CnHfBeiB.js.map} +1 -1
  15. package/dist/_chunks/{Form-Czi0cf_2.mjs → Form-CzPCJi3B.mjs} +2 -2
  16. package/dist/_chunks/{Form-Czi0cf_2.mjs.map → Form-CzPCJi3B.mjs.map} +1 -1
  17. package/dist/_chunks/{History-CIQHyi4T.mjs → History-CcmSn3Mj.mjs} +32 -8
  18. package/dist/_chunks/History-CcmSn3Mj.mjs.map +1 -0
  19. package/dist/_chunks/{History-C1TKAig-.js → History-zArjENzj.js} +43 -19
  20. package/dist/_chunks/History-zArjENzj.js.map +1 -0
  21. package/dist/_chunks/{Field-DwvmENVf.js → Input-CDHKQd7o.js} +1300 -1276
  22. package/dist/_chunks/Input-CDHKQd7o.js.map +1 -0
  23. package/dist/_chunks/{Field-BPkQ-3Ku.mjs → Input-aV8SSoTa.mjs} +1218 -1195
  24. package/dist/_chunks/Input-aV8SSoTa.mjs.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-DcZsfyEL.mjs → ListConfigurationPage-BPvzENJJ.mjs} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-DcZsfyEL.mjs.map → ListConfigurationPage-BPvzENJJ.mjs.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-D-NGRLYu.js → ListConfigurationPage-ByZAO_9H.js} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-D-NGRLYu.js.map → ListConfigurationPage-ByZAO_9H.js.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-xv5IQoZp.js → ListViewPage-BVKBeQAA.js} +13 -10
  30. package/dist/_chunks/{ListViewPage-xv5IQoZp.js.map → ListViewPage-BVKBeQAA.js.map} +1 -1
  31. package/dist/_chunks/{ListViewPage-C10McTK1.mjs → ListViewPage-HljQVnFH.mjs} +8 -5
  32. package/dist/_chunks/{ListViewPage-C10McTK1.mjs.map → ListViewPage-HljQVnFH.mjs.map} +1 -1
  33. package/dist/_chunks/{NoContentTypePage-Dzw5Yj5u.js → NoContentTypePage-BV5zfDxr.js} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-Dzw5Yj5u.js.map → NoContentTypePage-BV5zfDxr.js.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-CPc0Cd3S.mjs → NoContentTypePage-BfHaSM-K.mjs} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-CPc0Cd3S.mjs.map → NoContentTypePage-BfHaSM-K.mjs.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-wfPBh2_0.mjs → NoPermissionsPage-D6ze2nQL.mjs} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-wfPBh2_0.mjs.map → NoPermissionsPage-D6ze2nQL.mjs.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-DAe5CDCC.js → NoPermissionsPage-vdNpc6jb.js} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-DAe5CDCC.js.map → NoPermissionsPage-vdNpc6jb.js.map} +1 -1
  41. package/dist/_chunks/{Preview-B7LyGT_b.js → Preview-DEHdENT1.js} +29 -14
  42. package/dist/_chunks/Preview-DEHdENT1.js.map +1 -0
  43. package/dist/_chunks/{Preview-BVFFm7uB.mjs → Preview-vfWOtPG5.mjs} +30 -15
  44. package/dist/_chunks/Preview-vfWOtPG5.mjs.map +1 -0
  45. package/dist/_chunks/{Relations-JPhWxk-s.mjs → Relations-B7_hbF0w.mjs} +6 -5
  46. package/dist/_chunks/Relations-B7_hbF0w.mjs.map +1 -0
  47. package/dist/_chunks/{Relations-BmYR1AjY.js → Relations-DcoOBejP.js} +6 -5
  48. package/dist/_chunks/Relations-DcoOBejP.js.map +1 -0
  49. package/dist/_chunks/{en-BK8Xyl5I.js → en-BR48D_RH.js} +9 -2
  50. package/dist/_chunks/{en-BK8Xyl5I.js.map → en-BR48D_RH.js.map} +1 -1
  51. package/dist/_chunks/{en-Dtk_ot79.mjs → en-D65uIF6Y.mjs} +9 -2
  52. package/dist/_chunks/{en-Dtk_ot79.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-C2Q_PLWj.js → index-CxLSGwnk.js} +433 -157
  58. package/dist/_chunks/index-CxLSGwnk.js.map +1 -0
  59. package/dist/_chunks/{index-DLIkNVnQ.mjs → index-EH8ZtHd5.mjs} +452 -176
  60. package/dist/_chunks/index-EH8ZtHd5.mjs.map +1 -0
  61. package/dist/_chunks/{layout-qE8qkNH_.mjs → layout-CxDMdJ13.mjs} +3 -3
  62. package/dist/_chunks/{layout-qE8qkNH_.mjs.map → layout-CxDMdJ13.mjs.map} +1 -1
  63. package/dist/_chunks/{layout-7AsWJzZJ.js → layout-DSeUTfMv.js} +3 -3
  64. package/dist/_chunks/{layout-7AsWJzZJ.js.map → layout-DSeUTfMv.js.map} +1 -1
  65. package/dist/_chunks/{relations-BjHH_1Am.mjs → relations-B8_Uu38Q.mjs} +17 -3
  66. package/dist/_chunks/relations-B8_Uu38Q.mjs.map +1 -0
  67. package/dist/_chunks/{relations-EifVzf_2.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 +2 -1
  74. package/dist/admin/index.js.map +1 -1
  75. package/dist/admin/index.mjs +6 -5
  76. package/dist/admin/src/content-manager.d.ts +3 -2
  77. package/dist/admin/src/exports.d.ts +1 -0
  78. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  79. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  80. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  81. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +1 -1
  82. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  83. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  84. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  85. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  86. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  87. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  88. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  89. package/dist/admin/src/preview/pages/Preview.d.ts +1 -1
  90. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  91. package/dist/admin/src/services/api.d.ts +1 -1
  92. package/dist/admin/src/services/components.d.ts +2 -2
  93. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  94. package/dist/admin/src/services/documents.d.ts +16 -16
  95. package/dist/admin/src/services/init.d.ts +1 -1
  96. package/dist/admin/src/services/relations.d.ts +2 -2
  97. package/dist/admin/src/services/uid.d.ts +3 -3
  98. package/dist/server/index.js +156 -142
  99. package/dist/server/index.js.map +1 -1
  100. package/dist/server/index.mjs +157 -143
  101. package/dist/server/index.mjs.map +1 -1
  102. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  103. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  104. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  105. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  106. package/dist/server/src/history/services/history.d.ts +3 -3
  107. package/dist/server/src/history/services/history.d.ts.map +1 -1
  108. package/dist/server/src/history/services/utils.d.ts +6 -10
  109. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  110. package/dist/server/src/index.d.ts +3 -2
  111. package/dist/server/src/index.d.ts.map +1 -1
  112. package/dist/server/src/preview/index.d.ts.map +1 -1
  113. package/dist/server/src/services/document-metadata.d.ts +4 -2
  114. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  115. package/dist/server/src/services/index.d.ts +3 -2
  116. package/dist/server/src/services/index.d.ts.map +1 -1
  117. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  118. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  119. package/dist/server/src/services/utils/populate.d.ts +2 -2
  120. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  121. package/package.json +8 -7
  122. package/dist/_chunks/EditViewPage-BRewdTqE.js.map +0 -1
  123. package/dist/_chunks/EditViewPage-CD_hqc1J.mjs.map +0 -1
  124. package/dist/_chunks/Field-BPkQ-3Ku.mjs.map +0 -1
  125. package/dist/_chunks/Field-DwvmENVf.js.map +0 -1
  126. package/dist/_chunks/History-C1TKAig-.js.map +0 -1
  127. package/dist/_chunks/History-CIQHyi4T.mjs.map +0 -1
  128. package/dist/_chunks/Preview-B7LyGT_b.js.map +0 -1
  129. package/dist/_chunks/Preview-BVFFm7uB.mjs.map +0 -1
  130. package/dist/_chunks/Relations-BmYR1AjY.js.map +0 -1
  131. package/dist/_chunks/Relations-JPhWxk-s.mjs.map +0 -1
  132. package/dist/_chunks/index-C2Q_PLWj.js.map +0 -1
  133. package/dist/_chunks/index-DLIkNVnQ.mjs.map +0 -1
  134. package/dist/_chunks/relations-BjHH_1Am.mjs.map +0 -1
  135. package/dist/_chunks/relations-EifVzf_2.js.map +0 -1
  136. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  137. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +0 -29
  138. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
  139. package/dist/admin/src/preview/constants.d.ts +0 -1
  140. package/dist/server/src/preview/constants.d.ts +0 -2
  141. package/dist/server/src/preview/constants.d.ts.map +0 -1
@@ -3,23 +3,74 @@ 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-C2Q_PLWj.js");
9
- const fractionalIndexing = require("fractional-indexing");
10
- const Relations = require("./Relations-BmYR1AjY.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");
20
- const useDebounce = require("./useDebounce-CtcjDB3L.js");
13
+ const Prism = require("prismjs");
14
+ require("prismjs/themes/prism-solarizedlight.css");
15
+ require("prismjs/components/prism-asmatmel");
16
+ require("prismjs/components/prism-bash");
17
+ require("prismjs/components/prism-basic");
18
+ require("prismjs/components/prism-c");
19
+ require("prismjs/components/prism-clojure");
20
+ require("prismjs/components/prism-cobol");
21
+ require("prismjs/components/prism-cpp");
22
+ require("prismjs/components/prism-csharp");
23
+ require("prismjs/components/prism-dart");
24
+ require("prismjs/components/prism-docker");
25
+ require("prismjs/components/prism-elixir");
26
+ require("prismjs/components/prism-erlang");
27
+ require("prismjs/components/prism-fortran");
28
+ require("prismjs/components/prism-fsharp");
29
+ require("prismjs/components/prism-go");
30
+ require("prismjs/components/prism-graphql");
31
+ require("prismjs/components/prism-groovy");
32
+ require("prismjs/components/prism-haskell");
33
+ require("prismjs/components/prism-haxe");
34
+ require("prismjs/components/prism-ini");
35
+ require("prismjs/components/prism-java");
36
+ require("prismjs/components/prism-javascript");
37
+ require("prismjs/components/prism-jsx");
38
+ require("prismjs/components/prism-json");
39
+ require("prismjs/components/prism-julia");
40
+ require("prismjs/components/prism-kotlin");
41
+ require("prismjs/components/prism-latex");
42
+ require("prismjs/components/prism-lua");
43
+ require("prismjs/components/prism-markdown");
44
+ require("prismjs/components/prism-matlab");
45
+ require("prismjs/components/prism-makefile");
46
+ require("prismjs/components/prism-objectivec");
47
+ require("prismjs/components/prism-perl");
48
+ require("prismjs/components/prism-php");
49
+ require("prismjs/components/prism-powershell");
50
+ require("prismjs/components/prism-python");
51
+ require("prismjs/components/prism-r");
52
+ require("prismjs/components/prism-ruby");
53
+ require("prismjs/components/prism-rust");
54
+ require("prismjs/components/prism-sas");
55
+ require("prismjs/components/prism-scala");
56
+ require("prismjs/components/prism-scheme");
57
+ require("prismjs/components/prism-sql");
58
+ require("prismjs/components/prism-stata");
59
+ require("prismjs/components/prism-swift");
60
+ require("prismjs/components/prism-typescript");
61
+ require("prismjs/components/prism-tsx");
62
+ require("prismjs/components/prism-vbnet");
63
+ require("prismjs/components/prism-yaml");
64
+ const usePrev = require("./usePrev-B9w_-eYc.js");
65
+ const useDragAndDrop = require("./useDragAndDrop-BMtgCYzL.js");
21
66
  const Toolbar = require("@radix-ui/react-toolbar");
67
+ const reactDndHtml5Backend = require("react-dnd-html5-backend");
22
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");
23
74
  const CodeMirror = require("codemirror5");
24
75
  const sanitizeHtml = require("sanitize-html");
25
76
  const highlight_js = require("highlight.js");
@@ -54,8 +105,9 @@ function _interopNamespace(e) {
54
105
  return Object.freeze(n);
55
106
  }
56
107
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
57
- const pipe__default = /* @__PURE__ */ _interopDefault(pipe$1);
108
+ const Prism__namespace = /* @__PURE__ */ _interopNamespace(Prism);
58
109
  const Toolbar__namespace = /* @__PURE__ */ _interopNamespace(Toolbar);
110
+ const pipe__default = /* @__PURE__ */ _interopDefault(pipe$1);
59
111
  const CodeMirror__default = /* @__PURE__ */ _interopDefault(CodeMirror);
60
112
  const sanitizeHtml__default = /* @__PURE__ */ _interopDefault(sanitizeHtml);
61
113
  const Markdown__default = /* @__PURE__ */ _interopDefault(Markdown);
@@ -68,93 +120,6 @@ const ins__default = /* @__PURE__ */ _interopDefault(ins);
68
120
  const mark__default = /* @__PURE__ */ _interopDefault(mark);
69
121
  const sub__default = /* @__PURE__ */ _interopDefault(sub);
70
122
  const sup__default = /* @__PURE__ */ _interopDefault(sup);
71
- const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
72
- const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
73
- const traverse = (datum, attributes) => {
74
- return Object.entries(datum).reduce((acc, [key, value]) => {
75
- const attribute = attributes[key];
76
- if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
77
- acc[key] = value;
78
- return acc;
79
- }
80
- if (attribute.type === "component") {
81
- if (attribute.repeatable) {
82
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
83
- acc[key] = componentValue.map(
84
- (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
85
- );
86
- } else {
87
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
88
- acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
89
- }
90
- } else if (attribute.type === "dynamiczone") {
91
- const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
92
- acc[key] = dynamicZoneValue.map(
93
- (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
94
- );
95
- } else if (predicate(attribute, value)) {
96
- acc[key] = transform(value, attribute);
97
- } else {
98
- acc[key] = value;
99
- }
100
- return acc;
101
- }, {});
102
- };
103
- return traverse(data, schema.attributes);
104
- };
105
- const removeProhibitedFields = (prohibitedFields) => traverseData(
106
- (attribute) => prohibitedFields.includes(attribute.type),
107
- () => ""
108
- );
109
- const prepareRelations = traverseData(
110
- (attribute) => attribute.type === "relation",
111
- () => ({
112
- connect: [],
113
- disconnect: []
114
- })
115
- );
116
- const prepareTempKeys = traverseData(
117
- (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
118
- (data) => {
119
- if (Array.isArray(data) && data.length > 0) {
120
- const keys = fractionalIndexing.generateNKeysBetween(void 0, void 0, data.length);
121
- return data.map((datum, index2) => ({
122
- ...datum,
123
- __temp_key__: keys[index2]
124
- }));
125
- }
126
- return data;
127
- }
128
- );
129
- const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
130
- const schemaKeys = Object.keys(schema.attributes);
131
- const dataKeys = Object.keys(data);
132
- const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
133
- const revisedData = [...keysToRemove, ...index.DOCUMENT_META_FIELDS].reduce((acc, key) => {
134
- delete acc[key];
135
- return acc;
136
- }, structuredClone(data));
137
- return revisedData;
138
- };
139
- const removeNullValues = (data) => {
140
- return Object.entries(data).reduce((acc, [key, value]) => {
141
- if (value === null) {
142
- return acc;
143
- }
144
- acc[key] = value;
145
- return acc;
146
- }, {});
147
- };
148
- const transformDocument = (schema, components = {}) => (document2) => {
149
- const transformations = pipe__default.default(
150
- removeFieldsThatDontExistOnSchema(schema),
151
- removeProhibitedFields(["password"])(schema, components),
152
- removeNullValues,
153
- prepareRelations(schema, components),
154
- prepareTempKeys(schema, components)
155
- );
156
- return transformations(document2);
157
- };
158
123
  const componentStore = /* @__PURE__ */ new Map();
159
124
  const useLazyComponents = (componentUids = []) => {
160
125
  const [lazyComponentStore, setLazyComponentStore] = React.useState(Object.fromEntries(componentStore));
@@ -196,7 +161,8 @@ const useLazyComponents = (componentUids = []) => {
196
161
  const codeLanguages = [
197
162
  {
198
163
  value: "asm",
199
- label: "Assembly"
164
+ label: "Assembly",
165
+ decorate: "asmatmel"
200
166
  },
201
167
  {
202
168
  value: "bash",
@@ -232,7 +198,8 @@ const codeLanguages = [
232
198
  },
233
199
  {
234
200
  value: "dockerfile",
235
- label: "Dockerfile"
201
+ label: "Dockerfile",
202
+ decorate: "docker"
236
203
  },
237
204
  {
238
205
  value: "elixir",
@@ -388,7 +355,8 @@ const codeLanguages = [
388
355
  },
389
356
  {
390
357
  value: "typescript",
391
- label: "TypeScript"
358
+ label: "TypeScript",
359
+ decorate: "ts"
392
360
  },
393
361
  {
394
362
  value: "tsx",
@@ -404,7 +372,8 @@ const codeLanguages = [
404
372
  },
405
373
  {
406
374
  value: "yaml",
407
- label: "YAML"
375
+ label: "YAML",
376
+ decorate: "yml"
408
377
  }
409
378
  ];
410
379
  const baseHandleConvert = (editor, attributesToSet) => {
@@ -470,6 +439,29 @@ const pressEnterTwiceToExit = (editor) => {
470
439
  });
471
440
  }
472
441
  };
442
+ const decorateCode = ([node, path]) => {
443
+ const ranges = [];
444
+ if (!slate.Element.isElement(node) || node.type !== "code") return ranges;
445
+ const text = slate.Node.string(node);
446
+ const language = codeLanguages.find((lang) => lang.value === node.language);
447
+ const decorateKey = language?.decorate ?? language?.value;
448
+ const selectedLanguage = Prism__namespace.languages[decorateKey || "plaintext"];
449
+ const tokens = Prism__namespace.tokenize(text, selectedLanguage);
450
+ let start = 0;
451
+ for (const token of tokens) {
452
+ const length = token.length;
453
+ const end = start + length;
454
+ if (typeof token !== "string") {
455
+ ranges.push({
456
+ anchor: { path, offset: start },
457
+ focus: { path, offset: end },
458
+ className: `token ${token.type}`
459
+ });
460
+ }
461
+ start = end;
462
+ }
463
+ return ranges;
464
+ };
473
465
  const CodeBlock = styledComponents.styled.pre`
474
466
  border-radius: ${({ theme }) => theme.borderRadius};
475
467
  background-color: ${({ theme }) => theme.colors.neutral100};
@@ -554,8 +546,7 @@ const codeBlocks = {
554
546
  handleEnterKey(editor) {
555
547
  pressEnterTwiceToExit(editor);
556
548
  },
557
- snippets: ["```"],
558
- dragHandleTopMargin: "10px"
549
+ snippets: ["```"]
559
550
  }
560
551
  };
561
552
  const H1 = styledComponents.styled(designSystem.Typography).attrs({ tag: "h1" })`
@@ -764,7 +755,7 @@ const ImageDialog = () => {
764
755
  const nodeImage = {
765
756
  ...expectedImage,
766
757
  alternativeText: expectedImage.alternativeText || expectedImage.name,
767
- url: useDebounce.prefixFileUrlWithBackendUrl(image.url)
758
+ url: usePrev.prefixFileUrlWithBackendUrl(image.url)
768
759
  };
769
760
  return nodeImage;
770
761
  });
@@ -992,11 +983,11 @@ const LinkContent = React__namespace.forwardRef(
992
983
  ),
993
984
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
994
985
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: handleClose, children: formatMessage({
995
- id: "components.Blocks.popover.cancel",
986
+ id: "global.cancel",
996
987
  defaultMessage: "Cancel"
997
988
  }) }),
998
989
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { disabled: Boolean(inputNotDirty) || isSaveDisabled, onClick: handleSave, children: formatMessage({
999
- id: "components.Blocks.popover.save",
990
+ id: "global.save",
1000
991
  defaultMessage: "Save"
1001
992
  }) })
1002
993
  ] })
@@ -1334,13 +1325,13 @@ const quoteBlocks = {
1334
1325
  handleEnterKey(editor) {
1335
1326
  pressEnterTwiceToExit(editor);
1336
1327
  },
1337
- snippets: [">"],
1338
- dragHandleTopMargin: "6px"
1328
+ snippets: [">"]
1339
1329
  }
1340
1330
  };
1341
1331
  const ToolbarWrapper = styledComponents.styled(designSystem.Flex)`
1342
1332
  &[aria-disabled='true'] {
1343
1333
  cursor: not-allowed;
1334
+ background: ${({ theme }) => theme.colors.neutral150};
1344
1335
  }
1345
1336
  `;
1346
1337
  const Separator = styledComponents.styled(Toolbar__namespace.Separator)`
@@ -1351,7 +1342,7 @@ const Separator = styledComponents.styled(Toolbar__namespace.Separator)`
1351
1342
  const FlexButton = styledComponents.styled(designSystem.Flex)`
1352
1343
  // Inherit the not-allowed cursor from ToolbarWrapper when disabled
1353
1344
  &[aria-disabled] {
1354
- cursor: inherit;
1345
+ cursor: not-allowed;
1355
1346
  }
1356
1347
 
1357
1348
  &[aria-disabled='false'] {
@@ -1703,7 +1694,7 @@ const BlocksToolbar = () => {
1703
1694
  return false;
1704
1695
  };
1705
1696
  const isButtonDisabled = checkButtonDisabled();
1706
- return /* @__PURE__ */ jsxRuntime.jsx(Toolbar__namespace.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarWrapper, { gap: 2, padding: 2, children: [
1697
+ return /* @__PURE__ */ jsxRuntime.jsx(Toolbar__namespace.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarWrapper, { gap: 2, padding: 2, width: "100%", children: [
1707
1698
  /* @__PURE__ */ jsxRuntime.jsx(BlocksDropdown, {}),
1708
1699
  /* @__PURE__ */ jsxRuntime.jsx(Separator, {}),
1709
1700
  /* @__PURE__ */ jsxRuntime.jsx(Toolbar__namespace.ToggleGroup, { type: "multiple", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, children: [
@@ -1777,30 +1768,32 @@ const DragIconButton = styledComponents.styled(designSystem.IconButton)`
1777
1768
  display: flex;
1778
1769
  align-items: center;
1779
1770
  justify-content: center;
1771
+ border: none;
1780
1772
  border-radius: ${({ theme }) => theme.borderRadius};
1781
- width: ${({ theme }) => theme.spaces[4]};
1782
- height: ${({ theme }) => theme.spaces[6]};
1773
+ padding-left: ${({ theme }) => theme.spaces[0]};
1774
+ padding-right: ${({ theme }) => theme.spaces[0]};
1775
+ padding-top: ${({ theme }) => theme.spaces[1]};
1776
+ padding-bottom: ${({ theme }) => theme.spaces[1]};
1783
1777
  visibility: hidden;
1784
1778
  cursor: grab;
1785
1779
  opacity: inherit;
1786
1780
  margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};
1787
1781
 
1788
1782
  &:hover {
1789
- background: ${({ theme }) => theme.colors.neutral200};
1783
+ background: ${({ theme }) => theme.colors.neutral100};
1790
1784
  }
1791
1785
  &:active {
1792
1786
  cursor: grabbing;
1787
+ background: ${({ theme }) => theme.colors.neutral150};
1793
1788
  }
1794
1789
  &[aria-disabled='true'] {
1795
- cursor: not-allowed;
1796
- background: transparent;
1790
+ visibility: hidden;
1797
1791
  }
1798
1792
  svg {
1799
- height: auto;
1800
1793
  min-width: ${({ theme }) => theme.spaces[3]};
1801
1794
 
1802
1795
  path {
1803
- fill: ${({ theme }) => theme.colors.neutral700};
1796
+ fill: ${({ theme }) => theme.colors.neutral500};
1804
1797
  }
1805
1798
  }
1806
1799
  `;
@@ -1951,7 +1944,7 @@ const baseRenderLeaf = (props, modifiers2) => {
1951
1944
  }
1952
1945
  return currentChildren;
1953
1946
  }, props.children);
1954
- return /* @__PURE__ */ jsxRuntime.jsx("span", { ...props.attributes, children: wrappedChildren });
1947
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ...props.attributes, className: props.leaf.className, children: wrappedChildren });
1955
1948
  };
1956
1949
  const baseRenderElement = ({
1957
1950
  props,
@@ -2153,7 +2146,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2153
2146
  background: "neutral0",
2154
2147
  color: "neutral800",
2155
2148
  lineHeight: 6,
2156
- paddingRight: 4,
2149
+ paddingRight: 7,
2157
2150
  paddingTop: 6,
2158
2151
  paddingBottom: 3,
2159
2152
  children: [
@@ -2164,6 +2157,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
2164
2157
  readOnly: disabled,
2165
2158
  placeholder,
2166
2159
  isExpandedMode,
2160
+ decorate: decorateCode,
2167
2161
  renderElement,
2168
2162
  renderLeaf,
2169
2163
  onKeyDown: handleKeyDown,
@@ -2486,6 +2480,7 @@ const ExpandIconButton = styledComponents.styled(designSystem.IconButton)`
2486
2480
  position: absolute;
2487
2481
  bottom: 1.2rem;
2488
2482
  right: 1.2rem;
2483
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2489
2484
  `;
2490
2485
  function useResetKey(value) {
2491
2486
  const slateUpdatesCount = React__namespace.useRef(0);
@@ -2617,26 +2612,6 @@ const BlocksInput = React__namespace.forwardRef(
2617
2612
  }
2618
2613
  );
2619
2614
  const MemoizedBlocksInput = React__namespace.memo(BlocksInput);
2620
- const createDefaultForm = (contentType, components = {}) => {
2621
- const traverseSchema = (attributes) => {
2622
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2623
- if ("default" in attribute) {
2624
- acc[key] = attribute.default;
2625
- } else if (attribute.type === "component" && attribute.required) {
2626
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2627
- if (attribute.repeatable) {
2628
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2629
- } else {
2630
- acc[key] = defaultComponentForm;
2631
- }
2632
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2633
- acc[key] = [];
2634
- }
2635
- return acc;
2636
- }, {});
2637
- };
2638
- return traverseSchema(contentType.attributes);
2639
- };
2640
2615
  const Initializer = ({ disabled, name: name2, onClick }) => {
2641
2616
  const { formatMessage } = reactIntl.useIntl();
2642
2617
  const field = strapiAdmin.useField(name2);
@@ -2671,624 +2646,619 @@ const Initializer = ({ disabled, name: name2, onClick }) => {
2671
2646
  }
2672
2647
  ) });
2673
2648
  };
2674
- const NonRepeatableComponent = ({
2675
- attribute,
2676
- name: name2,
2649
+ const AddComponentButton = ({
2650
+ hasError,
2651
+ isDisabled,
2652
+ isOpen,
2677
2653
  children,
2678
- 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
2679
2703
  }) => {
2680
2704
  const { formatMessage } = reactIntl.useIntl();
2681
- const { value } = strapiAdmin.useField(name2);
2682
- const level = Relations.useComponent("NonRepeatableComponent", (state) => state.level);
2683
- const isNested = level > 0;
2684
- 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(
2685
2768
  designSystem.Box,
2686
2769
  {
2687
- background: "neutral100",
2688
- paddingLeft: 6,
2689
- paddingRight: 6,
2690
2770
  paddingTop: 6,
2691
2771
  paddingBottom: 6,
2692
- hasRadius: isNested,
2693
- borderColor: isNested ? "neutral200" : void 0,
2694
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index2) => {
2695
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2696
- const completeFieldName = `${name2}.${field.name}`;
2697
- const translatedLabel = formatMessage({
2698
- id: `content-manager.components.${attribute.component}.${field.name}`,
2699
- defaultMessage: field.label
2700
- });
2701
- return /* @__PURE__ */ jsxRuntime.jsx(
2702
- designSystem.Grid.Item,
2703
- {
2704
- col: size,
2705
- s: 12,
2706
- xs: 12,
2707
- direction: "column",
2708
- alignItems: "stretch",
2709
- children: children({ ...field, label: translatedLabel, name: completeFieldName })
2710
- },
2711
- completeFieldName
2712
- );
2713
- }) }, index2);
2714
- }) })
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
+ ]
2715
2794
  }
2716
- ) });
2795
+ );
2717
2796
  };
2718
- const RepeatableComponent = ({
2719
- attribute,
2797
+ const DynamicComponent = ({
2798
+ componentUid,
2720
2799
  disabled,
2800
+ index: index$1,
2721
2801
  name: name2,
2722
- mainField,
2723
- children,
2724
- layout
2802
+ onRemoveComponentClick,
2803
+ onMoveComponent,
2804
+ onGrabItem,
2805
+ onDropItem,
2806
+ onCancel,
2807
+ dynamicComponentsByCategory = {},
2808
+ onAddComponent,
2809
+ children
2725
2810
  }) => {
2726
- const { toggleNotification } = strapiAdmin.useNotification();
2727
2811
  const { formatMessage } = reactIntl.useIntl();
2728
- const { search: searchString } = reactRouterDom.useLocation();
2729
- const search = React__namespace.useMemo(() => new URLSearchParams(searchString), [searchString]);
2730
- const { components } = index.useDoc();
2812
+ const formValues = strapiAdmin.useForm("DynamicComponent", (state) => state.values);
2731
2813
  const {
2732
- value = [],
2733
- error,
2734
- rawError
2735
- } = strapiAdmin.useField(name2);
2736
- const addFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.addFieldRow);
2737
- const moveFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.moveFieldRow);
2738
- const removeFieldRow = strapiAdmin.useForm("RepeatableComponent", (state) => state.removeFieldRow);
2739
- const { max = Infinity } = attribute;
2740
- const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
2741
- const [liveText, setLiveText] = React__namespace.useState("");
2742
- React__namespace.useEffect(() => {
2743
- const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
2744
- const hasNestedValue = value && Array.isArray(value) && value.length > 0;
2745
- if (hasNestedErrors && hasNestedValue) {
2746
- const errorOpenItems = rawError.map((_, idx) => {
2747
- return value[idx] ? value[idx].__temp_key__ : null;
2748
- }).filter((value2) => !!value2);
2749
- if (errorOpenItems && errorOpenItems.length > 0) {
2750
- setCollapseToOpen((collapseToOpen2) => {
2751
- if (!errorOpenItems.includes(collapseToOpen2)) {
2752
- return errorOpenItems[0];
2753
- }
2754
- return collapseToOpen2;
2755
- });
2756
- }
2757
- }
2758
- }, [rawError, value]);
2759
- const componentTmpKeyWithFocussedField = React__namespace.useMemo(() => {
2760
- if (search.has("field")) {
2761
- const fieldParam = search.get("field");
2762
- if (!fieldParam) {
2763
- return void 0;
2764
- }
2765
- const [, path] = fieldParam.split(`${name2}.`);
2766
- if (objects.getIn(value, path, void 0) !== void 0) {
2767
- const [subpath] = path.split(".");
2768
- return objects.getIn(value, subpath, void 0)?.__temp_key__;
2769
- }
2770
- }
2771
- return void 0;
2772
- }, [search, name2, value]);
2773
- const prevValue = useDebounce.usePrev(value);
2774
- React__namespace.useEffect(() => {
2775
- if (prevValue && prevValue.length < value.length) {
2776
- setCollapseToOpen(value[value.length - 1].__temp_key__);
2777
- }
2778
- }, [value, prevValue]);
2779
- React__namespace.useEffect(() => {
2780
- if (typeof componentTmpKeyWithFocussedField === "string") {
2781
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2782
- }
2783
- }, [componentTmpKeyWithFocussedField]);
2784
- const toggleCollapses = () => {
2785
- setCollapseToOpen("");
2786
- };
2787
- const handleClick = () => {
2788
- if (value.length < max) {
2789
- const schema = components[attribute.component];
2790
- const form = createDefaultForm(schema, components);
2791
- const data = transformDocument(schema, components)(form);
2792
- addFieldRow(name2, data);
2793
- } else if (value.length >= max) {
2794
- toggleNotification({
2795
- type: "info",
2796
- message: formatMessage({
2797
- id: index.getTranslation("components.notification.info.maximum-requirement")
2798
- })
2799
- });
2800
- }
2801
- };
2802
- const handleMoveComponentField = (newIndex, currentIndex) => {
2803
- setLiveText(
2804
- formatMessage(
2805
- {
2806
- id: index.getTranslation("dnd.reorder"),
2807
- defaultMessage: "{item}, moved. New position in list: {position}."
2808
- },
2809
- {
2810
- item: `${name2}.${currentIndex}`,
2811
- position: getItemPos(newIndex)
2812
- }
2813
- )
2814
- );
2815
- moveFieldRow(name2, currentIndex, newIndex);
2816
- };
2817
- const handleValueChange = (key) => {
2818
- setCollapseToOpen(key);
2819
- };
2820
- const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
2821
- const handleCancel = (index$1) => {
2822
- setLiveText(
2823
- formatMessage(
2824
- {
2825
- id: index.getTranslation("dnd.cancel-item"),
2826
- defaultMessage: "{item}, dropped. Re-order cancelled."
2827
- },
2828
- {
2829
- item: `${name2}.${index$1}`
2830
- }
2831
- )
2832
- );
2833
- };
2834
- const handleGrabItem = (index$1) => {
2835
- setLiveText(
2836
- formatMessage(
2837
- {
2838
- id: index.getTranslation("dnd.grab-item"),
2839
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
2840
- },
2841
- {
2842
- item: `${name2}.${index$1}`,
2843
- position: getItemPos(index$1)
2844
- }
2845
- )
2846
- );
2847
- };
2848
- const handleDropItem = (index$1) => {
2849
- setLiveText(
2850
- formatMessage(
2851
- {
2852
- id: index.getTranslation("dnd.drop-item"),
2853
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
2854
- },
2855
- {
2856
- item: `${name2}.${index$1}`,
2857
- position: getItemPos(index$1)
2858
- }
2859
- )
2860
- );
2861
- };
2862
- const ariaDescriptionId = React__namespace.useId();
2863
- const level = Relations.useComponent("RepeatableComponent", (state) => state.level);
2864
- if (value.length === 0) {
2865
- return /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2866
- }
2867
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { hasRadius: true, children: [
2868
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2869
- id: index.getTranslation("dnd.instructions"),
2870
- defaultMessage: `Press spacebar to grab and re-order`
2871
- }) }),
2872
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2873
- /* @__PURE__ */ jsxRuntime.jsxs(
2874
- AccordionRoot,
2875
- {
2876
- $error: error,
2877
- value: collapseToOpen,
2878
- onValueChange: handleValueChange,
2879
- "aria-describedby": ariaDescriptionId,
2880
- children: [
2881
- value.map(({ __temp_key__: key, id }, index2) => {
2882
- const nameWithIndex = `${name2}.${index2}`;
2883
- return /* @__PURE__ */ jsxRuntime.jsx(
2884
- Relations.ComponentProvider,
2885
- {
2886
- id,
2887
- uid: attribute.component,
2888
- level: level + 1,
2889
- type: "repeatable",
2890
- children: /* @__PURE__ */ jsxRuntime.jsx(
2891
- Component,
2892
- {
2893
- disabled,
2894
- name: nameWithIndex,
2895
- attribute,
2896
- index: index2,
2897
- mainField,
2898
- onMoveItem: handleMoveComponentField,
2899
- onDeleteComponent: () => {
2900
- removeFieldRow(name2, index2);
2901
- toggleCollapses();
2902
- },
2903
- toggleCollapses,
2904
- onCancel: handleCancel,
2905
- onDropItem: handleDropItem,
2906
- onGrabItem: handleGrabItem,
2907
- __temp_key__: key,
2908
- children: layout.map((row, index22) => {
2909
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
2910
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2911
- const translatedLabel = formatMessage({
2912
- id: `content-manager.components.${attribute.component}.${field.name}`,
2913
- defaultMessage: field.label
2914
- });
2915
- return /* @__PURE__ */ jsxRuntime.jsx(
2916
- designSystem.Grid.Item,
2917
- {
2918
- col: size,
2919
- s: 12,
2920
- xs: 12,
2921
- direction: "column",
2922
- alignItems: "stretch",
2923
- children: children({
2924
- ...field,
2925
- label: translatedLabel,
2926
- name: completeFieldName
2927
- })
2928
- },
2929
- completeFieldName
2930
- );
2931
- }) }, index22);
2932
- })
2933
- }
2934
- )
2935
- },
2936
- key
2937
- );
2938
- }),
2939
- /* @__PURE__ */ jsxRuntime.jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Plus, {}), children: formatMessage({
2940
- id: index.getTranslation("containers.EditView.add.new-entry"),
2941
- defaultMessage: "Add an entry"
2942
- }) })
2943
- ]
2944
- }
2945
- )
2946
- ] });
2947
- };
2948
- const AccordionRoot = styledComponents.styled(designSystem.Accordion.Root)`
2949
- border: 1px solid
2950
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
2951
- `;
2952
- const TextButtonCustom = styledComponents.styled(designSystem.TextButton)`
2953
- width: 100%;
2954
- display: flex;
2955
- justify-content: center;
2956
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
2957
- padding-inline: ${(props) => props.theme.spaces[6]};
2958
- padding-block: ${(props) => props.theme.spaces[3]};
2959
-
2960
- &:not([disabled]) {
2961
- cursor: pointer;
2962
-
2963
- &:hover {
2964
- background-color: ${(props) => props.theme.colors.primary100};
2965
- }
2966
- }
2967
-
2968
- span {
2969
- font-weight: 600;
2970
- font-size: 1.4rem;
2971
- line-height: 2.4rem;
2972
- }
2973
-
2974
- @media (prefers-reduced-motion: no-preference) {
2975
- transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2976
- }
2977
- `;
2978
- const Component = ({
2979
- disabled,
2980
- index: index$1,
2981
- name: name2,
2982
- mainField = {
2983
- name: "id",
2984
- type: "integer"
2985
- },
2986
- children,
2987
- onDeleteComponent,
2988
- toggleCollapses,
2989
- __temp_key__,
2990
- ...dragProps
2991
- }) => {
2992
- const { formatMessage } = reactIntl.useIntl();
2993
- const displayValue = strapiAdmin.useForm("RepeatableComponent", (state) => {
2994
- return objects.getIn(state.values, [...name2.split("."), mainField.name]);
2995
- });
2996
- const accordionRef = React__namespace.useRef(null);
2997
- const componentKey = name2.split(".").slice(0, -1).join(".");
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]);
2998
2830
  const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(!disabled, {
2999
- type: `${useDragAndDrop.ItemTypes.COMPONENT}_${componentKey}`,
2831
+ type: `${useDragAndDrop.ItemTypes.DYNAMIC_ZONE}_${name2}`,
3000
2832
  index: index$1,
3001
2833
  item: {
3002
2834
  index: index$1,
3003
- displayedValue: displayValue
3004
- },
3005
- onStart() {
3006
- toggleCollapses();
2835
+ displayedValue: `${displayName} ${title}`,
2836
+ icon
3007
2837
  },
3008
- ...dragProps
2838
+ onMoveItem: onMoveComponent,
2839
+ onDropItem,
2840
+ onGrabItem,
2841
+ onCancel
3009
2842
  });
3010
2843
  React__namespace.useEffect(() => {
3011
2844
  dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
3012
2845
  }, [dragPreviewRef, index$1]);
3013
- const composedAccordionRefs = designSystem.useComposedRefs(accordionRef, dragRef);
3014
- const composedBoxRefs = designSystem.useComposedRefs(
3015
- boxRef,
3016
- dropRef
3017
- );
3018
- 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: [
3019
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
3020
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: displayValue }),
3021
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Actions, { children: [
3022
- /* @__PURE__ */ jsxRuntime.jsx(
3023
- designSystem.IconButton,
2846
+ const accordionValue = React__namespace.useId();
2847
+ const { value = [], rawError } = strapiAdmin.useField(`${name2}.${index$1}`);
2848
+ const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
2849
+ React__namespace.useEffect(() => {
2850
+ if (rawError && value) {
2851
+ setCollapseToOpen(accordionValue);
2852
+ }
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(
3024
2861
  {
3025
- variant: "ghost",
3026
- onClick: onDeleteComponent,
3027
- label: formatMessage({
3028
- id: index.getTranslation("containers.Edit.delete"),
3029
- defaultMessage: "Delete"
3030
- }),
3031
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
3032
- }
2862
+ id: index.getTranslation("components.DynamicZone.delete-label"),
2863
+ defaultMessage: "Delete {name}"
2864
+ },
2865
+ { name: title }
3033
2866
  ),
3034
- /* @__PURE__ */ jsxRuntime.jsx(
3035
- designSystem.IconButton,
3036
- {
3037
- ref: composedAccordionRefs,
3038
- variant: "ghost",
3039
- onClick: (e) => e.stopPropagation(),
3040
- "data-handler-id": handlerId,
3041
- label: formatMessage({
3042
- id: index.getTranslation("components.DragHandle-label"),
3043
- defaultMessage: "Drag"
3044
- }),
3045
- onKeyDown: handleKeyDown,
3046
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
3047
- }
3048
- )
3049
- ] })
3050
- ] }),
3051
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(
3052
- designSystem.Flex,
2867
+ onClick: onRemoveComponentClick,
2868
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
2869
+ }
2870
+ ),
2871
+ /* @__PURE__ */ jsxRuntime.jsx(
2872
+ designSystem.IconButton,
3053
2873
  {
3054
- direction: "column",
3055
- alignItems: "stretch",
3056
- background: "neutral100",
3057
- padding: 6,
3058
- gap: 6,
3059
- children
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, {})
3060
2884
  }
3061
- ) })
3062
- ] }) });
3063
- };
3064
- const Preview$1 = () => {
3065
- return /* @__PURE__ */ jsxRuntime.jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
3066
- };
3067
- const StyledSpan = styledComponents.styled(designSystem.Box)`
3068
- display: block;
3069
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
3070
- outline-offset: -1px;
3071
- `;
3072
- const ComponentInput = ({
3073
- label,
3074
- required,
3075
- name: name2,
3076
- attribute,
3077
- disabled,
3078
- labelAction,
3079
- ...props
3080
- }) => {
3081
- const { formatMessage } = reactIntl.useIntl();
3082
- const field = strapiAdmin.useField(name2);
3083
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
3084
- const { components } = index.useDoc();
3085
- const handleInitialisationClick = () => {
3086
- const schema = components[attribute.component];
3087
- const form = createDefaultForm(schema, components);
3088
- const data = transformDocument(schema, components)(form);
3089
- field.onChange(name2, data);
3090
- };
3091
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: field.error, required, children: [
3092
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
3093
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { action: labelAction, children: [
3094
- label,
3095
- attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3096
- " (",
3097
- Array.isArray(field.value) ? field.value.length : 0,
3098
- ")"
3099
- ] })
3100
- ] }),
3101
- showResetComponent && /* @__PURE__ */ jsxRuntime.jsx(
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(
3102
2888
  designSystem.IconButton,
3103
2889
  {
2890
+ variant: "ghost",
3104
2891
  label: formatMessage({
3105
- id: index.getTranslation("components.reset-entry"),
3106
- defaultMessage: "Reset Entry"
2892
+ id: index.getTranslation("components.DynamicZone.more-actions"),
2893
+ defaultMessage: "More actions"
3107
2894
  }),
3108
- variant: "ghost",
3109
- onClick: () => {
3110
- field.onChange(name2, null);
3111
- },
3112
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
2895
+ tag: "span",
2896
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false })
3113
2897
  }
3114
- )
3115
- ] }),
3116
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsxRuntime.jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
3117
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsxRuntime.jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
3118
- attribute.repeatable && /* @__PURE__ */ jsxRuntime.jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
3119
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
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,
2939
+ {
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
+ };
2954
+ return /* @__PURE__ */ jsxRuntime.jsx(
2955
+ ResponsiveGridItem,
2956
+ {
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 })
2963
+ },
2964
+ fieldName
2965
+ );
2966
+ }) })
2967
+ },
2968
+ rowInd
2969
+ )) }) }) }) })
2970
+ ] }) }) })
3120
2971
  ] });
3121
2972
  };
3122
- const MemoizedComponentInput = React__namespace.memo(ComponentInput);
3123
- const AddComponentButton = ({
3124
- hasError,
3125
- isDisabled,
3126
- isOpen,
3127
- children,
3128
- onClick
2973
+ const StyledBox = styledComponents.styled(designSystem.Box)`
2974
+ > div:first-child {
2975
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
2976
+ }
2977
+ `;
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`
2986
+ display: block;
2987
+ background-color: ${({ theme }) => theme.colors.primary100};
2988
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2989
+ outline-offset: -1px;
2990
+ padding: ${({ theme }) => theme.spaces[6]};
2991
+ `;
2992
+ const ComponentContainer = styledComponents.styled(designSystem.Box)`
2993
+ list-style: none;
2994
+ padding: 0;
2995
+ margin: 0;
2996
+ `;
2997
+ const DynamicZoneLabel = ({
2998
+ hint,
2999
+ label,
3000
+ labelAction,
3001
+ name: name2,
3002
+ numberOfComponents = 0,
3003
+ required
3129
3004
  }) => {
3130
- return /* @__PURE__ */ jsxRuntime.jsx(
3131
- StyledButton,
3005
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
3006
+ designSystem.Box,
3132
3007
  {
3133
- type: "button",
3134
- onClick,
3135
- disabled: isDisabled,
3008
+ paddingTop: 3,
3009
+ paddingBottom: 3,
3010
+ paddingRight: 4,
3011
+ paddingLeft: 4,
3012
+ borderRadius: "26px",
3136
3013
  background: "neutral0",
3137
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
3138
- variant: "tertiary",
3139
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { tag: "span", gap: 2, children: [
3140
- /* @__PURE__ */ jsxRuntime.jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
3141
- /* @__PURE__ */ jsxRuntime.jsx(
3142
- AddComponentTitle,
3143
- {
3144
- variant: "pi",
3145
- fontWeight: "bold",
3146
- textColor: hasError && !isOpen ? "danger600" : "neutral500",
3147
- children
3148
- }
3149
- )
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 }) })
3150
3031
  ] })
3151
3032
  }
3152
- );
3033
+ ) });
3153
3034
  };
3154
- const StyledAddIcon = styledComponents.styled(Icons.PlusCircle)`
3155
- height: ${({ theme }) => theme.spaces[6]};
3156
- width: ${({ theme }) => theme.spaces[6]};
3157
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
3158
-
3159
- > circle {
3160
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
3161
- }
3162
- > path {
3163
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral600};
3035
+ const [DynamicZoneProvider, useDynamicZone] = strapiAdmin.createContext(
3036
+ "DynamicZone",
3037
+ {
3038
+ isInDynamicZone: false
3164
3039
  }
3165
- `;
3166
- const AddComponentTitle = styledComponents.styled(designSystem.Typography)``;
3167
- const StyledButton = styledComponents.styled(designSystem.Button)`
3168
- border-radius: 26px;
3169
- border-color: ${({ theme }) => theme.colors.neutral150};
3170
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
3171
- height: 5rem;
3172
-
3173
- &:hover {
3174
- ${AddComponentTitle} {
3175
- color: ${({ theme }) => theme.colors.primary600};
3176
- }
3177
-
3178
- ${StyledAddIcon} {
3179
- > circle {
3180
- fill: ${({ theme }) => theme.colors.primary600};
3181
- }
3182
- > path {
3183
- fill: ${({ theme }) => theme.colors.primary600};
3040
+ );
3041
+ const DynamicZone = ({
3042
+ attribute,
3043
+ disabled: disabledProp,
3044
+ hint,
3045
+ label,
3046
+ labelAction,
3047
+ name: name2,
3048
+ required = false,
3049
+ children
3050
+ }) => {
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] = [];
3184
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
+ });
3185
3100
  }
3186
- }
3187
- &:active {
3188
- ${AddComponentTitle} {
3189
- color: ${({ theme }) => theme.colors.primary600};
3101
+ };
3102
+ const handleMoveComponent = (newIndex, currentIndex) => {
3103
+ setLiveText(
3104
+ formatMessage(
3105
+ {
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)
3112
+ }
3113
+ )
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" });
3190
3166
  }
3191
- ${StyledAddIcon} {
3192
- > circle {
3193
- fill: ${({ theme }) => theme.colors.primary600};
3194
- }
3195
- > path {
3196
- fill: ${({ theme }) => theme.colors.neutral100};
3197
- }
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
+ );
3198
3177
  }
3199
- }
3200
- `;
3201
- const ComponentCategory = ({
3202
- category,
3203
- components = [],
3204
- variant = "primary",
3205
- onAddComponent
3206
- }) => {
3207
- const { formatMessage } = reactIntl.useIntl();
3208
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: category, children: [
3209
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { variant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
3210
- /* @__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(
3211
- ComponentBox,
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(
3212
3188
  {
3213
- tag: "button",
3214
- type: "button",
3215
- background: "neutral100",
3216
- justifyContent: "center",
3217
- onClick: onAddComponent(uid),
3218
- hasRadius: true,
3219
- height: "8.4rem",
3220
- shrink: 0,
3221
- borderColor: "neutral200",
3222
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
3223
- /* @__PURE__ */ jsxRuntime.jsx(ComponentIcon.ComponentIcon, { color: "currentColor", background: "primary200", icon }),
3224
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: displayName })
3225
- ] })
3189
+ id: index.getTranslation("components.DynamicZone.add-component"),
3190
+ defaultMessage: "Add a component to {componentName}"
3226
3191
  },
3227
- uid
3228
- )) }) })
3229
- ] });
3230
- };
3231
- const Grid = styledComponents.styled(designSystem.Box)`
3232
- display: grid;
3233
- grid-template-columns: repeat(auto-fit, 14rem);
3234
- grid-gap: ${({ theme }) => theme.spaces[1]};
3235
- `;
3236
- const ComponentBox = styledComponents.styled(designSystem.Flex)`
3237
- color: ${({ theme }) => theme.colors.neutral600};
3238
- cursor: pointer;
3239
-
3240
- @media (prefers-reduced-motion: no-preference) {
3241
- transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
3242
- }
3243
-
3244
- &:focus,
3245
- &:hover {
3246
- border: 1px solid ${({ theme }) => theme.colors.primary200};
3247
- background: ${({ theme }) => theme.colors.primary100};
3248
- color: ${({ theme }) => theme.colors.primary600};
3249
- }
3250
- `;
3251
- const ComponentPicker = ({
3252
- dynamicComponentsByCategory = {},
3253
- isOpen,
3254
- onClickAddComponent
3255
- }) => {
3256
- const { formatMessage } = reactIntl.useIntl();
3257
- const handleAddComponentToDz = (componentUid) => () => {
3258
- onClickAddComponent(componentUid);
3192
+ { componentName: label || name2 }
3193
+ );
3259
3194
  };
3260
- if (!isOpen) {
3261
- return null;
3262
- }
3263
- return /* @__PURE__ */ jsxRuntime.jsxs(
3264
- designSystem.Box,
3265
- {
3266
- paddingTop: 6,
3267
- paddingBottom: 6,
3268
- paddingLeft: 5,
3269
- paddingRight: 5,
3270
- background: "neutral0",
3271
- shadow: "tableShadow",
3272
- borderColor: "neutral150",
3273
- hasRadius: true,
3274
- children: [
3275
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral600", children: formatMessage({
3276
- id: index.getTranslation("components.DynamicZone.ComponentPicker-label"),
3277
- defaultMessage: "Pick one component"
3278
- }) }) }),
3279
- /* @__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(
3280
- ComponentCategory,
3281
- {
3282
- category,
3283
- components,
3284
- onAddComponent: handleAddComponentToDz,
3285
- variant: index2 % 2 === 1 ? "primary" : "secondary"
3286
- },
3287
- category
3288
- )) }) })
3289
- ]
3290
- }
3291
- );
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
+ ] }) });
3292
3262
  };
3293
3263
  const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3294
3264
  const { formatMessage } = reactIntl.useIntl();
@@ -3362,7 +3332,7 @@ const UIDInput = React__namespace.forwardRef(
3362
3332
  const [showRegenerate, setShowRegenerate] = React__namespace.useState(false);
3363
3333
  const isCloning = reactRouterDom.useMatch(index.CLONE_PATH) !== null;
3364
3334
  const field = strapiAdmin.useField(name2);
3365
- const debouncedValue = useDebounce.useDebounce(field.value, 300);
3335
+ const debouncedValue = relations.useDebounce(field.value, 300);
3366
3336
  const hasChanged = debouncedValue !== field.initialValue;
3367
3337
  const { toggleNotification } = strapiAdmin.useNotification();
3368
3338
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
@@ -4913,7 +4883,7 @@ const Wysiwyg = React__namespace.forwardRef(
4913
4883
  const handleSelectAssets = (files) => {
4914
4884
  const formattedFiles = files.map((f) => ({
4915
4885
  alt: f.alternativeText || f.name,
4916
- url: useDebounce.prefixFileUrlWithBackendUrl(f.url),
4886
+ url: usePrev.prefixFileUrlWithBackendUrl(f.url),
4917
4887
  mime: f.mime
4918
4888
  }));
4919
4889
  insertFile(editorRef, formattedFiles);
@@ -4969,626 +4939,680 @@ const Wysiwyg = React__namespace.forwardRef(
4969
4939
  /* @__PURE__ */ jsxRuntime.jsx(MediaLibraryDialog, { onClose: handleToggleMediaLib, onSelectAssets: handleSelectAssets })
4970
4940
  ] });
4971
4941
  }
4972
- );
4973
- const MemoizedWysiwyg = React__namespace.memo(Wysiwyg);
4974
- const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4975
- const { id, document: document2, collectionType } = index.useDoc();
4976
- const isFormDisabled = strapiAdmin.useForm("InputRenderer", (state) => state.disabled);
4977
- const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4978
- const canCreateFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4979
- const canReadFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4980
- const canUpdateFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4981
- const canUserAction = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4982
- let idToCheck = id;
4983
- if (collectionType === index.SINGLE_TYPES) {
4984
- idToCheck = document2?.documentId;
4942
+ );
4943
+ const MemoizedWysiwyg = React__namespace.memo(Wysiwyg);
4944
+ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4945
+ const { id, document: document2, collectionType } = index.useDoc();
4946
+ const isFormDisabled = strapiAdmin.useForm("InputRenderer", (state) => state.disabled);
4947
+ const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4948
+ const canCreateFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4949
+ const canReadFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4950
+ const canUpdateFields = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4951
+ const canUserAction = index.useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4952
+ let idToCheck = id;
4953
+ if (collectionType === index.SINGLE_TYPES) {
4954
+ idToCheck = document2?.documentId;
4955
+ }
4956
+ const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4957
+ const readableFields = idToCheck ? canReadFields : canCreateFields;
4958
+ const canUserReadField = canUserAction(props.name, readableFields, props.type);
4959
+ const canUserEditField = canUserAction(props.name, editableFields, props.type);
4960
+ const fields = strapiAdmin.useStrapiApp("InputRenderer", (app) => app.fields);
4961
+ const { lazyComponentStore } = useLazyComponents(
4962
+ attributeHasCustomFieldProperty(props.attribute) ? [props.attribute.customField] : void 0
4963
+ );
4964
+ const hint = useFieldHint(providedHint, props.attribute);
4965
+ const {
4966
+ edit: { components }
4967
+ } = index.useDocLayout();
4968
+ const field = strapiAdmin.useField(props.name);
4969
+ if (!visible) {
4970
+ return null;
4971
+ }
4972
+ if (!canUserReadField && !isInDynamicZone) {
4973
+ return /* @__PURE__ */ jsxRuntime.jsx(NotAllowedInput, { hint, ...props });
4974
+ }
4975
+ const fieldIsDisabled = !canUserEditField && !isInDynamicZone || props.disabled || isFormDisabled;
4976
+ if (attributeHasCustomFieldProperty(props.attribute)) {
4977
+ const CustomInput = lazyComponentStore[props.attribute.customField];
4978
+ if (CustomInput) {
4979
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
4980
+ }
4981
+ return /* @__PURE__ */ jsxRuntime.jsx(
4982
+ strapiAdmin.InputRenderer,
4983
+ {
4984
+ ...props,
4985
+ hint,
4986
+ type: props.attribute.customField,
4987
+ disabled: fieldIsDisabled
4988
+ }
4989
+ );
4990
+ }
4991
+ const addedInputTypes = Object.keys(fields);
4992
+ if (!attributeHasCustomFieldProperty(props.attribute) && addedInputTypes.includes(props.type)) {
4993
+ const CustomInput = fields[props.type];
4994
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
4995
+ }
4996
+ switch (props.type) {
4997
+ case "blocks":
4998
+ return /* @__PURE__ */ jsxRuntime.jsx(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4999
+ case "component":
5000
+ return /* @__PURE__ */ jsxRuntime.jsx(
5001
+ MemoizedComponentInput,
5002
+ {
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;
4985
5048
  }
4986
- const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4987
- const readableFields = idToCheck ? canReadFields : canCreateFields;
4988
- const canUserReadField = canUserAction(props.name, readableFields, props.type);
4989
- const canUserEditField = canUserAction(props.name, editableFields, props.type);
4990
- const fields = strapiAdmin.useStrapiApp("InputRenderer", (app) => app.fields);
4991
- const { lazyComponentStore } = useLazyComponents(
4992
- attributeHasCustomFieldProperty(props.attribute) ? [props.attribute.customField] : void 0
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
+ }
4993
5077
  );
4994
- const hint = useFieldHint(providedHint, props.attribute);
4995
- const {
4996
- edit: { components }
4997
- } = index.useDocLayout();
4998
- const field = strapiAdmin.useField(props.name);
4999
- if (!visible) {
5000
- return null;
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 };
5001
5089
  }
5002
- if (!canUserReadField && !isInDynamicZone) {
5003
- return /* @__PURE__ */ jsxRuntime.jsx(NotAllowedInput, { hint, ...props });
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};`}
5004
5104
  }
5005
- const fieldIsDisabled = !canUserEditField && !isInDynamicZone || props.disabled || isFormDisabled;
5006
- if (attributeHasCustomFieldProperty(props.attribute)) {
5007
- const CustomInput = lazyComponentStore[props.attribute.customField];
5008
- if (CustomInput) {
5009
- return /* @__PURE__ */ jsxRuntime.jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
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);
5010
5121
  }
5011
5122
  return /* @__PURE__ */ jsxRuntime.jsx(
5012
- strapiAdmin.InputRenderer,
5123
+ designSystem.Box,
5013
5124
  {
5014
- ...props,
5015
- hint,
5016
- type: props.attribute.customField,
5017
- disabled: fieldIsDisabled
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__;
5018
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)
5297
+ }
5298
+ )
5019
5299
  );
5020
- }
5021
- const addedInputTypes = Object.keys(fields);
5022
- if (!attributeHasCustomFieldProperty(props.attribute) && addedInputTypes.includes(props.type)) {
5023
- const CustomInput = fields[props.type];
5024
- return /* @__PURE__ */ jsxRuntime.jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
5025
- }
5026
- switch (props.type) {
5027
- case "blocks":
5028
- return /* @__PURE__ */ jsxRuntime.jsx(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5029
- case "component":
5030
- return /* @__PURE__ */ jsxRuntime.jsx(
5031
- MemoizedComponentInput,
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(
5032
5309
  {
5033
- ...props,
5034
- hint,
5035
- layout: components[props.attribute.component].layout,
5036
- disabled: fieldIsDisabled,
5037
- children: (inputProps) => /* @__PURE__ */ jsxRuntime.jsx(InputRenderer, { ...inputProps })
5310
+ id: index.getTranslation("dnd.cancel-item"),
5311
+ defaultMessage: "{item}, dropped. Re-order cancelled."
5312
+ },
5313
+ {
5314
+ item: `${name2}.${index$1}`
5038
5315
  }
5039
- );
5040
- case "dynamiczone":
5041
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
5042
- case "relation":
5043
- return /* @__PURE__ */ jsxRuntime.jsx(Relations.MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
5044
- case "richtext":
5045
- return /* @__PURE__ */ jsxRuntime.jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5046
- case "uid":
5047
- return /* @__PURE__ */ jsxRuntime.jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
5048
- case "enumeration":
5049
- return /* @__PURE__ */ jsxRuntime.jsx(
5050
- strapiAdmin.InputRenderer,
5316
+ )
5317
+ );
5318
+ };
5319
+ const handleGrabItem = (index$1) => {
5320
+ setLiveText(
5321
+ formatMessage(
5051
5322
  {
5052
- ...props,
5053
- hint,
5054
- options: props.attribute.enum.map((value) => ({ value })),
5055
- type: props.customField ? "custom-field" : props.type,
5056
- 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)
5057
5329
  }
5058
- );
5059
- default:
5060
- const { unique: _unique, mainField: _mainField, ...restProps } = props;
5061
- return /* @__PURE__ */ jsxRuntime.jsx(
5062
- strapiAdmin.InputRenderer,
5330
+ )
5331
+ );
5332
+ };
5333
+ const handleDropItem = (index$1) => {
5334
+ setLiveText(
5335
+ formatMessage(
5063
5336
  {
5064
- ...restProps,
5065
- hint,
5066
- type: props.customField ? "custom-field" : props.type,
5067
- disabled: fieldIsDisabled
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)
5068
5343
  }
5069
- );
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 });
5070
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
+ ] });
5071
5432
  };
5072
- const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5073
- const useFieldHint = (hint = void 0, attribute) => {
5074
- const { formatMessage } = reactIntl.useIntl();
5075
- const { maximum, minimum } = getMinMax(attribute);
5076
- if (!maximum && !minimum) {
5077
- return hint;
5078
- }
5079
- const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5080
- attribute.type
5081
- ) ? formatMessage(
5082
- {
5083
- id: "content-manager.form.Input.hint.character.unit",
5084
- defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5085
- },
5086
- {
5087
- maxValue: Math.max(minimum || 0, maximum || 0)
5088
- }
5089
- ) : null;
5090
- const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5091
- return formatMessage(
5092
- {
5093
- id: "content-manager.form.Input.hint.text",
5094
- defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5095
- },
5096
- {
5097
- min: minimum,
5098
- max: maximum,
5099
- description: hint,
5100
- unit: units,
5101
- divider: hasMinAndMax ? formatMessage({
5102
- id: "content-manager.form.Input.hint.minMaxDivider",
5103
- defaultMessage: " / "
5104
- }) : null,
5105
- 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};
5106
5450
  }
5107
- );
5108
- };
5109
- const getMinMax = (attribute) => {
5110
- if ("min" in attribute || "max" in attribute) {
5111
- return {
5112
- maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5113
- minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5114
- };
5115
- } else if ("maxLength" in attribute || "minLength" in attribute) {
5116
- return { maximum: attribute.maxLength, minimum: attribute.minLength };
5117
- } else {
5118
- return { maximum: void 0, minimum: void 0 };
5119
5451
  }
5120
- };
5121
- const MemoizedInputRenderer = React.memo(InputRenderer);
5122
- const DynamicComponent = ({
5123
- 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 = ({
5124
5464
  disabled,
5125
5465
  index: index$1,
5126
5466
  name: name2,
5127
- onRemoveComponentClick,
5128
- onMoveComponent,
5129
- onGrabItem,
5130
- onDropItem,
5131
- onCancel,
5132
- dynamicComponentsByCategory = {},
5133
- onAddComponent
5467
+ mainField = {
5468
+ name: "id",
5469
+ type: "integer"
5470
+ },
5471
+ children,
5472
+ onDeleteComponent,
5473
+ toggleCollapses,
5474
+ __temp_key__,
5475
+ ...dragProps
5134
5476
  }) => {
5135
5477
  const { formatMessage } = reactIntl.useIntl();
5136
- const formValues = strapiAdmin.useForm("DynamicComponent", (state) => state.values);
5137
- const {
5138
- edit: { components }
5139
- } = index.useDocLayout();
5140
- const title = React__namespace.useMemo(() => {
5141
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
5142
- const mainFieldValue = objects.getIn(formValues, `${name2}.${index$1}.${mainField}`);
5143
- const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
5144
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
5145
- return mainValue;
5146
- }, [componentUid, components, formValues, name2, index$1]);
5147
- const { icon, displayName } = React__namespace.useMemo(() => {
5148
- const [category] = componentUid.split(".");
5149
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
5150
- (component) => component.uid === componentUid
5151
- ) ?? { icon: null, displayName: null };
5152
- return { icon: icon2, displayName: displayName2 };
5153
- }, [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(".");
5154
5483
  const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(!disabled, {
5155
- type: `${useDragAndDrop.ItemTypes.DYNAMIC_ZONE}_${name2}`,
5484
+ type: `${useDragAndDrop.ItemTypes.COMPONENT}_${componentKey}`,
5156
5485
  index: index$1,
5157
5486
  item: {
5158
5487
  index: index$1,
5159
- displayedValue: `${displayName} ${title}`,
5160
- icon
5488
+ displayedValue: displayValue
5161
5489
  },
5162
- onMoveItem: onMoveComponent,
5163
- onDropItem,
5164
- onGrabItem,
5165
- onCancel
5490
+ onStart() {
5491
+ toggleCollapses();
5492
+ },
5493
+ ...dragProps
5166
5494
  });
5167
5495
  React__namespace.useEffect(() => {
5168
5496
  dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
5169
5497
  }, [dragPreviewRef, index$1]);
5170
- const accordionValue = React__namespace.useId();
5171
- const { value = [], rawError } = strapiAdmin.useField(`${name2}.${index$1}`);
5172
- const [collapseToOpen, setCollapseToOpen] = React__namespace.useState("");
5173
- React__namespace.useEffect(() => {
5174
- if (rawError && value) {
5175
- setCollapseToOpen(accordionValue);
5176
- }
5177
- }, [rawError, value, accordionValue]);
5178
- const composedBoxRefs = designSystem.useComposedRefs(boxRef, dropRef);
5179
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5180
- /* @__PURE__ */ jsxRuntime.jsx(
5181
- designSystem.IconButton,
5182
- {
5183
- variant: "ghost",
5184
- 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,
5185
5509
  {
5186
- id: index.getTranslation("components.DynamicZone.delete-label"),
5187
- defaultMessage: "Delete {name}"
5188
- },
5189
- { 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
+ }
5190
5518
  ),
5191
- onClick: onRemoveComponentClick,
5192
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {})
5193
- }
5194
- ),
5195
- /* @__PURE__ */ jsxRuntime.jsx(
5196
- designSystem.IconButton,
5197
- {
5198
- variant: "ghost",
5199
- onClick: (e) => e.stopPropagation(),
5200
- "data-handler-id": handlerId,
5201
- ref: dragRef,
5202
- label: formatMessage({
5203
- id: index.getTranslation("components.DragHandle-label"),
5204
- defaultMessage: "Drag"
5205
- }),
5206
- onKeyDown: handleKeyDown,
5207
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Drag, {})
5208
- }
5209
- ),
5210
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
5211
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
5212
- /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
5213
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage({
5214
- id: index.getTranslation("components.DynamicZone.more-actions"),
5215
- defaultMessage: "More actions"
5216
- }) })
5217
- ] }),
5218
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { children: [
5219
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
5220
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
5221
- id: index.getTranslation("components.DynamicZone.add-item-above"),
5222
- defaultMessage: "Add component above"
5223
- }) }),
5224
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
5225
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
5226
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1), children: displayName2 }, componentUid))
5227
- ] }, category)) })
5228
- ] }),
5229
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
5230
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubTrigger, { children: formatMessage({
5231
- id: index.getTranslation("components.DynamicZone.add-item-below"),
5232
- defaultMessage: "Add component below"
5233
- }) }),
5234
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
5235
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Label, { children: category }),
5236
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onSelect: () => onAddComponent(uid, index$1 + 1), children: displayName2 }, componentUid))
5237
- ] }, category)) })
5238
- ] })
5239
- ] })
5240
- ] })
5241
- ] });
5242
- const accordionTitle = title ? `${displayName} ${title}` : displayName;
5243
- return /* @__PURE__ */ jsxRuntime.jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
5244
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Rectangle, { background: "neutral200" }) }),
5245
- /* @__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: [
5246
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
5247
5519
  /* @__PURE__ */ jsxRuntime.jsx(
5248
- designSystem.Accordion.Trigger,
5520
+ designSystem.IconButton,
5249
5521
  {
5250
- icon: icon && ComponentIcon.COMPONENT_ICONS[icon] ? ComponentIcon.COMPONENT_ICONS[icon] : ComponentIcon.COMPONENT_ICONS.dashboard,
5251
- 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, {})
5252
5532
  }
5253
- ),
5254
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Actions, { children: accordionActions })
5255
- ] }),
5256
- /* @__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(
5257
- designSystem.Grid.Item,
5258
- {
5259
- col: 12,
5260
- s: 12,
5261
- xs: 12,
5262
- direction: "column",
5263
- alignItems: "stretch",
5264
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: row.map(({ size, ...field }) => {
5265
- const fieldName = `${name2}.${index$1}.${field.name}`;
5266
- const fieldWithTranslatedLabel = {
5267
- ...field,
5268
- label: formatMessage({
5269
- id: `content-manager.components.${componentUid}.${field.name}`,
5270
- defaultMessage: field.label
5271
- })
5272
- };
5273
- return /* @__PURE__ */ jsxRuntime.jsx(
5274
- designSystem.Grid.Item,
5275
- {
5276
- col: size,
5277
- s: 12,
5278
- xs: 12,
5279
- direction: "column",
5280
- alignItems: "stretch",
5281
- children: /* @__PURE__ */ jsxRuntime.jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
5282
- },
5283
- fieldName
5284
- );
5285
- }) })
5286
- },
5287
- rowInd
5288
- )) }) }) }) })
5289
- ] }) }) })
5290
- ] });
5291
- };
5292
- const StyledBox = styledComponents.styled(designSystem.Box)`
5293
- > div:first-child {
5294
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5295
- }
5296
- `;
5297
- const AccordionContentRadius = styledComponents.styled(designSystem.Box)`
5298
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5299
- `;
5300
- const Rectangle = styledComponents.styled(designSystem.Box)`
5301
- width: ${({ theme }) => theme.spaces[2]};
5302
- height: ${({ theme }) => theme.spaces[4]};
5303
- `;
5304
- const Preview = styledComponents.styled.span`
5305
- display: block;
5306
- background-color: ${({ theme }) => theme.colors.primary100};
5307
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5308
- outline-offset: -1px;
5309
- padding: ${({ theme }) => theme.spaces[6]};
5310
- `;
5311
- const ComponentContainer = styledComponents.styled(designSystem.Box)`
5312
- list-style: none;
5313
- padding: 0;
5314
- margin: 0;
5315
- `;
5316
- const DynamicZoneLabel = ({
5317
- hint,
5318
- label,
5319
- labelAction,
5320
- name: name2,
5321
- numberOfComponents = 0,
5322
- required
5323
- }) => {
5324
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
5325
- designSystem.Box,
5326
- {
5327
- paddingTop: 3,
5328
- paddingBottom: 3,
5329
- paddingRight: 4,
5330
- paddingLeft: 4,
5331
- borderRadius: "26px",
5332
- background: "neutral0",
5333
- shadow: "filterShadow",
5334
- color: "neutral500",
5335
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", justifyContent: "center", children: [
5336
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { maxWidth: "35.6rem", children: [
5337
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5338
- label || name2,
5339
- " "
5340
- ] }),
5341
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5342
- "(",
5343
- numberOfComponents,
5344
- ")"
5345
- ] }),
5346
- required && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: "*" }),
5347
- labelAction && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 1, children: labelAction })
5348
- ] }),
5349
- 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
+ )
5350
5534
  ] })
5351
- }
5352
- ) });
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" });
5353
5551
  };
5354
- const [DynamicZoneProvider, useDynamicZone] = strapiAdmin.createContext(
5355
- "DynamicZone",
5356
- {
5357
- isInDynamicZone: false
5358
- }
5359
- );
5360
- const DynamicZone = ({
5361
- attribute,
5362
- disabled: disabledProp,
5363
- hint,
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 = ({
5364
5558
  label,
5365
- labelAction,
5559
+ required,
5366
5560
  name: name2,
5367
- required = false
5561
+ attribute,
5562
+ disabled,
5563
+ labelAction,
5564
+ ...props
5368
5565
  }) => {
5369
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5370
- const [addComponentIsOpen, setAddComponentIsOpen] = React__namespace.useState(false);
5371
- const [liveText, setLiveText] = React__namespace.useState("");
5372
- const { components, isLoading } = index.useDoc();
5373
- const disabled = disabledProp || isLoading;
5374
- const { addFieldRow, removeFieldRow, moveFieldRow } = strapiAdmin.useForm(
5375
- "DynamicZone",
5376
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5377
- addFieldRow: addFieldRow2,
5378
- removeFieldRow: removeFieldRow2,
5379
- moveFieldRow: moveFieldRow2
5380
- })
5381
- );
5382
- const { value = [], error } = strapiAdmin.useField(name2);
5383
- const dynamicComponentsByCategory = React__namespace.useMemo(() => {
5384
- return attribute.components.reduce((acc, componentUid) => {
5385
- const { category, info } = components[componentUid] ?? { info: {} };
5386
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5387
- if (!acc[category]) {
5388
- acc[category] = [];
5389
- }
5390
- acc[category] = [...acc[category], component];
5391
- return acc;
5392
- }, {});
5393
- }, [attribute.components, components]);
5394
5566
  const { formatMessage } = reactIntl.useIntl();
5395
- const { toggleNotification } = strapiAdmin.useNotification();
5396
- const dynamicDisplayedComponentsLength = value.length;
5397
- const handleAddComponent = (uid, position) => {
5398
- setAddComponentIsOpen(false);
5399
- const schema = components[uid];
5400
- const form = createDefaultForm(schema, components);
5401
- const transformations = pipe__default.default(transformDocument(schema, components), (data2) => ({
5402
- ...data2,
5403
- __component: uid
5404
- }));
5405
- const data = transformations(form);
5406
- addFieldRow(name2, data, position);
5407
- };
5408
- const handleClickOpenPicker = () => {
5409
- if (dynamicDisplayedComponentsLength < max) {
5410
- setAddComponentIsOpen((prev) => !prev);
5411
- } else {
5412
- toggleNotification({
5413
- type: "info",
5414
- message: formatMessage({
5415
- id: index.getTranslation("components.notification.info.maximum-requirement")
5416
- })
5417
- });
5418
- }
5419
- };
5420
- const handleMoveComponent = (newIndex, currentIndex) => {
5421
- setLiveText(
5422
- formatMessage(
5423
- {
5424
- id: index.getTranslation("dnd.reorder"),
5425
- defaultMessage: "{item}, moved. New position in list: {position}."
5426
- },
5427
- {
5428
- item: `${name2}.${currentIndex}`,
5429
- position: getItemPos(newIndex)
5430
- }
5431
- )
5432
- );
5433
- moveFieldRow(name2, currentIndex, newIndex);
5434
- };
5435
- const getItemPos = (index2) => `${index2 + 1} of ${value.length}`;
5436
- const handleCancel = (index$1) => {
5437
- setLiveText(
5438
- formatMessage(
5439
- {
5440
- id: index.getTranslation("dnd.cancel-item"),
5441
- defaultMessage: "{item}, dropped. Re-order cancelled."
5442
- },
5443
- {
5444
- item: `${name2}.${index$1}`
5445
- }
5446
- )
5447
- );
5448
- };
5449
- const handleGrabItem = (index$1) => {
5450
- setLiveText(
5451
- formatMessage(
5452
- {
5453
- id: index.getTranslation("dnd.grab-item"),
5454
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
5455
- },
5456
- {
5457
- item: `${name2}.${index$1}`,
5458
- position: getItemPos(index$1)
5459
- }
5460
- )
5461
- );
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);
5462
5575
  };
5463
- const handleDropItem = (index$1) => {
5464
- setLiveText(
5465
- formatMessage(
5466
- {
5467
- id: index.getTranslation("dnd.drop-item"),
5468
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
5469
- },
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,
5470
5588
  {
5471
- item: `${name2}.${index$1}`,
5472
- 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, {})
5473
5598
  }
5474
5599
  )
5475
- );
5476
- };
5477
- const handleRemoveComponent = (name22, currentIndex) => () => {
5478
- removeFieldRow(name22, currentIndex);
5479
- };
5480
- const hasError = error !== void 0;
5481
- const renderButtonLabel = () => {
5482
- if (addComponentIsOpen) {
5483
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5484
- }
5485
- if (hasError && dynamicDisplayedComponentsLength > max) {
5486
- return formatMessage(
5487
- {
5488
- id: index.getTranslation(`components.DynamicZone.extra-components`),
5489
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5490
- },
5491
- {
5492
- number: dynamicDisplayedComponentsLength - max
5493
- }
5494
- );
5495
- }
5496
- if (hasError && dynamicDisplayedComponentsLength < min) {
5497
- return formatMessage(
5498
- {
5499
- id: index.getTranslation(`components.DynamicZone.missing-components`),
5500
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5501
- },
5502
- { number: min - dynamicDisplayedComponentsLength }
5503
- );
5504
- }
5505
- return formatMessage(
5506
- {
5507
- id: index.getTranslation("components.DynamicZone.add-component"),
5508
- defaultMessage: "Add a component to {componentName}"
5509
- },
5510
- { componentName: label || name2 }
5511
- );
5512
- };
5513
- const level = Relations.useComponent("DynamicZone", (state) => state.level);
5514
- const ariaDescriptionId = React__namespace.useId();
5515
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5516
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
5517
- /* @__PURE__ */ jsxRuntime.jsx(
5518
- DynamicZoneLabel,
5519
- {
5520
- hint,
5521
- label,
5522
- labelAction,
5523
- name: name2,
5524
- numberOfComponents: dynamicDisplayedComponentsLength,
5525
- required
5526
- }
5527
- ),
5528
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5529
- id: index.getTranslation("dnd.instructions"),
5530
- defaultMessage: `Press spacebar to grab and re-order`
5531
- }) }),
5532
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5533
- /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index2) => /* @__PURE__ */ jsxRuntime.jsx(
5534
- Relations.ComponentProvider,
5535
- {
5536
- level: level + 1,
5537
- uid: field.__component,
5538
- id: field.id,
5539
- type: "dynamiczone",
5540
- children: /* @__PURE__ */ jsxRuntime.jsx(
5541
- DynamicComponent,
5542
- {
5543
- disabled,
5544
- name: name2,
5545
- index: index2,
5546
- componentUid: field.__component,
5547
- onMoveComponent: handleMoveComponent,
5548
- onRemoveComponentClick: handleRemoveComponent(name2, index2),
5549
- onCancel: handleCancel,
5550
- onDropItem: handleDropItem,
5551
- onGrabItem: handleGrabItem,
5552
- onAddComponent: handleAddComponent,
5553
- dynamicComponentsByCategory
5554
- }
5555
- )
5556
- },
5557
- field.__temp_key__
5558
- )) })
5559
5600
  ] }),
5560
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
5561
- AddComponentButton,
5562
- {
5563
- hasError,
5564
- isDisabled: disabled,
5565
- isOpen: addComponentIsOpen,
5566
- onClick: handleClickOpenPicker,
5567
- children: renderButtonLabel()
5568
- }
5569
- ) }),
5570
- /* @__PURE__ */ jsxRuntime.jsx(
5571
- ComponentPicker,
5572
- {
5573
- dynamicComponentsByCategory,
5574
- isOpen: addComponentIsOpen,
5575
- onClickAddComponent: handleAddComponent
5576
- }
5577
- )
5578
- ] }) });
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
+ ] });
5579
5606
  };
5607
+ const MemoizedComponentInput = React__namespace.memo(ComponentInput);
5580
5608
  exports.DynamicZone = DynamicZone;
5609
+ exports.FormLayout = FormLayout;
5581
5610
  exports.MemoizedBlocksInput = MemoizedBlocksInput;
5582
5611
  exports.MemoizedComponentInput = MemoizedComponentInput;
5583
- exports.MemoizedInputRenderer = MemoizedInputRenderer;
5584
5612
  exports.MemoizedUIDInput = MemoizedUIDInput;
5585
5613
  exports.MemoizedWysiwyg = MemoizedWysiwyg;
5586
5614
  exports.NotAllowedInput = NotAllowedInput;
5587
- exports.createDefaultForm = createDefaultForm;
5588
- exports.prepareTempKeys = prepareTempKeys;
5589
- exports.removeFieldsThatDontExistOnSchema = removeFieldsThatDontExistOnSchema;
5590
- exports.transformDocument = transformDocument;
5591
5615
  exports.useDynamicZone = useDynamicZone;
5592
5616
  exports.useFieldHint = useFieldHint;
5593
5617
  exports.useLazyComponents = useLazyComponents;
5594
- //# sourceMappingURL=Field-DwvmENVf.js.map
5618
+ //# sourceMappingURL=Input-CDHKQd7o.js.map