@strapi/content-manager 0.0.0-experimental.17b4116f461a49b8ce5386f7c8d79c511d40fb3b → 0.0.0-experimental.19d775295eb622de3e659110caf22fcd2cd5d10d

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 (264) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
  3. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
  4. package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
  5. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
  6. package/dist/_chunks/{ComponentConfigurationPage-DjQBdcKF.mjs → ComponentConfigurationPage-B_99pmC0.mjs} +4 -4
  7. package/dist/_chunks/{ComponentConfigurationPage-DjQBdcKF.mjs.map → ComponentConfigurationPage-B_99pmC0.mjs.map} +1 -1
  8. package/dist/_chunks/{ComponentConfigurationPage-2iOVVhqV.js → ComponentConfigurationPage-NeMPjY5M.js} +5 -6
  9. package/dist/_chunks/{ComponentConfigurationPage-2iOVVhqV.js.map → ComponentConfigurationPage-NeMPjY5M.js.map} +1 -1
  10. package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-CRbtQEUV.js} +9 -4
  11. package/dist/_chunks/ComponentIcon-CRbtQEUV.js.map +1 -0
  12. package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
  13. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
  14. package/dist/_chunks/{EditConfigurationPage-BoBb-DLH.mjs → EditConfigurationPage-B0kNlNoj.mjs} +4 -4
  15. package/dist/_chunks/{EditConfigurationPage-BoBb-DLH.mjs.map → EditConfigurationPage-B0kNlNoj.mjs.map} +1 -1
  16. package/dist/_chunks/{EditConfigurationPage-B7dw5_cS.js → EditConfigurationPage-n7_xHayb.js} +5 -6
  17. package/dist/_chunks/{EditConfigurationPage-B7dw5_cS.js.map → EditConfigurationPage-n7_xHayb.js.map} +1 -1
  18. package/dist/_chunks/EditViewPage-BT7Achc-.js +209 -0
  19. package/dist/_chunks/EditViewPage-BT7Achc-.js.map +1 -0
  20. package/dist/_chunks/EditViewPage-DYXZs4_2.mjs +191 -0
  21. package/dist/_chunks/EditViewPage-DYXZs4_2.mjs.map +1 -0
  22. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  23. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  24. package/dist/_chunks/{Form-CQ67ZifP.js → Form-BRmk2Dp3.js} +68 -49
  25. package/dist/_chunks/Form-BRmk2Dp3.js.map +1 -0
  26. package/dist/_chunks/{Form-Jgh5hGTu.mjs → Form-D3paRF1F.mjs} +67 -46
  27. package/dist/_chunks/Form-D3paRF1F.mjs.map +1 -0
  28. package/dist/_chunks/{History-BLEnudTX.js → History-BQpDoOu8.js} +211 -148
  29. package/dist/_chunks/History-BQpDoOu8.js.map +1 -0
  30. package/dist/_chunks/{History-DKhZAPcK.mjs → History-CzQbTOwa.mjs} +204 -139
  31. package/dist/_chunks/History-CzQbTOwa.mjs.map +1 -0
  32. package/dist/_chunks/{Field-kVFO4ZKB.mjs → Input-ww3KFYZr.mjs} +1996 -1730
  33. package/dist/_chunks/Input-ww3KFYZr.mjs.map +1 -0
  34. package/dist/_chunks/{Field-kq1c2TF1.js → Input-yM6HnyQa.js} +2035 -1770
  35. package/dist/_chunks/Input-yM6HnyQa.js.map +1 -0
  36. package/dist/_chunks/{ListConfigurationPage-Zso_LUjn.js → ListConfigurationPage-B6NsS-0m.js} +72 -63
  37. package/dist/_chunks/ListConfigurationPage-B6NsS-0m.js.map +1 -0
  38. package/dist/_chunks/{ListConfigurationPage-nrXcxNYi.mjs → ListConfigurationPage-Bbw8w5cS.mjs} +68 -57
  39. package/dist/_chunks/ListConfigurationPage-Bbw8w5cS.mjs.map +1 -0
  40. package/dist/_chunks/{ListViewPage-ChhYmA-L.mjs → ListViewPage-DnOP55pM.mjs} +179 -160
  41. package/dist/_chunks/ListViewPage-DnOP55pM.mjs.map +1 -0
  42. package/dist/_chunks/{ListViewPage-DsaOakWQ.js → ListViewPage-Dt8OUTwO.js} +183 -165
  43. package/dist/_chunks/ListViewPage-Dt8OUTwO.js.map +1 -0
  44. package/dist/_chunks/{NoContentTypePage-BrdFcN33.mjs → NoContentTypePage-CXKXHNMa.mjs} +3 -3
  45. package/dist/_chunks/NoContentTypePage-CXKXHNMa.mjs.map +1 -0
  46. package/dist/_chunks/{NoContentTypePage-DPCuS9Y1.js → NoContentTypePage-Dgm-uj-6.js} +3 -3
  47. package/dist/_chunks/NoContentTypePage-Dgm-uj-6.js.map +1 -0
  48. package/dist/_chunks/{NoPermissionsPage-DdyOfdKb.js → NoPermissionsPage-CLbU5SOt.js} +2 -2
  49. package/dist/_chunks/{NoPermissionsPage-DdyOfdKb.js.map → NoPermissionsPage-CLbU5SOt.js.map} +1 -1
  50. package/dist/_chunks/{NoPermissionsPage-B9dqrtTy.mjs → NoPermissionsPage-kaj1rPiW.mjs} +2 -2
  51. package/dist/_chunks/{NoPermissionsPage-B9dqrtTy.mjs.map → NoPermissionsPage-kaj1rPiW.mjs.map} +1 -1
  52. package/dist/_chunks/Preview-Bieh13Ro.mjs +287 -0
  53. package/dist/_chunks/Preview-Bieh13Ro.mjs.map +1 -0
  54. package/dist/_chunks/Preview-CbXHXqBg.js +305 -0
  55. package/dist/_chunks/Preview-CbXHXqBg.js.map +1 -0
  56. package/dist/_chunks/{Relations-DjFiYd7-.mjs → Relations-7rWJcZ3_.mjs} +138 -94
  57. package/dist/_chunks/Relations-7rWJcZ3_.mjs.map +1 -0
  58. package/dist/_chunks/{Relations-CY8Isqdu.js → Relations-CvifV6Y6.js} +142 -100
  59. package/dist/_chunks/Relations-CvifV6Y6.js.map +1 -0
  60. package/dist/_chunks/{en-C-V1_90f.js → en-BR48D_RH.js} +45 -18
  61. package/dist/_chunks/{en-C-V1_90f.js.map → en-BR48D_RH.js.map} +1 -1
  62. package/dist/_chunks/{en-MBPul9Su.mjs → en-D65uIF6Y.mjs} +45 -18
  63. package/dist/_chunks/{en-MBPul9Su.mjs.map → en-D65uIF6Y.mjs.map} +1 -1
  64. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  65. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  66. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  67. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  68. package/dist/_chunks/{fr-B7kGGg3E.js → fr-C43IbhA_.js} +16 -3
  69. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-C43IbhA_.js.map} +1 -1
  70. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr-DBseuRuB.mjs} +16 -3
  71. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  72. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  73. package/dist/_chunks/{index-CAc9yTnx.mjs → index-BH2JnYpF.mjs} +2302 -995
  74. package/dist/_chunks/index-BH2JnYpF.mjs.map +1 -0
  75. package/dist/_chunks/{index-DNa1J4HE.js → index-DkJQjlak.js} +2273 -967
  76. package/dist/_chunks/index-DkJQjlak.js.map +1 -0
  77. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  78. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  79. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  80. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  81. package/dist/_chunks/{layout-BqtLA6Lb.js → layout-4BqLFW_b.js} +47 -32
  82. package/dist/_chunks/layout-4BqLFW_b.js.map +1 -0
  83. package/dist/_chunks/{layout-CXsHbc3E.mjs → layout-bbOlPwLA.mjs} +46 -28
  84. package/dist/_chunks/layout-bbOlPwLA.mjs.map +1 -0
  85. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  86. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  87. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  88. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  89. package/dist/_chunks/{relations-mMFEcZRq.mjs → relations-HsflnFpO.mjs} +6 -7
  90. package/dist/_chunks/relations-HsflnFpO.mjs.map +1 -0
  91. package/dist/_chunks/{relations-BHY_KDJ_.js → relations-Yc0Z6A20.js} +6 -7
  92. package/dist/_chunks/relations-Yc0Z6A20.js.map +1 -0
  93. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  94. package/dist/_chunks/useDragAndDrop-BMtgCYzL.js.map +1 -0
  95. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  96. package/dist/_chunks/useDragAndDrop-DJ6jqvZN.mjs.map +1 -0
  97. package/dist/_chunks/usePrev-CZGy2Vjf.mjs +29 -0
  98. package/dist/_chunks/usePrev-CZGy2Vjf.mjs.map +1 -0
  99. package/dist/_chunks/usePrev-D5J_2fEu.js +28 -0
  100. package/dist/_chunks/usePrev-D5J_2fEu.js.map +1 -0
  101. package/dist/admin/index.js +4 -1
  102. package/dist/admin/index.js.map +1 -1
  103. package/dist/admin/index.mjs +10 -7
  104. package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
  105. package/dist/admin/src/content-manager.d.ts +7 -5
  106. package/dist/admin/src/exports.d.ts +3 -1
  107. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
  108. package/dist/admin/src/history/index.d.ts +3 -0
  109. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  110. package/dist/admin/src/hooks/useDocument.d.ts +54 -9
  111. package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
  112. package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
  113. package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
  114. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  115. package/dist/admin/src/index.d.ts +1 -0
  116. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  117. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +12 -5
  118. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
  119. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  120. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  121. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
  122. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +5 -0
  123. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
  124. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
  125. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  126. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  127. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
  128. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
  129. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
  130. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
  131. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  132. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +16 -53
  133. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  134. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  135. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
  136. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  137. package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
  138. package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
  139. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
  140. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  141. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  142. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  143. package/dist/admin/src/preview/index.d.ts +4 -0
  144. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  145. package/dist/admin/src/preview/routes.d.ts +3 -0
  146. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  147. package/dist/admin/src/router.d.ts +1 -1
  148. package/dist/admin/src/services/api.d.ts +2 -3
  149. package/dist/admin/src/services/components.d.ts +2 -2
  150. package/dist/admin/src/services/contentTypes.d.ts +5 -5
  151. package/dist/admin/src/services/documents.d.ts +31 -20
  152. package/dist/admin/src/services/init.d.ts +2 -2
  153. package/dist/admin/src/services/relations.d.ts +3 -3
  154. package/dist/admin/src/services/uid.d.ts +3 -3
  155. package/dist/admin/src/utils/api.d.ts +4 -18
  156. package/dist/admin/src/utils/validation.d.ts +5 -7
  157. package/dist/server/index.js +959 -543
  158. package/dist/server/index.js.map +1 -1
  159. package/dist/server/index.mjs +960 -543
  160. package/dist/server/index.mjs.map +1 -1
  161. package/dist/server/src/bootstrap.d.ts.map +1 -1
  162. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  163. package/dist/server/src/controllers/index.d.ts.map +1 -1
  164. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  165. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  166. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  167. package/dist/server/src/controllers/utils/metadata.d.ts +23 -0
  168. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
  169. package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
  170. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
  171. package/dist/server/src/controllers/validation/index.d.ts +1 -1
  172. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  173. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  174. package/dist/server/src/history/services/history.d.ts +3 -3
  175. package/dist/server/src/history/services/history.d.ts.map +1 -1
  176. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  177. package/dist/server/src/history/services/utils.d.ts +8 -12
  178. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  179. package/dist/server/src/index.d.ts +21 -36
  180. package/dist/server/src/index.d.ts.map +1 -1
  181. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  182. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  183. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  184. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  185. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  186. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  187. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  188. package/dist/server/src/preview/index.d.ts +4 -0
  189. package/dist/server/src/preview/index.d.ts.map +1 -0
  190. package/dist/server/src/preview/routes/index.d.ts +8 -0
  191. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  192. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  193. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  194. package/dist/server/src/preview/services/index.d.ts +16 -0
  195. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  196. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  197. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  198. package/dist/server/src/preview/services/preview.d.ts +12 -0
  199. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  200. package/dist/server/src/preview/utils.d.ts +19 -0
  201. package/dist/server/src/preview/utils.d.ts.map +1 -0
  202. package/dist/server/src/register.d.ts.map +1 -1
  203. package/dist/server/src/routes/index.d.ts.map +1 -1
  204. package/dist/server/src/services/document-manager.d.ts +11 -6
  205. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  206. package/dist/server/src/services/document-metadata.d.ts +16 -35
  207. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  208. package/dist/server/src/services/index.d.ts +21 -36
  209. package/dist/server/src/services/index.d.ts.map +1 -1
  210. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  211. package/dist/server/src/services/utils/populate.d.ts +8 -1
  212. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  213. package/dist/server/src/utils/index.d.ts +2 -0
  214. package/dist/server/src/utils/index.d.ts.map +1 -1
  215. package/dist/shared/contracts/collection-types.d.ts +17 -7
  216. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  217. package/dist/shared/contracts/index.d.ts +1 -0
  218. package/dist/shared/contracts/index.d.ts.map +1 -1
  219. package/dist/shared/contracts/preview.d.ts +27 -0
  220. package/dist/shared/contracts/preview.d.ts.map +1 -0
  221. package/dist/shared/contracts/relations.d.ts +2 -2
  222. package/dist/shared/contracts/relations.d.ts.map +1 -1
  223. package/dist/shared/index.js +4 -0
  224. package/dist/shared/index.js.map +1 -1
  225. package/dist/shared/index.mjs +4 -0
  226. package/dist/shared/index.mjs.map +1 -1
  227. package/package.json +22 -22
  228. package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
  229. package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
  230. package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
  231. package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
  232. package/dist/_chunks/EditViewPage-KRG56aCq.js +0 -224
  233. package/dist/_chunks/EditViewPage-KRG56aCq.js.map +0 -1
  234. package/dist/_chunks/EditViewPage-aUnqL-63.mjs +0 -203
  235. package/dist/_chunks/EditViewPage-aUnqL-63.mjs.map +0 -1
  236. package/dist/_chunks/Field-kVFO4ZKB.mjs.map +0 -1
  237. package/dist/_chunks/Field-kq1c2TF1.js.map +0 -1
  238. package/dist/_chunks/Form-CQ67ZifP.js.map +0 -1
  239. package/dist/_chunks/Form-Jgh5hGTu.mjs.map +0 -1
  240. package/dist/_chunks/History-BLEnudTX.js.map +0 -1
  241. package/dist/_chunks/History-DKhZAPcK.mjs.map +0 -1
  242. package/dist/_chunks/ListConfigurationPage-Zso_LUjn.js.map +0 -1
  243. package/dist/_chunks/ListConfigurationPage-nrXcxNYi.mjs.map +0 -1
  244. package/dist/_chunks/ListViewPage-ChhYmA-L.mjs.map +0 -1
  245. package/dist/_chunks/ListViewPage-DsaOakWQ.js.map +0 -1
  246. package/dist/_chunks/NoContentTypePage-BrdFcN33.mjs.map +0 -1
  247. package/dist/_chunks/NoContentTypePage-DPCuS9Y1.js.map +0 -1
  248. package/dist/_chunks/Relations-CY8Isqdu.js.map +0 -1
  249. package/dist/_chunks/Relations-DjFiYd7-.mjs.map +0 -1
  250. package/dist/_chunks/index-CAc9yTnx.mjs.map +0 -1
  251. package/dist/_chunks/index-DNa1J4HE.js.map +0 -1
  252. package/dist/_chunks/layout-BqtLA6Lb.js.map +0 -1
  253. package/dist/_chunks/layout-CXsHbc3E.mjs.map +0 -1
  254. package/dist/_chunks/relations-BHY_KDJ_.js.map +0 -1
  255. package/dist/_chunks/relations-mMFEcZRq.mjs.map +0 -1
  256. package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
  257. package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
  258. package/dist/_chunks/urls-DzZya_gm.js +0 -6
  259. package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
  260. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +0 -1
  261. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +0 -1
  262. package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
  263. package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
  264. package/strapi-server.js +0 -3
@@ -1,25 +1,75 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
- import { useState, useEffect, useCallback } from "react";
4
- import { useStrapiApp, createContext, useField, useNotification, useForm, useAPIErrorHandler, useQueryParams, useFocusInputField, InputRenderer as InputRenderer$1 } from "@strapi/admin/strapi-admin";
5
- import { Typography, Flex, Box, BaseLink, Button, useComposedRefs, Popover, Field, FieldLabel, FieldInput, Tooltip, SingleSelect, SingleSelectOption, IconButton, Portal, FocusTrap, InputWrapper, Divider, VisuallyHidden, FieldHint, FieldError, Grid as Grid$1, GridItem, TextButton, KeyboardNavigable, Accordion, AccordionToggle, AccordionContent as AccordionContent$1, BaseButton, TextInput, FieldAction, IconButtonGroup, Menu, MenuItem } from "@strapi/design-system";
6
- import pipe$1 from "lodash/fp/pipe";
3
+ import { useState, useEffect, useCallback, memo } from "react";
4
+ import { useStrapiApp, createContext, useField, useForm, useNotification, useAPIErrorHandler, useQueryParams, useFocusInputField, InputRenderer as InputRenderer$1 } from "@strapi/admin/strapi-admin";
5
+ import { Box, SingleSelect, SingleSelectOption, Typography, Flex, BaseLink, Button, Popover, Field, Tooltip, IconButton, useComposedRefs, Portal, FocusTrap, Divider, VisuallyHidden, Accordion, Menu, MenuItem, Grid as Grid$1, TextInput, IconButtonGroup, TextButton } from "@strapi/design-system";
6
+ import { CodeBlock as CodeBlock$1, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Code, Expand, PlusCircle, Trash, More, EyeStriked, CheckCircle, WarningCircle, Loader, ArrowClockwise, Plus } from "@strapi/icons";
7
7
  import { useIntl } from "react-intl";
8
- import { l as DOCUMENT_META_FIELDS, g as getTranslation, b as useDoc, d as contentManagerApi, c as buildValidParams, e as useDocumentRBAC, m as useDocLayout } from "./index-CAc9yTnx.mjs";
9
- import { generateNKeysBetween } from "fractional-indexing";
10
- import { u as useComponent, C as ComponentProvider, R as RelationsField } from "./Relations-DjFiYd7-.mjs";
11
- import { Code, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Expand, PlusCircle, Plus, Trash, EyeStriked, CheckCircle, WarningCircle, Loader, ArrowClockwise, More } from "@strapi/icons";
12
- import styled, { css, keyframes } from "styled-components";
13
- import { C as ComponentIcon } from "./ComponentIcon-BOFnK76n.mjs";
14
- import { getEmptyImage } from "react-dnd-html5-backend";
15
- import { a as DIRECTIONS, u as useDragAndDrop, I as ItemTypes } from "./useDragAndDrop-DdHgKsqq.mjs";
16
- import { g as getIn } from "./objects-mKMAmfec.mjs";
8
+ import { g as getTranslation, m as useDocLayout, c as useDoc, n as createDefaultForm, t as transformDocument, e as contentManagerApi, o as CLONE_PATH, d as buildValidParams, f as useDocumentRBAC, S as SINGLE_TYPES } from "./index-BH2JnYpF.mjs";
9
+ import { styled, css, keyframes } from "styled-components";
17
10
  import { Editor as Editor$1, Transforms, Node, Element, Range, Path, Point, createEditor } from "slate";
18
11
  import { withHistory } from "slate-history";
19
12
  import { useFocused, useSelected, ReactEditor, Editable, useSlate, Slate, withReact } from "slate-react";
20
- import { p as prefixFileUrlWithBackendUrl } from "./urls-CbOsUOoW.mjs";
13
+ import * as Prism from "prismjs";
14
+ import "prismjs/themes/prism-solarizedlight.css";
15
+ import "prismjs/components/prism-asmatmel";
16
+ import "prismjs/components/prism-bash";
17
+ import "prismjs/components/prism-basic";
18
+ import "prismjs/components/prism-c";
19
+ import "prismjs/components/prism-clojure";
20
+ import "prismjs/components/prism-cobol";
21
+ import "prismjs/components/prism-cpp";
22
+ import "prismjs/components/prism-csharp";
23
+ import "prismjs/components/prism-dart";
24
+ import "prismjs/components/prism-docker";
25
+ import "prismjs/components/prism-elixir";
26
+ import "prismjs/components/prism-erlang";
27
+ import "prismjs/components/prism-fortran";
28
+ import "prismjs/components/prism-fsharp";
29
+ import "prismjs/components/prism-go";
30
+ import "prismjs/components/prism-graphql";
31
+ import "prismjs/components/prism-groovy";
32
+ import "prismjs/components/prism-haskell";
33
+ import "prismjs/components/prism-haxe";
34
+ import "prismjs/components/prism-ini";
35
+ import "prismjs/components/prism-java";
36
+ import "prismjs/components/prism-javascript";
37
+ import "prismjs/components/prism-jsx";
38
+ import "prismjs/components/prism-json";
39
+ import "prismjs/components/prism-julia";
40
+ import "prismjs/components/prism-kotlin";
41
+ import "prismjs/components/prism-latex";
42
+ import "prismjs/components/prism-lua";
43
+ import "prismjs/components/prism-markdown";
44
+ import "prismjs/components/prism-matlab";
45
+ import "prismjs/components/prism-makefile";
46
+ import "prismjs/components/prism-objectivec";
47
+ import "prismjs/components/prism-perl";
48
+ import "prismjs/components/prism-php";
49
+ import "prismjs/components/prism-powershell";
50
+ import "prismjs/components/prism-python";
51
+ import "prismjs/components/prism-r";
52
+ import "prismjs/components/prism-ruby";
53
+ import "prismjs/components/prism-rust";
54
+ import "prismjs/components/prism-sas";
55
+ import "prismjs/components/prism-scala";
56
+ import "prismjs/components/prism-scheme";
57
+ import "prismjs/components/prism-sql";
58
+ import "prismjs/components/prism-stata";
59
+ import "prismjs/components/prism-swift";
60
+ import "prismjs/components/prism-typescript";
61
+ import "prismjs/components/prism-tsx";
62
+ import "prismjs/components/prism-vbnet";
63
+ import "prismjs/components/prism-yaml";
64
+ import { p as prefixFileUrlWithBackendUrl, u as useDebounce, a as usePrev } from "./usePrev-CZGy2Vjf.mjs";
65
+ import { a as DIRECTIONS, u as useDragAndDrop, I as ItemTypes } from "./useDragAndDrop-DJ6jqvZN.mjs";
21
66
  import * as Toolbar from "@radix-ui/react-toolbar";
22
- import { useLocation } from "react-router-dom";
67
+ import { getEmptyImage } from "react-dnd-html5-backend";
68
+ import { useMatch, useLocation } from "react-router-dom";
69
+ import { g as getIn } from "./objects-D6yBsdmx.mjs";
70
+ import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from "./Relations-7rWJcZ3_.mjs";
71
+ import pipe$1 from "lodash/fp/pipe";
72
+ import { C as ComponentIcon, a as COMPONENT_ICONS } from "./ComponentIcon-u4bIXTFY.mjs";
23
73
  import CodeMirror from "codemirror5";
24
74
  import sanitizeHtml from "sanitize-html";
25
75
  import { getLanguage, highlight, highlightAuto } from "highlight.js";
@@ -35,93 +85,6 @@ import sub from "markdown-it-sub";
35
85
  import sup from "markdown-it-sup";
36
86
  import "highlight.js/styles/solarized-dark.css";
37
87
  import "codemirror5/addon/display/placeholder";
38
- const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
39
- const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
40
- const traverse = (datum, attributes) => {
41
- return Object.entries(datum).reduce((acc, [key, value]) => {
42
- const attribute = attributes[key];
43
- if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
44
- acc[key] = value;
45
- return acc;
46
- }
47
- if (attribute.type === "component") {
48
- if (attribute.repeatable) {
49
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
50
- acc[key] = componentValue.map(
51
- (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
52
- );
53
- } else {
54
- const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
55
- acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
56
- }
57
- } else if (attribute.type === "dynamiczone") {
58
- const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
59
- acc[key] = dynamicZoneValue.map(
60
- (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
61
- );
62
- } else if (predicate(attribute, value)) {
63
- acc[key] = transform(value, attribute);
64
- } else {
65
- acc[key] = value;
66
- }
67
- return acc;
68
- }, {});
69
- };
70
- return traverse(data, schema.attributes);
71
- };
72
- const removeProhibitedFields = (prohibitedFields) => traverseData(
73
- (attribute) => prohibitedFields.includes(attribute.type),
74
- () => ""
75
- );
76
- const prepareRelations = traverseData(
77
- (attribute) => attribute.type === "relation",
78
- () => ({
79
- connect: [],
80
- disconnect: []
81
- })
82
- );
83
- const prepareTempKeys = traverseData(
84
- (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
85
- (data) => {
86
- if (Array.isArray(data) && data.length > 0) {
87
- const keys = generateNKeysBetween(void 0, void 0, data.length);
88
- return data.map((datum, index) => ({
89
- ...datum,
90
- __temp_key__: keys[index]
91
- }));
92
- }
93
- return data;
94
- }
95
- );
96
- const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
97
- const schemaKeys = Object.keys(schema.attributes);
98
- const dataKeys = Object.keys(data);
99
- const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
100
- const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
101
- delete acc[key];
102
- return acc;
103
- }, structuredClone(data));
104
- return revisedData;
105
- };
106
- const removeNullValues = (data) => {
107
- return Object.entries(data).reduce((acc, [key, value]) => {
108
- if (value === null) {
109
- return acc;
110
- }
111
- acc[key] = value;
112
- return acc;
113
- }, {});
114
- };
115
- const transformDocument = (schema, components = {}) => (document2) => {
116
- const transformations = pipe$1(
117
- removeFieldsThatDontExistOnSchema(schema),
118
- removeProhibitedFields(["password"])(schema, components),
119
- removeNullValues,
120
- prepareRelations(schema, components),
121
- prepareTempKeys(schema, components)
122
- );
123
- return transformations(document2);
124
- };
125
88
  const componentStore = /* @__PURE__ */ new Map();
126
89
  const useLazyComponents = (componentUids = []) => {
127
90
  const [lazyComponentStore, setLazyComponentStore] = useState(Object.fromEntries(componentStore));
@@ -160,6 +123,224 @@ const useLazyComponents = (componentUids = []) => {
160
123
  }, []);
161
124
  return { isLazyLoading: loading, lazyComponentStore, cleanup };
162
125
  };
126
+ const codeLanguages = [
127
+ {
128
+ value: "asm",
129
+ label: "Assembly",
130
+ decorate: "asmatmel"
131
+ },
132
+ {
133
+ value: "bash",
134
+ label: "Bash"
135
+ },
136
+ {
137
+ value: "c",
138
+ label: "C"
139
+ },
140
+ {
141
+ value: "clojure",
142
+ label: "Clojure"
143
+ },
144
+ {
145
+ value: "cobol",
146
+ label: "COBOL"
147
+ },
148
+ {
149
+ value: "cpp",
150
+ label: "C++"
151
+ },
152
+ {
153
+ value: "csharp",
154
+ label: "C#"
155
+ },
156
+ {
157
+ value: "css",
158
+ label: "CSS"
159
+ },
160
+ {
161
+ value: "dart",
162
+ label: "Dart"
163
+ },
164
+ {
165
+ value: "dockerfile",
166
+ label: "Dockerfile",
167
+ decorate: "docker"
168
+ },
169
+ {
170
+ value: "elixir",
171
+ label: "Elixir"
172
+ },
173
+ {
174
+ value: "erlang",
175
+ label: "Erlang"
176
+ },
177
+ {
178
+ value: "fortran",
179
+ label: "Fortran"
180
+ },
181
+ {
182
+ value: "fsharp",
183
+ label: "F#"
184
+ },
185
+ {
186
+ value: "go",
187
+ label: "Go"
188
+ },
189
+ {
190
+ value: "graphql",
191
+ label: "GraphQL"
192
+ },
193
+ {
194
+ value: "groovy",
195
+ label: "Groovy"
196
+ },
197
+ {
198
+ value: "haskell",
199
+ label: "Haskell"
200
+ },
201
+ {
202
+ value: "haxe",
203
+ label: "Haxe"
204
+ },
205
+ {
206
+ value: "html",
207
+ label: "HTML"
208
+ },
209
+ {
210
+ value: "ini",
211
+ label: "INI"
212
+ },
213
+ {
214
+ value: "java",
215
+ label: "Java"
216
+ },
217
+ {
218
+ value: "javascript",
219
+ label: "JavaScript"
220
+ },
221
+ {
222
+ value: "jsx",
223
+ label: "JavaScript (React)"
224
+ },
225
+ {
226
+ value: "json",
227
+ label: "JSON"
228
+ },
229
+ {
230
+ value: "julia",
231
+ label: "Julia"
232
+ },
233
+ {
234
+ value: "kotlin",
235
+ label: "Kotlin"
236
+ },
237
+ {
238
+ value: "latex",
239
+ label: "LaTeX"
240
+ },
241
+ {
242
+ value: "lua",
243
+ label: "Lua"
244
+ },
245
+ {
246
+ value: "markdown",
247
+ label: "Markdown"
248
+ },
249
+ {
250
+ value: "matlab",
251
+ label: "MATLAB"
252
+ },
253
+ {
254
+ value: "makefile",
255
+ label: "Makefile"
256
+ },
257
+ {
258
+ value: "objectivec",
259
+ label: "Objective-C"
260
+ },
261
+ {
262
+ value: "perl",
263
+ label: "Perl"
264
+ },
265
+ {
266
+ value: "php",
267
+ label: "PHP"
268
+ },
269
+ {
270
+ value: "plaintext",
271
+ label: "Plain text"
272
+ },
273
+ {
274
+ value: "powershell",
275
+ label: "PowerShell"
276
+ },
277
+ {
278
+ value: "python",
279
+ label: "Python"
280
+ },
281
+ {
282
+ value: "r",
283
+ label: "R"
284
+ },
285
+ {
286
+ value: "ruby",
287
+ label: "Ruby"
288
+ },
289
+ {
290
+ value: "rust",
291
+ label: "Rust"
292
+ },
293
+ {
294
+ value: "sas",
295
+ label: "SAS"
296
+ },
297
+ {
298
+ value: "scala",
299
+ label: "Scala"
300
+ },
301
+ {
302
+ value: "scheme",
303
+ label: "Scheme"
304
+ },
305
+ {
306
+ value: "shell",
307
+ label: "Shell"
308
+ },
309
+ {
310
+ value: "sql",
311
+ label: "SQL"
312
+ },
313
+ {
314
+ value: "stata",
315
+ label: "Stata"
316
+ },
317
+ {
318
+ value: "swift",
319
+ label: "Swift"
320
+ },
321
+ {
322
+ value: "typescript",
323
+ label: "TypeScript",
324
+ decorate: "ts"
325
+ },
326
+ {
327
+ value: "tsx",
328
+ label: "TypeScript (React)"
329
+ },
330
+ {
331
+ value: "vbnet",
332
+ label: "VB.NET"
333
+ },
334
+ {
335
+ value: "xml",
336
+ label: "XML"
337
+ },
338
+ {
339
+ value: "yaml",
340
+ label: "YAML",
341
+ decorate: "yml"
342
+ }
343
+ ];
163
344
  const baseHandleConvert = (editor, attributesToSet) => {
164
345
  const [_, lastNodePath] = Editor$1.last(editor, []);
165
346
  Transforms.unwrapNodes(editor, {
@@ -223,13 +404,37 @@ const pressEnterTwiceToExit = (editor) => {
223
404
  });
224
405
  }
225
406
  };
226
- const CodeBlock = styled.pre.attrs({ role: "code" })`
407
+ const decorateCode = ([node, path]) => {
408
+ const ranges = [];
409
+ if (!Element.isElement(node) || node.type !== "code") return ranges;
410
+ const text = Node.string(node);
411
+ const language = codeLanguages.find((lang) => lang.value === node.language);
412
+ const decorateKey = language?.decorate ?? language?.value;
413
+ const selectedLanguage = Prism.languages[decorateKey || "plaintext"];
414
+ const tokens = Prism.tokenize(text, selectedLanguage);
415
+ let start = 0;
416
+ for (const token of tokens) {
417
+ const length = token.length;
418
+ const end = start + length;
419
+ if (typeof token !== "string") {
420
+ ranges.push({
421
+ anchor: { path, offset: start },
422
+ focus: { path, offset: end },
423
+ className: `token ${token.type}`
424
+ });
425
+ }
426
+ start = end;
427
+ }
428
+ return ranges;
429
+ };
430
+ const CodeBlock = styled.pre`
227
431
  border-radius: ${({ theme }) => theme.borderRadius};
228
432
  background-color: ${({ theme }) => theme.colors.neutral100};
229
433
  max-width: 100%;
230
434
  overflow: auto;
231
435
  padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[4]}`};
232
436
  flex-shrink: 1;
437
+
233
438
  & > code {
234
439
  font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas,
235
440
  monospace;
@@ -238,10 +443,62 @@ const CodeBlock = styled.pre.attrs({ role: "code" })`
238
443
  max-width: 100%;
239
444
  }
240
445
  `;
446
+ const CodeEditor = (props) => {
447
+ const { editor } = useBlocksEditorContext("ImageDialog");
448
+ const editorIsFocused = useFocused();
449
+ const imageIsSelected = useSelected();
450
+ const { formatMessage } = useIntl();
451
+ const [isSelectOpen, setIsSelectOpen] = React.useState(false);
452
+ const shouldDisplayLanguageSelect = editorIsFocused && imageIsSelected || isSelectOpen;
453
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", width: "100%", children: [
454
+ /* @__PURE__ */ jsx(CodeBlock, { ...props.attributes, children: /* @__PURE__ */ jsx("code", { children: props.children }) }),
455
+ shouldDisplayLanguageSelect && /* @__PURE__ */ jsx(
456
+ Box,
457
+ {
458
+ position: "absolute",
459
+ background: "neutral0",
460
+ borderColor: "neutral150",
461
+ borderStyle: "solid",
462
+ borderWidth: "0.5px",
463
+ shadow: "tableShadow",
464
+ top: "100%",
465
+ marginTop: 1,
466
+ right: 0,
467
+ padding: 1,
468
+ hasRadius: true,
469
+ children: /* @__PURE__ */ jsx(
470
+ SingleSelect,
471
+ {
472
+ onChange: (open) => {
473
+ Transforms.setNodes(
474
+ editor,
475
+ { language: open.toString() },
476
+ { match: (node) => !Editor$1.isEditor(node) && node.type === "code" }
477
+ );
478
+ },
479
+ value: props.element.type === "code" && props.element.language || "plaintext",
480
+ onOpenChange: (open) => {
481
+ setIsSelectOpen(open);
482
+ if (!open) {
483
+ ReactEditor.focus(editor);
484
+ }
485
+ },
486
+ onCloseAutoFocus: (e) => e.preventDefault(),
487
+ "aria-label": formatMessage({
488
+ id: "components.Blocks.blocks.code.languageLabel",
489
+ defaultMessage: "Select a language"
490
+ }),
491
+ children: codeLanguages.map(({ value, label }) => /* @__PURE__ */ jsx(SingleSelectOption, { value, children: label }, value))
492
+ }
493
+ )
494
+ }
495
+ )
496
+ ] });
497
+ };
241
498
  const codeBlocks = {
242
499
  code: {
243
- renderElement: (props) => /* @__PURE__ */ jsx(CodeBlock, { ...props.attributes, children: /* @__PURE__ */ jsx("code", { children: props.children }) }),
244
- icon: Code,
500
+ renderElement: (props) => /* @__PURE__ */ jsx(CodeEditor, { ...props }),
501
+ icon: CodeBlock$1,
245
502
  label: {
246
503
  id: "components.Blocks.blocks.code",
247
504
  defaultMessage: "Code block"
@@ -249,36 +506,35 @@ const codeBlocks = {
249
506
  matchNode: (node) => node.type === "code",
250
507
  isInBlocksSelector: true,
251
508
  handleConvert(editor) {
252
- baseHandleConvert(editor, { type: "code" });
509
+ baseHandleConvert(editor, { type: "code", language: "plaintext" });
253
510
  },
254
511
  handleEnterKey(editor) {
255
512
  pressEnterTwiceToExit(editor);
256
513
  },
257
- snippets: ["```"],
258
- dragHandleTopMargin: "10px"
514
+ snippets: ["```"]
259
515
  }
260
516
  };
261
- const H1 = styled(Typography).attrs({ as: "h1" })`
517
+ const H1 = styled(Typography).attrs({ tag: "h1" })`
262
518
  font-size: 4.2rem;
263
519
  line-height: ${({ theme }) => theme.lineHeights[1]};
264
520
  `;
265
- const H2 = styled(Typography).attrs({ as: "h2" })`
521
+ const H2 = styled(Typography).attrs({ tag: "h2" })`
266
522
  font-size: 3.5rem;
267
523
  line-height: ${({ theme }) => theme.lineHeights[1]};
268
524
  `;
269
- const H3 = styled(Typography).attrs({ as: "h3" })`
525
+ const H3 = styled(Typography).attrs({ tag: "h3" })`
270
526
  font-size: 2.9rem;
271
527
  line-height: ${({ theme }) => theme.lineHeights[1]};
272
528
  `;
273
- const H4 = styled(Typography).attrs({ as: "h4" })`
529
+ const H4 = styled(Typography).attrs({ tag: "h4" })`
274
530
  font-size: 2.4rem;
275
531
  line-height: ${({ theme }) => theme.lineHeights[1]};
276
532
  `;
277
- const H5 = styled(Typography).attrs({ as: "h5" })`
533
+ const H5 = styled(Typography).attrs({ tag: "h5" })`
278
534
  font-size: 2rem;
279
535
  line-height: ${({ theme }) => theme.lineHeights[1]};
280
536
  `;
281
- const H6 = styled(Typography).attrs({ as: "h6" })`
537
+ const H6 = styled(Typography).attrs({ tag: "h6" })`
282
538
  font-size: 1.6rem;
283
539
  line-height: ${({ theme }) => theme.lineHeights[1]};
284
540
  `;
@@ -367,7 +623,7 @@ const headingBlocks = {
367
623
  const ImageWrapper = styled(Flex)`
368
624
  transition-property: box-shadow;
369
625
  transition-duration: 0.2s;
370
- ${(props) => props.isFocused && css`
626
+ ${(props) => props.$isFocused && css`
371
627
  box-shadow: ${props.theme.colors.primary600} 0px 0px 0px 3px;
372
628
  `}
373
629
 
@@ -419,7 +675,7 @@ const Image = ({ attributes, children, element }) => {
419
675
  background: "neutral100",
420
676
  contentEditable: false,
421
677
  justifyContent: "center",
422
- isFocused: editorIsFocused && imageIsSelected,
678
+ $isFocused: editorIsFocused && imageIsSelected,
423
679
  hasRadius: true,
424
680
  children: /* @__PURE__ */ jsx("img", { src: url, alt: alternativeText, width, height })
425
681
  }
@@ -430,8 +686,7 @@ const ImageDialog = () => {
430
686
  const [isOpen, setIsOpen] = React.useState(true);
431
687
  const { editor } = useBlocksEditorContext("ImageDialog");
432
688
  const components = useStrapiApp("ImageDialog", (state) => state.components);
433
- if (!components || !isOpen)
434
- return null;
689
+ if (!components || !isOpen) return null;
435
690
  const MediaLibraryDialog = components["media-library"];
436
691
  const insertImages = (images) => {
437
692
  Transforms.unwrapNodes(editor, {
@@ -440,14 +695,12 @@ const ImageDialog = () => {
440
695
  });
441
696
  const nodeEntryBeingReplaced = Editor$1.above(editor, {
442
697
  match(node) {
443
- if (Editor$1.isEditor(node))
444
- return false;
698
+ if (Editor$1.isEditor(node)) return false;
445
699
  const isInlineNode = ["text", "link"].includes(node.type);
446
700
  return !isInlineNode;
447
701
  }
448
702
  });
449
- if (!nodeEntryBeingReplaced)
450
- return;
703
+ if (!nodeEntryBeingReplaced) return;
451
704
  const [, pathToInsert] = nodeEntryBeingReplaced;
452
705
  Transforms.removeNodes(editor);
453
706
  const nodesToInsert = images.map((image) => {
@@ -579,7 +832,7 @@ const StyledBaseLink = styled(BaseLink)`
579
832
  text-decoration: none;
580
833
  `;
581
834
  const RemoveButton = styled(Button)`
582
- visibility: ${(props) => props.visible ? "visible" : "hidden"};
835
+ visibility: ${(props) => props.$visible ? "visible" : "hidden"};
583
836
  `;
584
837
  const LinkContent = React.forwardRef(
585
838
  ({ link, children, attributes }, forwardedRef) => {
@@ -589,18 +842,12 @@ const LinkContent = React.forwardRef(
589
842
  const [popoverOpen, setPopoverOpen] = React.useState(
590
843
  editor.lastInsertedLinkPath ? Path.equals(path, editor.lastInsertedLinkPath) : false
591
844
  );
592
- const linkRef = React.useRef(null);
593
845
  const elementText = link.children.map((child) => child.text).join("");
594
846
  const [linkText, setLinkText] = React.useState(elementText);
595
847
  const [linkUrl, setLinkUrl] = React.useState(link.url);
596
848
  const linkInputRef = React.useRef(null);
597
- const [showRemoveButton, setShowRemoveButton] = React.useState(false);
849
+ const isLastInsertedLink = editor.lastInsertedLinkPath ? !Path.equals(path, editor.lastInsertedLinkPath) : true;
598
850
  const [isSaveDisabled, setIsSaveDisabled] = React.useState(false);
599
- const handleOpenEditPopover = (e) => {
600
- e.preventDefault();
601
- setPopoverOpen(true);
602
- setShowRemoveButton(true);
603
- };
604
851
  const onLinkChange = (e) => {
605
852
  setIsSaveDisabled(false);
606
853
  setLinkUrl(e.target.value);
@@ -621,40 +868,39 @@ const LinkContent = React.forwardRef(
621
868
  editLink(editor, { url: linkUrl, text: linkText });
622
869
  setPopoverOpen(false);
623
870
  editor.lastInsertedLinkPath = null;
871
+ ReactEditor.focus(editor);
624
872
  };
625
- const handleDismiss = () => {
626
- setPopoverOpen(false);
873
+ const handleClose = () => {
627
874
  if (link.url === "") {
628
875
  removeLink(editor);
629
876
  }
877
+ setPopoverOpen(false);
630
878
  ReactEditor.focus(editor);
631
879
  };
632
- const inputNotDirty = !linkText || !linkUrl || link.url && link.url === linkUrl && elementText && elementText === linkText;
633
- const composedRefs = useComposedRefs(linkRef, forwardedRef);
634
880
  React.useEffect(() => {
635
- if (popoverOpen)
636
- linkInputRef.current?.focus();
881
+ if (popoverOpen) linkInputRef.current?.focus();
637
882
  }, [popoverOpen]);
638
- return /* @__PURE__ */ jsxs(Fragment, { children: [
639
- /* @__PURE__ */ jsx(
883
+ const inputNotDirty = !linkText || !linkUrl || link.url && link.url === linkUrl && elementText && elementText === linkText;
884
+ return /* @__PURE__ */ jsxs(Popover.Root, { open: popoverOpen, children: [
885
+ /* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(
640
886
  StyledBaseLink,
641
887
  {
642
888
  ...attributes,
643
- ref: composedRefs,
889
+ ref: forwardedRef,
644
890
  href: link.url,
645
- onClick: handleOpenEditPopover,
891
+ onClick: () => setPopoverOpen(true),
646
892
  color: "primary600",
647
893
  children
648
894
  }
649
- ),
650
- popoverOpen && /* @__PURE__ */ jsx(Popover, { source: linkRef, onDismiss: handleDismiss, padding: 4, contentEditable: false, children: /* @__PURE__ */ jsxs(Flex, { as: "form", onSubmit: handleSave, direction: "column", gap: 4, children: [
651
- /* @__PURE__ */ jsx(Field, { width: "368px", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "stretch", children: [
652
- /* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
895
+ ) }),
896
+ /* @__PURE__ */ jsx(Popover.Content, { onPointerDownOutside: handleClose, children: /* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 4, children: [
897
+ /* @__PURE__ */ jsx(Field.Root, { width: "368px", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "stretch", children: [
898
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
653
899
  id: "components.Blocks.popover.text",
654
900
  defaultMessage: "Text"
655
901
  }) }),
656
902
  /* @__PURE__ */ jsx(
657
- FieldInput,
903
+ Field.Input,
658
904
  {
659
905
  name: "text",
660
906
  placeholder: formatMessage({
@@ -668,13 +914,13 @@ const LinkContent = React.forwardRef(
668
914
  }
669
915
  )
670
916
  ] }) }),
671
- /* @__PURE__ */ jsx(Field, { width: "368px", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "stretch", children: [
672
- /* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
917
+ /* @__PURE__ */ jsx(Field.Root, { width: "368px", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "stretch", children: [
918
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
673
919
  id: "components.Blocks.popover.link",
674
920
  defaultMessage: "Link"
675
921
  }) }),
676
922
  /* @__PURE__ */ jsx(
677
- FieldInput,
923
+ Field.Input,
678
924
  {
679
925
  ref: linkInputRef,
680
926
  name: "url",
@@ -693,7 +939,7 @@ const LinkContent = React.forwardRef(
693
939
  {
694
940
  variant: "danger-light",
695
941
  onClick: () => removeLink(editor),
696
- visible: showRemoveButton,
942
+ $visible: isLastInsertedLink,
697
943
  children: formatMessage({
698
944
  id: "components.Blocks.popover.remove",
699
945
  defaultMessage: "Remove"
@@ -701,12 +947,12 @@ const LinkContent = React.forwardRef(
701
947
  }
702
948
  ),
703
949
  /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
704
- /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: handleDismiss, children: formatMessage({
705
- id: "components.Blocks.popover.cancel",
950
+ /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: handleClose, children: formatMessage({
951
+ id: "global.cancel",
706
952
  defaultMessage: "Cancel"
707
953
  }) }),
708
- /* @__PURE__ */ jsx(Button, { type: "submit", disabled: Boolean(inputNotDirty) || isSaveDisabled, children: formatMessage({
709
- id: "components.Blocks.popover.save",
954
+ /* @__PURE__ */ jsx(Button, { disabled: Boolean(inputNotDirty) || isSaveDisabled, onClick: handleSave, children: formatMessage({
955
+ id: "global.save",
710
956
  defaultMessage: "Save"
711
957
  }) })
712
958
  ] })
@@ -748,11 +994,11 @@ const listStyle = css`
748
994
  }
749
995
  `;
750
996
  const Orderedlist = styled.ol`
751
- list-style-type: ${(props) => props.listStyleType};
997
+ list-style-type: ${(props) => props.$listStyleType};
752
998
  ${listStyle}
753
999
  `;
754
1000
  const Unorderedlist = styled.ul`
755
- list-style-type: ${(props) => props.listStyleType};
1001
+ list-style-type: ${(props) => props.$listStyleType};
756
1002
  ${listStyle}
757
1003
  `;
758
1004
  const orderedStyles = ["decimal", "lower-alpha", "upper-roman"];
@@ -765,9 +1011,9 @@ const List = ({ attributes, children, element }) => {
765
1011
  const nextIndex = (element.indentLevel || 0) % listStyles.length;
766
1012
  const listStyleType = listStyles[nextIndex];
767
1013
  if (element.format === "ordered") {
768
- return /* @__PURE__ */ jsx(Orderedlist, { listStyleType, ...attributes, children });
1014
+ return /* @__PURE__ */ jsx(Orderedlist, { $listStyleType: listStyleType, ...attributes, children });
769
1015
  }
770
- return /* @__PURE__ */ jsx(Unorderedlist, { listStyleType, ...attributes, children });
1016
+ return /* @__PURE__ */ jsx(Unorderedlist, { $listStyleType: listStyleType, ...attributes, children });
771
1017
  };
772
1018
  const replaceListWithEmptyBlock = (editor, currentListPath) => {
773
1019
  Transforms.removeNodes(editor, { at: currentListPath });
@@ -787,8 +1033,7 @@ const isText$1 = (node) => {
787
1033
  return Node.isNode(node) && !Editor$1.isEditor(node) && node.type === "text";
788
1034
  };
789
1035
  const handleBackspaceKeyOnList = (editor, event) => {
790
- if (!editor.selection)
791
- return;
1036
+ if (!editor.selection) return;
792
1037
  const [currentListItem, currentListItemPath] = Editor$1.parent(editor, editor.selection.anchor);
793
1038
  const [currentList, currentListPath] = Editor$1.parent(editor, currentListItemPath);
794
1039
  const isListEmpty = currentList.children.length === 1 && isText$1(currentListItem.children[0]) && currentListItem.children[0].text === "";
@@ -897,8 +1142,7 @@ const handleEnterKeyOnList = (editor) => {
897
1142
  };
898
1143
  const handleConvertToList = (editor, format) => {
899
1144
  const convertedPath = baseHandleConvert(editor, { type: "list-item" });
900
- if (!convertedPath)
901
- return;
1145
+ if (!convertedPath) return;
902
1146
  Transforms.wrapNodes(editor, { type: "list", format, children: [] }, { at: convertedPath });
903
1147
  };
904
1148
  const handleTabOnList = (editor) => {
@@ -910,8 +1154,7 @@ const handleTabOnList = (editor) => {
910
1154
  }
911
1155
  const [currentListItem, currentListItemPath] = currentListItemEntry;
912
1156
  const [currentList] = Editor$1.parent(editor, currentListItemPath);
913
- if (currentListItem === currentList.children[0])
914
- return;
1157
+ if (currentListItem === currentList.children[0]) return;
915
1158
  const currentListItemIndex = currentList.children.findIndex((item) => item === currentListItem);
916
1159
  const previousNode = currentList.children[currentListItemIndex - 1];
917
1160
  if (previousNode.type === "list") {
@@ -964,7 +1207,7 @@ const listBlocks = {
964
1207
  snippets: ["-", "*", "+"]
965
1208
  },
966
1209
  "list-item": {
967
- renderElement: (props) => /* @__PURE__ */ jsx(Typography, { as: "li", ...props.attributes, children: props.children }),
1210
+ renderElement: (props) => /* @__PURE__ */ jsx(Typography, { tag: "li", ...props.attributes, children: props.children }),
968
1211
  // No handleConvert, list items are created when converting to the parent list
969
1212
  matchNode: (node) => node.type === "list-item",
970
1213
  isInBlocksSelector: false,
@@ -973,7 +1216,7 @@ const listBlocks = {
973
1216
  };
974
1217
  const paragraphBlocks = {
975
1218
  paragraph: {
976
- renderElement: (props) => /* @__PURE__ */ jsx(Typography, { as: "p", variant: "omega", ...props.attributes, children: props.children }),
1219
+ renderElement: (props) => /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", ...props.attributes, children: props.children }),
977
1220
  icon: Paragraph,
978
1221
  label: {
979
1222
  id: "components.Blocks.blocks.text",
@@ -1047,13 +1290,13 @@ const quoteBlocks = {
1047
1290
  handleEnterKey(editor) {
1048
1291
  pressEnterTwiceToExit(editor);
1049
1292
  },
1050
- snippets: [">"],
1051
- dragHandleTopMargin: "6px"
1293
+ snippets: [">"]
1052
1294
  }
1053
1295
  };
1054
1296
  const ToolbarWrapper = styled(Flex)`
1055
1297
  &[aria-disabled='true'] {
1056
1298
  cursor: not-allowed;
1299
+ background: ${({ theme }) => theme.colors.neutral150};
1057
1300
  }
1058
1301
  `;
1059
1302
  const Separator = styled(Toolbar.Separator)`
@@ -1064,7 +1307,7 @@ const Separator = styled(Toolbar.Separator)`
1064
1307
  const FlexButton = styled(Flex)`
1065
1308
  // Inherit the not-allowed cursor from ToolbarWrapper when disabled
1066
1309
  &[aria-disabled] {
1067
- cursor: inherit;
1310
+ cursor: not-allowed;
1068
1311
  }
1069
1312
 
1070
1313
  &[aria-disabled='false'] {
@@ -1139,14 +1382,14 @@ const ToolbarButton = ({
1139
1382
  children: /* @__PURE__ */ jsx(
1140
1383
  FlexButton,
1141
1384
  {
1142
- as: "button",
1385
+ tag: "button",
1143
1386
  background: isActive ? "primary100" : "",
1144
1387
  alignItems: "center",
1145
1388
  justifyContent: "center",
1146
1389
  width: 7,
1147
1390
  height: 7,
1148
1391
  hasRadius: true,
1149
- children: /* @__PURE__ */ jsx(Icon, { width: "1.2rem", height: "1.2rem", fill: disabled ? "neutral300" : enabledColor })
1392
+ children: /* @__PURE__ */ jsx(Icon, { fill: disabled ? "neutral300" : enabledColor })
1150
1393
  }
1151
1394
  )
1152
1395
  }
@@ -1278,8 +1521,7 @@ const isListNode = (node) => {
1278
1521
  const ListButton = ({ block, format }) => {
1279
1522
  const { editor, disabled, blocks } = useBlocksEditorContext("ListButton");
1280
1523
  const isListActive = () => {
1281
- if (!editor.selection)
1282
- return false;
1524
+ if (!editor.selection) return false;
1283
1525
  const currentListEntry = Editor$1.above(editor, {
1284
1526
  match: (node) => !Editor$1.isEditor(node) && node.type === "list",
1285
1527
  at: editor.selection.anchor
@@ -1291,6 +1533,26 @@ const ListButton = ({ block, format }) => {
1291
1533
  }
1292
1534
  return false;
1293
1535
  };
1536
+ const isListDisabled = () => {
1537
+ if (disabled) {
1538
+ return true;
1539
+ }
1540
+ if (!editor.selection) {
1541
+ return false;
1542
+ }
1543
+ const anchorNodeEntry = Editor$1.above(editor, {
1544
+ at: editor.selection.anchor,
1545
+ match: (node) => !Editor$1.isEditor(node) && node.type !== "text"
1546
+ });
1547
+ const focusNodeEntry = Editor$1.above(editor, {
1548
+ at: editor.selection.focus,
1549
+ match: (node) => !Editor$1.isEditor(node) && node.type !== "text"
1550
+ });
1551
+ if (!anchorNodeEntry || !focusNodeEntry) {
1552
+ return false;
1553
+ }
1554
+ return anchorNodeEntry[0] !== focusNodeEntry[0];
1555
+ };
1294
1556
  const toggleList = (format2) => {
1295
1557
  let currentListEntry;
1296
1558
  if (editor.selection) {
@@ -1324,7 +1586,7 @@ const ListButton = ({ block, format }) => {
1324
1586
  name: format,
1325
1587
  label: block.label,
1326
1588
  isActive: isListActive(),
1327
- disabled,
1589
+ disabled: isListDisabled(),
1328
1590
  handleClick: () => toggleList(format)
1329
1591
  }
1330
1592
  );
@@ -1333,8 +1595,7 @@ const LinkButton = ({ disabled }) => {
1333
1595
  const { editor } = useBlocksEditorContext("LinkButton");
1334
1596
  const isLinkActive = () => {
1335
1597
  const { selection } = editor;
1336
- if (!selection)
1337
- return false;
1598
+ if (!selection) return false;
1338
1599
  const [match] = Array.from(
1339
1600
  Editor$1.nodes(editor, {
1340
1601
  at: Editor$1.unhangRange(editor, selection),
@@ -1398,7 +1659,7 @@ const BlocksToolbar = () => {
1398
1659
  return false;
1399
1660
  };
1400
1661
  const isButtonDisabled = checkButtonDisabled();
1401
- return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, children: [
1662
+ return /* @__PURE__ */ jsx(Toolbar.Root, { "aria-disabled": disabled, asChild: true, children: /* @__PURE__ */ jsxs(ToolbarWrapper, { gap: 2, padding: 2, width: "100%", children: [
1402
1663
  /* @__PURE__ */ jsx(BlocksDropdown, {}),
1403
1664
  /* @__PURE__ */ jsx(Separator, {}),
1404
1665
  /* @__PURE__ */ jsx(Toolbar.ToggleGroup, { type: "multiple", asChild: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 1, children: [
@@ -1460,7 +1721,7 @@ const DragItem = styled(Flex)`
1460
1721
 
1461
1722
  // Set the visibility of drag button
1462
1723
  [role='button'] {
1463
- visibility: ${(props) => props.dragVisibility};
1724
+ visibility: ${(props) => props.$dragVisibility};
1464
1725
  opacity: inherit;
1465
1726
  }
1466
1727
  &[aria-disabled='true'] {
@@ -1468,33 +1729,36 @@ const DragItem = styled(Flex)`
1468
1729
  }
1469
1730
  `;
1470
1731
  const DragIconButton = styled(IconButton)`
1732
+ user-select: none;
1471
1733
  display: flex;
1472
1734
  align-items: center;
1473
1735
  justify-content: center;
1736
+ border: none;
1474
1737
  border-radius: ${({ theme }) => theme.borderRadius};
1475
- width: ${({ theme }) => theme.spaces[4]};
1476
- height: ${({ theme }) => theme.spaces[6]};
1738
+ padding-left: ${({ theme }) => theme.spaces[0]};
1739
+ padding-right: ${({ theme }) => theme.spaces[0]};
1740
+ padding-top: ${({ theme }) => theme.spaces[1]};
1741
+ padding-bottom: ${({ theme }) => theme.spaces[1]};
1477
1742
  visibility: hidden;
1478
1743
  cursor: grab;
1479
1744
  opacity: inherit;
1480
- margin-top: ${(props) => props.dragHandleTopMargin ?? 0};
1745
+ margin-top: ${(props) => props.$dragHandleTopMargin ?? 0};
1481
1746
 
1482
1747
  &:hover {
1483
- background: ${({ theme }) => theme.colors.neutral200};
1748
+ background: ${({ theme }) => theme.colors.neutral100};
1484
1749
  }
1485
1750
  &:active {
1486
1751
  cursor: grabbing;
1752
+ background: ${({ theme }) => theme.colors.neutral150};
1487
1753
  }
1488
1754
  &[aria-disabled='true'] {
1489
- cursor: not-allowed;
1490
- background: transparent;
1755
+ visibility: hidden;
1491
1756
  }
1492
1757
  svg {
1493
- height: auto;
1494
- width: ${({ theme }) => theme.spaces[3]};
1758
+ min-width: ${({ theme }) => theme.spaces[3]};
1495
1759
 
1496
1760
  path {
1497
- fill: ${({ theme }) => theme.colors.neutral700};
1761
+ fill: ${({ theme }) => theme.colors.neutral500};
1498
1762
  }
1499
1763
  }
1500
1764
  `;
@@ -1539,8 +1803,7 @@ const DragAndDropElement = ({
1539
1803
  displayedValue: children
1540
1804
  },
1541
1805
  onDropItem(currentIndex, newIndex) {
1542
- if (newIndex)
1543
- handleMoveBlock(newIndex, currentIndex);
1806
+ if (newIndex) handleMoveBlock(newIndex, currentIndex);
1544
1807
  }
1545
1808
  });
1546
1809
  const composedBoxRefs = useComposedRefs(blockRef, dropRef);
@@ -1552,7 +1815,7 @@ const DragAndDropElement = ({
1552
1815
  React.useEffect(() => {
1553
1816
  setDragVisibility("hidden");
1554
1817
  }, [editor.selection]);
1555
- return /* @__PURE__ */ jsxs(Wrapper$1, { ref: (ref) => composedBoxRefs(ref), isOverDropTarget, children: [
1818
+ return /* @__PURE__ */ jsxs(Wrapper$1, { ref: composedBoxRefs, isOverDropTarget, children: [
1556
1819
  isOverDropTarget && /* @__PURE__ */ jsx(
1557
1820
  DropPlaceholder,
1558
1821
  {
@@ -1590,15 +1853,17 @@ const DragAndDropElement = ({
1590
1853
  onSelect: () => setDragVisibility("visible"),
1591
1854
  onMouseLeave: () => setDragVisibility("hidden"),
1592
1855
  "aria-disabled": disabled,
1593
- dragVisibility,
1856
+ $dragVisibility: dragVisibility,
1594
1857
  children: [
1595
1858
  /* @__PURE__ */ jsx(
1596
1859
  DragIconButton,
1597
1860
  {
1598
- forwardedAs: "div",
1861
+ tag: "div",
1862
+ contentEditable: false,
1599
1863
  role: "button",
1600
1864
  tabIndex: 0,
1601
- "aria-label": formatMessage({
1865
+ withTooltip: false,
1866
+ label: formatMessage({
1602
1867
  id: getTranslation("components.DragHandle-label"),
1603
1868
  defaultMessage: "Drag"
1604
1869
  }),
@@ -1606,8 +1871,8 @@ const DragAndDropElement = ({
1606
1871
  "aria-disabled": disabled,
1607
1872
  disabled,
1608
1873
  draggable: true,
1609
- dragHandleTopMargin,
1610
- children: /* @__PURE__ */ jsx(Drag, { color: "neutral600" })
1874
+ $dragHandleTopMargin: dragHandleTopMargin,
1875
+ children: /* @__PURE__ */ jsx(Drag, { color: "primary500" })
1611
1876
  }
1612
1877
  ),
1613
1878
  children
@@ -1618,17 +1883,18 @@ const DragAndDropElement = ({
1618
1883
  };
1619
1884
  const CloneDragItem = ({ children, dragHandleTopMargin }) => {
1620
1885
  const { formatMessage } = useIntl();
1621
- return /* @__PURE__ */ jsxs(DragItem, { gap: 2, paddingLeft: 2, alignItems: "start", dragVisibility: "visible", children: [
1886
+ return /* @__PURE__ */ jsxs(DragItem, { gap: 2, paddingLeft: 2, alignItems: "start", $dragVisibility: "visible", children: [
1622
1887
  /* @__PURE__ */ jsx(
1623
1888
  DragIconButton,
1624
1889
  {
1625
- forwardedAs: "div",
1890
+ tag: "div",
1626
1891
  role: "button",
1627
- "aria-label": formatMessage({
1892
+ withTooltip: false,
1893
+ label: formatMessage({
1628
1894
  id: getTranslation("components.DragHandle-label"),
1629
1895
  defaultMessage: "Drag"
1630
1896
  }),
1631
- dragHandleTopMargin,
1897
+ $dragHandleTopMargin: dragHandleTopMargin,
1632
1898
  children: /* @__PURE__ */ jsx(Drag, { color: "neutral600" })
1633
1899
  }
1634
1900
  ),
@@ -1643,7 +1909,7 @@ const baseRenderLeaf = (props, modifiers2) => {
1643
1909
  }
1644
1910
  return currentChildren;
1645
1911
  }, props.children);
1646
- return /* @__PURE__ */ jsx("span", { ...props.attributes, children: wrappedChildren });
1912
+ return /* @__PURE__ */ jsx("span", { ...props.attributes, className: props.leaf.className, children: wrappedChildren });
1647
1913
  };
1648
1914
  const baseRenderElement = ({
1649
1915
  props,
@@ -1681,8 +1947,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1681
1947
  [modifiers2]
1682
1948
  );
1683
1949
  const handleMoveBlocks = (editor2, event) => {
1684
- if (!editor2.selection)
1685
- return;
1950
+ if (!editor2.selection) return;
1686
1951
  const start = Range.start(editor2.selection);
1687
1952
  const currentIndex = [start.path[0]];
1688
1953
  let newIndexPosition = 0;
@@ -1819,8 +2084,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1819
2084
  }
1820
2085
  };
1821
2086
  const handleScrollSelectionIntoView = () => {
1822
- if (!editor.selection)
1823
- return;
2087
+ if (!editor.selection) return;
1824
2088
  const domRange = ReactEditor.toDOMRange(editor, editor.selection);
1825
2089
  const domRect = domRange.getBoundingClientRect();
1826
2090
  const blocksInput = blocksRef.current;
@@ -1847,7 +2111,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1847
2111
  background: "neutral0",
1848
2112
  color: "neutral800",
1849
2113
  lineHeight: 6,
1850
- paddingRight: 4,
2114
+ paddingRight: 7,
1851
2115
  paddingTop: 6,
1852
2116
  paddingBottom: 3,
1853
2117
  children: [
@@ -1858,6 +2122,7 @@ const BlocksContent = ({ placeholder, ariaLabelId }) => {
1858
2122
  readOnly: disabled,
1859
2123
  placeholder,
1860
2124
  isExpandedMode,
2125
+ decorate: decorateCode,
1861
2126
  renderElement,
1862
2127
  renderLeaf,
1863
2128
  onKeyDown: handleKeyDown,
@@ -1930,7 +2195,7 @@ const EditorLayout$1 = ({
1930
2195
  /* @__PURE__ */ jsx(
1931
2196
  CollapseIconButton,
1932
2197
  {
1933
- "aria-label": formatMessage({
2198
+ label: formatMessage({
1934
2199
  id: getTranslation("components.Blocks.collapse"),
1935
2200
  defaultMessage: "Collapse"
1936
2201
  }),
@@ -1950,8 +2215,8 @@ const EditorLayout$1 = ({
1950
2215
  direction: "column",
1951
2216
  alignItems: "flex-start",
1952
2217
  height: "512px",
1953
- disabled,
1954
- hasError: Boolean(error),
2218
+ $disabled: disabled,
2219
+ $hasError: Boolean(error),
1955
2220
  style: { overflow: "hidden" },
1956
2221
  "aria-describedby": ariaDescriptionId,
1957
2222
  position: "relative",
@@ -1959,6 +2224,29 @@ const EditorLayout$1 = ({
1959
2224
  }
1960
2225
  );
1961
2226
  };
2227
+ const InputWrapper = styled(Flex)`
2228
+ border: 1px solid
2229
+ ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral200};
2230
+ border-radius: ${({ theme }) => theme.borderRadius};
2231
+ background: ${({ theme }) => theme.colors.neutral0};
2232
+
2233
+ ${({ theme, $hasError = false }) => css`
2234
+ outline: none;
2235
+ box-shadow: 0;
2236
+ transition-property: border-color, box-shadow, fill;
2237
+ transition-duration: 0.2s;
2238
+
2239
+ &:focus-within {
2240
+ border: 1px solid ${$hasError ? theme.colors.danger600 : theme.colors.primary600};
2241
+ box-shadow: ${$hasError ? theme.colors.danger600 : theme.colors.primary600} 0px 0px 0px 2px;
2242
+ }
2243
+ `}
2244
+
2245
+ ${({ theme, $disabled }) => $disabled ? css`
2246
+ color: ${theme.colors.neutral600};
2247
+ background: ${theme.colors.neutral150};
2248
+ ` : void 0}
2249
+ `;
1962
2250
  const stylesToInherit = css`
1963
2251
  font-size: inherit;
1964
2252
  color: inherit;
@@ -1971,10 +2259,14 @@ const ItalicText = styled(Typography)`
1971
2259
  font-style: italic;
1972
2260
  ${stylesToInherit}
1973
2261
  `;
1974
- const UnderlineText = styled(Typography).attrs({ textDecoration: "underline" })`
2262
+ const UnderlineText = styled(Typography).attrs({
2263
+ textDecoration: "underline"
2264
+ })`
1975
2265
  ${stylesToInherit}
1976
2266
  `;
1977
- const StrikeThroughText = styled(Typography).attrs({ textDecoration: "line-through" })`
2267
+ const StrikeThroughText = styled(Typography).attrs({
2268
+ textDecoration: "line-through"
2269
+ })`
1978
2270
  ${stylesToInherit}
1979
2271
  `;
1980
2272
  const InlineCode = styled.code`
@@ -1987,8 +2279,7 @@ const InlineCode = styled.code`
1987
2279
  `;
1988
2280
  const baseCheckIsActive = (editor, name2) => {
1989
2281
  const marks = Editor$1.marks(editor);
1990
- if (!marks)
1991
- return false;
2282
+ if (!marks) return false;
1992
2283
  return Boolean(marks[name2]);
1993
2284
  };
1994
2285
  const baseHandleToggle = (editor, name2) => {
@@ -2154,6 +2445,7 @@ const ExpandIconButton = styled(IconButton)`
2154
2445
  position: absolute;
2155
2446
  bottom: 1.2rem;
2156
2447
  right: 1.2rem;
2448
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2157
2449
  `;
2158
2450
  function useResetKey(value) {
2159
2451
  const slateUpdatesCount = React.useRef(0);
@@ -2242,7 +2534,7 @@ const BlocksEditor = React.forwardRef(
2242
2534
  !isExpandedMode && /* @__PURE__ */ jsx(
2243
2535
  ExpandIconButton,
2244
2536
  {
2245
- "aria-label": formatMessage({
2537
+ label: formatMessage({
2246
2538
  id: getTranslation("components.Blocks.expand"),
2247
2539
  defaultMessage: "Expand"
2248
2540
  }),
@@ -2265,8 +2557,8 @@ const BlocksInput = React.forwardRef(
2265
2557
  ({ label, name: name2, required = false, hint, labelAction, ...editorProps }, forwardedRef) => {
2266
2558
  const id = React.useId();
2267
2559
  const field = useField(name2);
2268
- return /* @__PURE__ */ jsx(Field, { id, name: name2, hint, error: field.error, required, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
2269
- /* @__PURE__ */ jsx(FieldLabel, { action: labelAction, children: label }),
2560
+ return /* @__PURE__ */ jsx(Field.Root, { id, name: name2, hint, error: field.error, required, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
2561
+ /* @__PURE__ */ jsx(Field.Label, { action: labelAction, children: label }),
2270
2562
  /* @__PURE__ */ jsx(
2271
2563
  BlocksEditor,
2272
2564
  {
@@ -2279,675 +2571,150 @@ const BlocksInput = React.forwardRef(
2279
2571
  ...editorProps
2280
2572
  }
2281
2573
  ),
2282
- /* @__PURE__ */ jsx(FieldHint, {}),
2283
- /* @__PURE__ */ jsx(FieldError, {})
2574
+ /* @__PURE__ */ jsx(Field.Hint, {}),
2575
+ /* @__PURE__ */ jsx(Field.Error, {})
2284
2576
  ] }) });
2285
2577
  }
2286
2578
  );
2287
- const createDefaultForm = (contentType, components = {}) => {
2288
- const traverseSchema = (attributes) => {
2289
- return Object.entries(attributes).reduce((acc, [key, attribute]) => {
2290
- if ("default" in attribute) {
2291
- acc[key] = attribute.default;
2292
- } else if (attribute.type === "component" && attribute.required) {
2293
- const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
2294
- if (attribute.repeatable) {
2295
- acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
2296
- } else {
2297
- acc[key] = defaultComponentForm;
2298
- }
2299
- } else if (attribute.type === "dynamiczone" && attribute.required) {
2300
- acc[key] = [];
2301
- }
2302
- return acc;
2303
- }, {});
2304
- };
2305
- return traverseSchema(contentType.attributes);
2306
- };
2579
+ const MemoizedBlocksInput = React.memo(BlocksInput);
2307
2580
  const Initializer = ({ disabled, name: name2, onClick }) => {
2308
2581
  const { formatMessage } = useIntl();
2309
2582
  const field = useField(name2);
2310
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2311
- /* @__PURE__ */ jsx(
2312
- Box,
2313
- {
2314
- as: "button",
2315
- background: "neutral100",
2316
- borderColor: field.error ? "danger600" : "neutral200",
2317
- hasRadius: true,
2318
- disabled,
2319
- onClick,
2320
- paddingTop: 9,
2321
- paddingBottom: 9,
2322
- type: "button",
2323
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2324
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(CircleIcon, {}) }),
2325
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { textColor: "primary600", variant: "pi", fontWeight: "bold", children: formatMessage({
2326
- id: getTranslation("components.empty-repeatable"),
2327
- defaultMessage: "No entry yet. Click on the button below to add one."
2328
- }) }) })
2329
- ] })
2330
- }
2331
- ),
2332
- field.error && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "pi", children: field.error })
2333
- ] });
2334
- };
2335
- const CircleIcon = styled(PlusCircle)`
2336
- width: 2.4rem;
2337
- height: 2.4rem;
2338
- > circle {
2339
- fill: ${({ theme }) => theme.colors.primary200};
2340
- }
2341
- > path {
2342
- fill: ${({ theme }) => theme.colors.primary600};
2343
- }
2344
- `;
2345
- const NonRepeatableComponent = ({
2346
- attribute,
2347
- name: name2,
2348
- children,
2349
- layout
2350
- }) => {
2351
- const { value } = useField(name2);
2352
- const level = useComponent("NonRepeatableComponent", (state) => state.level);
2353
- const isNested = level > 0;
2354
- return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
2583
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
2355
2584
  Box,
2356
2585
  {
2357
- background: "neutral100",
2358
- paddingLeft: 6,
2359
- paddingRight: 6,
2360
- paddingTop: 6,
2361
- paddingBottom: 6,
2362
- hasRadius: isNested,
2363
- borderColor: isNested ? "neutral200" : void 0,
2364
- children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
2365
- return /* @__PURE__ */ jsx(Grid$1, { gap: 4, children: row.map(({ size, ...field }) => {
2366
- const completeFieldName = `${name2}.${field.name}`;
2367
- return /* @__PURE__ */ jsx(GridItem, { col: size, s: 12, xs: 12, children: children({ ...field, name: completeFieldName }) }, completeFieldName);
2368
- }) }, index);
2369
- }) })
2586
+ tag: "button",
2587
+ background: disabled ? "neutral150" : "neutral100",
2588
+ borderColor: field.error ? "danger600" : "neutral200",
2589
+ hasRadius: true,
2590
+ disabled,
2591
+ onClick,
2592
+ paddingTop: 9,
2593
+ paddingBottom: 9,
2594
+ type: "button",
2595
+ style: { cursor: disabled ? "not-allowed" : "pointer" },
2596
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2597
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", color: disabled ? "neutral500" : "primary600", children: /* @__PURE__ */ jsx(PlusCircle, { width: "3.2rem", height: "3.2rem" }) }),
2598
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2599
+ Typography,
2600
+ {
2601
+ textColor: disabled ? "neutral600" : "primary600",
2602
+ variant: "pi",
2603
+ fontWeight: "bold",
2604
+ children: formatMessage({
2605
+ id: getTranslation("components.empty-repeatable"),
2606
+ defaultMessage: "No entry yet. Click to add one."
2607
+ })
2608
+ }
2609
+ ) })
2610
+ ] })
2370
2611
  }
2371
2612
  ) });
2372
2613
  };
2373
- const RepeatableComponent = ({
2374
- attribute,
2375
- disabled,
2376
- name: name2,
2377
- mainField,
2614
+ const AddComponentButton = ({
2615
+ hasError,
2616
+ isDisabled,
2617
+ isOpen,
2378
2618
  children,
2379
- layout
2619
+ onClick
2380
2620
  }) => {
2381
- const { toggleNotification } = useNotification();
2382
- const { formatMessage } = useIntl();
2383
- const { search: searchString } = useLocation();
2384
- const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
2385
- const { components } = useDoc();
2386
- const { value = [], error } = useField(name2);
2387
- const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
2388
- const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
2389
- const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
2390
- const { max = Infinity } = attribute;
2391
- const [collapseToOpen, setCollapseToOpen] = React.useState(null);
2392
- const [liveText, setLiveText] = React.useState("");
2393
- const componentTmpKeyWithFocussedField = React.useMemo(() => {
2394
- if (search.has("field")) {
2395
- const fieldParam = search.get("field");
2396
- if (!fieldParam) {
2397
- return void 0;
2398
- }
2399
- const [, path] = fieldParam.split(`${name2}.`);
2400
- if (getIn(value, path, void 0) !== void 0) {
2401
- const [subpath] = path.split(".");
2402
- return getIn(value, subpath, void 0)?.__temp_key__;
2403
- }
2404
- }
2405
- return void 0;
2406
- }, [search, name2, value]);
2407
- React.useEffect(() => {
2408
- if (typeof componentTmpKeyWithFocussedField === "number") {
2409
- setCollapseToOpen(componentTmpKeyWithFocussedField);
2410
- }
2411
- }, [componentTmpKeyWithFocussedField]);
2412
- const toggleCollapses = () => {
2413
- setCollapseToOpen(null);
2414
- };
2415
- const handleClick = () => {
2416
- if (value.length < max) {
2417
- const schema = components[attribute.component];
2418
- const form = createDefaultForm(schema, components);
2419
- const data = transformDocument(schema, components)(form);
2420
- addFieldRow(name2, data);
2421
- } else if (value.length >= max) {
2422
- toggleNotification({
2423
- type: "info",
2424
- message: formatMessage({
2425
- id: getTranslation("components.notification.info.maximum-requirement")
2426
- })
2427
- });
2428
- }
2429
- };
2430
- const handleMoveComponentField = (newIndex, currentIndex) => {
2431
- setLiveText(
2432
- formatMessage(
2433
- {
2434
- id: getTranslation("dnd.reorder"),
2435
- defaultMessage: "{item}, moved. New position in list: {position}."
2436
- },
2437
- {
2438
- item: `${name2}.${currentIndex}`,
2439
- position: getItemPos(newIndex)
2440
- }
2441
- )
2442
- );
2443
- moveFieldRow(name2, currentIndex, newIndex);
2444
- };
2445
- const handleToggle = (key) => () => {
2446
- if (collapseToOpen === key) {
2447
- setCollapseToOpen(null);
2448
- } else {
2449
- setCollapseToOpen(key);
2450
- }
2451
- };
2452
- const getItemPos = (index) => `${index + 1} of ${value.length}`;
2453
- const handleCancel = (index) => {
2454
- setLiveText(
2455
- formatMessage(
2456
- {
2457
- id: getTranslation("dnd.cancel-item"),
2458
- defaultMessage: "{item}, dropped. Re-order cancelled."
2459
- },
2460
- {
2461
- item: `${name2}.${index}`
2462
- }
2463
- )
2464
- );
2465
- };
2466
- const handleGrabItem = (index) => {
2467
- setLiveText(
2468
- formatMessage(
2469
- {
2470
- id: getTranslation("dnd.grab-item"),
2471
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
2472
- },
2473
- {
2474
- item: `${name2}.${index}`,
2475
- position: getItemPos(index)
2476
- }
2477
- )
2478
- );
2479
- };
2480
- const handleDropItem = (index) => {
2481
- setLiveText(
2482
- formatMessage(
2483
- {
2484
- id: getTranslation("dnd.drop-item"),
2485
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
2486
- },
2487
- {
2488
- item: `${name2}.${index}`,
2489
- position: getItemPos(index)
2490
- }
2491
- )
2492
- );
2493
- };
2494
- const ariaDescriptionId = React.useId();
2495
- const level = useComponent("RepeatableComponent", (state) => state.level);
2496
- if (value.length === 0) {
2497
- return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
2498
- }
2499
- return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
2500
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
2501
- id: getTranslation("dnd.instructions"),
2502
- defaultMessage: `Press spacebar to grab and re-order`
2503
- }) }),
2504
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
2505
- /* @__PURE__ */ jsxs(AccordionGroup, { error, children: [
2506
- /* @__PURE__ */ jsx(AccordionContent, { "aria-describedby": ariaDescriptionId, children: value.map(({ __temp_key__: key, id }, index) => {
2507
- const nameWithIndex = `${name2}.${index}`;
2508
- return /* @__PURE__ */ jsx(
2509
- ComponentProvider,
2621
+ return /* @__PURE__ */ jsx(
2622
+ StyledButton,
2623
+ {
2624
+ type: "button",
2625
+ onClick,
2626
+ disabled: isDisabled,
2627
+ background: "neutral0",
2628
+ style: { cursor: isDisabled ? "not-allowed" : "pointer" },
2629
+ variant: "tertiary",
2630
+ children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
2631
+ /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
2632
+ /* @__PURE__ */ jsx(
2633
+ Typography,
2510
2634
  {
2511
- id,
2512
- uid: attribute.component,
2513
- level: level + 1,
2514
- type: "repeatable",
2515
- children: /* @__PURE__ */ jsx(
2516
- Component,
2517
- {
2518
- disabled,
2519
- name: nameWithIndex,
2520
- attribute,
2521
- index,
2522
- isOpen: collapseToOpen === key,
2523
- mainField,
2524
- onMoveItem: handleMoveComponentField,
2525
- onClickToggle: handleToggle(key),
2526
- onDeleteComponent: () => {
2527
- removeFieldRow(name2, index);
2528
- toggleCollapses();
2529
- },
2530
- toggleCollapses,
2531
- onCancel: handleCancel,
2532
- onDropItem: handleDropItem,
2533
- onGrabItem: handleGrabItem,
2534
- children: layout.map((row, index2) => {
2535
- return /* @__PURE__ */ jsx(Grid$1, { gap: 4, children: row.map(({ size, ...field }) => {
2536
- const completeFieldName = `${nameWithIndex}.${field.name}`;
2537
- return /* @__PURE__ */ jsx(GridItem, { col: size, s: 12, xs: 12, children: children({ ...field, name: completeFieldName }) }, completeFieldName);
2538
- }) }, index2);
2539
- })
2540
- }
2541
- )
2542
- },
2543
- key
2544
- );
2545
- }) }),
2546
- /* @__PURE__ */ jsx(AccordionFooter, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", height: "48px", background: "neutral0", children: /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
2547
- id: getTranslation("containers.EditView.add.new-entry"),
2548
- defaultMessage: "Add an entry"
2549
- }) }) }) })
2550
- ] })
2551
- ] });
2635
+ variant: "pi",
2636
+ fontWeight: "bold",
2637
+ textColor: hasError && !isOpen ? "danger600" : "neutral600",
2638
+ children
2639
+ }
2640
+ )
2641
+ ] })
2642
+ }
2643
+ );
2552
2644
  };
2553
- const TextButtonCustom = styled(TextButton)`
2554
- height: 100%;
2555
- width: 100%;
2556
- border-radius: 0 0 4px 4px;
2557
- display: flex;
2558
- justify-content: center;
2559
- span {
2560
- font-weight: 600;
2561
- font-size: 14px;
2562
- }
2563
- `;
2564
- const AccordionFooter = styled(Box)`
2565
- overflow: hidden;
2566
- border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};
2567
- border-right: 1px solid ${({ theme }) => theme.colors.neutral200};
2568
- border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
2569
- border-radius: 0 0 ${({ theme }) => theme.borderRadius} ${({ theme }) => theme.borderRadius};
2570
- `;
2571
- const AccordionContent = styled(Box)`
2572
- border-bottom: none;
2573
-
2574
- /* add the borders and make sure the top is transparent to avoid jumping with the hover effect */
2575
- & > div > div {
2576
- border: 1px solid ${({ theme }) => theme.colors.neutral200};
2577
- border-top-color: transparent;
2578
- }
2579
-
2580
- /* the top accordion _does_ need a border though */
2581
- & > div:first-child > div {
2582
- border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
2583
- }
2584
-
2585
- /* Reset all the border-radius' */
2586
- & > div > div,
2587
- & > div > div > div {
2588
- border-radius: unset;
2589
- }
2645
+ const StyledAddIcon = styled(PlusCircle)`
2646
+ height: ${({ theme }) => theme.spaces[6]};
2647
+ width: ${({ theme }) => theme.spaces[6]};
2648
+ transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
2590
2649
 
2591
- /* Give the border radius back to the first accordion */
2592
- & > div:first-child > div,
2593
- & > div:first-child > div > div {
2594
- border-radius: ${({ theme }) => theme.borderRadius} ${({ theme }) => theme.borderRadius} 0 0;
2650
+ > circle {
2651
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2595
2652
  }
2596
-
2597
- & > div > div[data-strapi-expanded='true'] {
2598
- border: 1px solid ${({ theme }) => theme.colors.primary600};
2653
+ > path {
2654
+ fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral500};
2599
2655
  }
2600
2656
  `;
2601
- const AccordionGroup = ({ children, error }) => {
2602
- return /* @__PURE__ */ jsxs(KeyboardNavigable, { attributeName: "data-strapi-accordion-toggle", children: [
2603
- children,
2604
- error && /* @__PURE__ */ jsx(Box, { paddingTop: 1, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "danger600", children: error }) })
2657
+ const StyledButton = styled(Button)`
2658
+ padding-left: ${({ theme }) => theme.spaces[3]};
2659
+ border-radius: 26px;
2660
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2661
+ height: 5rem;
2662
+ `;
2663
+ const ComponentCategory = ({
2664
+ category,
2665
+ components = [],
2666
+ variant = "primary",
2667
+ onAddComponent
2668
+ }) => {
2669
+ const { formatMessage } = useIntl();
2670
+ return /* @__PURE__ */ jsxs(Accordion.Item, { value: category, children: [
2671
+ /* @__PURE__ */ jsx(Accordion.Header, { variant, children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: formatMessage({ id: category, defaultMessage: category }) }) }),
2672
+ /* @__PURE__ */ jsx(ResponsiveAccordionContent, { children: /* @__PURE__ */ jsx(Grid, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
2673
+ ComponentBox,
2674
+ {
2675
+ tag: "button",
2676
+ type: "button",
2677
+ background: "neutral100",
2678
+ justifyContent: "center",
2679
+ onClick: onAddComponent(uid),
2680
+ hasRadius: true,
2681
+ height: "8.4rem",
2682
+ shrink: 0,
2683
+ borderColor: "neutral200",
2684
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
2685
+ /* @__PURE__ */ jsx(ComponentIcon, { color: "currentColor", background: "primary200", icon }),
2686
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: displayName })
2687
+ ] })
2688
+ },
2689
+ uid
2690
+ )) }) })
2605
2691
  ] });
2606
2692
  };
2607
- const CustomIconButton$1 = styled(IconButton)`
2608
- background-color: transparent;
2693
+ const ResponsiveAccordionContent = styled(Accordion.Content)`
2694
+ container-type: inline-size;
2695
+ `;
2696
+ const Grid = styled(Box)`
2697
+ display: grid;
2698
+ grid-template-columns: repeat(auto-fill, 100%);
2699
+ grid-gap: ${({ theme }) => theme.spaces[1]};
2609
2700
 
2610
- svg {
2611
- path {
2612
- fill: ${({ theme, expanded }) => expanded ? theme.colors.primary600 : theme.colors.neutral600};
2613
- }
2701
+ @container (min-width: ${() => RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
2702
+ grid-template-columns: repeat(auto-fill, 14rem);
2703
+ }
2704
+ `;
2705
+ const ComponentBox = styled(Flex)`
2706
+ color: ${({ theme }) => theme.colors.neutral600};
2707
+ cursor: pointer;
2708
+
2709
+ @media (prefers-reduced-motion: no-preference) {
2710
+ transition: color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
2614
2711
  }
2615
2712
 
2713
+ &:focus,
2616
2714
  &:hover {
2617
- svg {
2618
- path {
2619
- fill: ${({ theme }) => theme.colors.primary600};
2620
- }
2621
- }
2622
- }
2623
- `;
2624
- const ActionsFlex$1 = styled(Flex)`
2625
- & .drag-handle {
2626
- background: unset;
2627
-
2628
- svg {
2629
- path {
2630
- fill: ${({ theme, expanded }) => expanded ? theme.colors.primary600 : void 0};
2631
- }
2632
- }
2633
-
2634
- &:hover {
2635
- svg {
2636
- path {
2637
- /* keeps the hover style of the accordion */
2638
- fill: ${({ theme }) => theme.colors.primary600};
2639
- }
2640
- }
2641
- }
2642
- }
2643
- `;
2644
- const Component = ({
2645
- disabled,
2646
- index,
2647
- isOpen,
2648
- name: name2,
2649
- mainField = {
2650
- name: "id",
2651
- type: "integer"
2652
- },
2653
- children,
2654
- onClickToggle,
2655
- onDeleteComponent,
2656
- toggleCollapses,
2657
- ...dragProps
2658
- }) => {
2659
- const { formatMessage } = useIntl();
2660
- const displayValue = useForm("RepeatableComponent", (state) => {
2661
- return getIn(state.values, [...name2.split("."), mainField.name]);
2662
- });
2663
- const accordionRef = React.useRef(null);
2664
- const componentKey = name2.split(".").slice(0, -1).join(".");
2665
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2666
- type: `${ItemTypes.COMPONENT}_${componentKey}`,
2667
- index,
2668
- item: {
2669
- index,
2670
- displayedValue: displayValue
2671
- },
2672
- onStart() {
2673
- toggleCollapses();
2674
- },
2675
- ...dragProps
2676
- });
2677
- React.useEffect(() => {
2678
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2679
- }, [dragPreviewRef, index]);
2680
- const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
2681
- const composedBoxRefs = useComposedRefs(boxRef, dropRef);
2682
- return /* @__PURE__ */ jsx(Box, { ref: (ref) => composedBoxRefs(ref), children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsxs(Accordion, { expanded: isOpen, onToggle: onClickToggle, id: name2, size: "S", children: [
2683
- /* @__PURE__ */ jsx(
2684
- AccordionToggle,
2685
- {
2686
- action: disabled ? null : /* @__PURE__ */ jsxs(ActionsFlex$1, { gap: 0, expanded: isOpen, children: [
2687
- /* @__PURE__ */ jsx(
2688
- CustomIconButton$1,
2689
- {
2690
- expanded: isOpen,
2691
- borderWidth: 0,
2692
- onClick: onDeleteComponent,
2693
- label: formatMessage({
2694
- id: getTranslation("containers.Edit.delete"),
2695
- defaultMessage: "Delete"
2696
- }),
2697
- icon: /* @__PURE__ */ jsx(Trash, {})
2698
- }
2699
- ),
2700
- /* @__PURE__ */ jsx(
2701
- IconButton,
2702
- {
2703
- className: "drag-handle",
2704
- ref: composedAccordionRefs,
2705
- forwardedAs: "div",
2706
- role: "button",
2707
- borderWidth: 0,
2708
- tabIndex: 0,
2709
- onClick: (e) => e.stopPropagation(),
2710
- "data-handler-id": handlerId,
2711
- label: formatMessage({
2712
- id: getTranslation("components.DragHandle-label"),
2713
- defaultMessage: "Drag"
2714
- }),
2715
- onKeyDown: handleKeyDown,
2716
- children: /* @__PURE__ */ jsx(Drag, {})
2717
- }
2718
- )
2719
- ] }),
2720
- title: displayValue,
2721
- togglePosition: "left"
2722
- }
2723
- ),
2724
- /* @__PURE__ */ jsx(AccordionContent$1, { children: /* @__PURE__ */ jsx(
2725
- Flex,
2726
- {
2727
- direction: "column",
2728
- alignItems: "stretch",
2729
- background: "neutral100",
2730
- padding: 6,
2731
- gap: 6,
2732
- children
2733
- }
2734
- ) })
2735
- ] }) });
2736
- };
2737
- const Preview$1 = () => {
2738
- return /* @__PURE__ */ jsx(StyledSpan, { as: "span", padding: 6, background: "primary100" });
2739
- };
2740
- const StyledSpan = styled(Box)`
2741
- display: block;
2742
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2743
- outline-offset: -1px;
2744
- `;
2745
- const ComponentInput = ({
2746
- label,
2747
- required,
2748
- name: name2,
2749
- attribute,
2750
- disabled,
2751
- labelAction,
2752
- ...props
2753
- }) => {
2754
- const { formatMessage } = useIntl();
2755
- const field = useField(name2);
2756
- const showResetComponent = !attribute.repeatable && field.value && !disabled;
2757
- const { components } = useDoc();
2758
- const handleInitialisationClick = () => {
2759
- const schema = components[attribute.component];
2760
- const form = createDefaultForm(schema, components);
2761
- const data = transformDocument(schema, components)(form);
2762
- field.onChange(name2, data);
2763
- };
2764
- return /* @__PURE__ */ jsxs(Box, { children: [
2765
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
2766
- /* @__PURE__ */ jsxs(Flex, { paddingBottom: 1, children: [
2767
- /* @__PURE__ */ jsxs(
2768
- Typography,
2769
- {
2770
- textColor: "neutral800",
2771
- htmlFor: name2,
2772
- variant: "pi",
2773
- fontWeight: "bold",
2774
- as: "label",
2775
- children: [
2776
- label,
2777
- attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
2778
- " (",
2779
- Array.isArray(field.value) ? field.value.length : 0,
2780
- ")"
2781
- ] }),
2782
- required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" })
2783
- ]
2784
- }
2785
- ),
2786
- labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
2787
- ] }),
2788
- showResetComponent && /* @__PURE__ */ jsx(
2789
- IconButton,
2790
- {
2791
- label: formatMessage({
2792
- id: getTranslation("components.reset-entry"),
2793
- defaultMessage: "Reset Entry"
2794
- }),
2795
- icon: /* @__PURE__ */ jsx(Trash, {}),
2796
- borderWidth: 0,
2797
- onClick: () => {
2798
- field.onChange(name2, null);
2799
- }
2800
- }
2801
- )
2802
- ] }),
2803
- /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
2804
- !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
2805
- !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
2806
- attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children })
2807
- ] })
2808
- ] });
2809
- };
2810
- const AddComponentButton = ({
2811
- hasError,
2812
- isDisabled,
2813
- isOpen,
2814
- children,
2815
- onClick
2816
- }) => {
2817
- return /* @__PURE__ */ jsx(
2818
- StyledButton,
2819
- {
2820
- type: "button",
2821
- onClick,
2822
- disabled: isDisabled,
2823
- background: "neutral0",
2824
- paddingTop: 3,
2825
- paddingBottom: 3,
2826
- paddingLeft: 4,
2827
- paddingRight: 4,
2828
- style: { cursor: isDisabled ? "not-allowed" : "pointer" },
2829
- children: /* @__PURE__ */ jsxs(Flex, { as: "span", gap: 2, children: [
2830
- /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true, $isOpen: isOpen, $hasError: hasError && !isOpen }),
2831
- /* @__PURE__ */ jsx(
2832
- Typography,
2833
- {
2834
- variant: "pi",
2835
- fontWeight: "bold",
2836
- textColor: hasError && !isOpen ? "danger600" : "neutral500",
2837
- children
2838
- }
2839
- )
2840
- ] })
2841
- }
2842
- );
2843
- };
2844
- const StyledAddIcon = styled(PlusCircle)`
2845
- height: ${({ theme }) => theme.spaces[6]};
2846
- width: ${({ theme }) => theme.spaces[6]};
2847
- transform: ${({ $isOpen }) => $isOpen ? "rotate(45deg)" : "rotate(0deg)"};
2848
-
2849
- > circle {
2850
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger200 : theme.colors.neutral150};
2851
- }
2852
- > path {
2853
- fill: ${({ theme, $hasError }) => $hasError ? theme.colors.danger600 : theme.colors.neutral600};
2854
- }
2855
- `;
2856
- const StyledButton = styled(BaseButton)`
2857
- border-radius: 26px;
2858
- border-color: ${({ theme }) => theme.colors.neutral150};
2859
- box-shadow: ${({ theme }) => theme.shadows.filterShadow};
2860
-
2861
- &:hover {
2862
- ${Typography} {
2863
- color: ${({ theme }) => theme.colors.primary600};
2864
- }
2865
-
2866
- ${StyledAddIcon} {
2867
- > circle {
2868
- fill: ${({ theme }) => theme.colors.primary600};
2869
- }
2870
- > path {
2871
- fill: ${({ theme }) => theme.colors.neutral100};
2872
- }
2873
- }
2874
- }
2875
- &:active {
2876
- ${Typography} {
2877
- color: ${({ theme }) => theme.colors.primary600};
2878
- }
2879
- ${StyledAddIcon} {
2880
- > circle {
2881
- fill: ${({ theme }) => theme.colors.primary600};
2882
- }
2883
- > path {
2884
- fill: ${({ theme }) => theme.colors.neutral100};
2885
- }
2886
- }
2887
- }
2888
- `;
2889
- const ComponentCategory = ({
2890
- category,
2891
- components = [],
2892
- variant = "primary",
2893
- isOpen,
2894
- onAddComponent,
2895
- onToggle
2896
- }) => {
2897
- const { formatMessage } = useIntl();
2898
- const handleToggle = () => {
2899
- onToggle(category);
2900
- };
2901
- return /* @__PURE__ */ jsxs(Accordion, { expanded: isOpen, onToggle: handleToggle, size: "S", children: [
2902
- /* @__PURE__ */ jsx(
2903
- AccordionToggle,
2904
- {
2905
- variant,
2906
- title: formatMessage({ id: category, defaultMessage: category }),
2907
- togglePosition: "left"
2908
- }
2909
- ),
2910
- /* @__PURE__ */ jsx(AccordionContent$1, { children: /* @__PURE__ */ jsx(Box, { paddingTop: 4, paddingBottom: 4, paddingLeft: 3, paddingRight: 3, children: /* @__PURE__ */ jsx(Grid, { children: components.map(({ uid, displayName, icon }) => /* @__PURE__ */ jsx(
2911
- ComponentBox,
2912
- {
2913
- as: "button",
2914
- type: "button",
2915
- background: "neutral100",
2916
- justifyContent: "center",
2917
- onClick: onAddComponent(uid),
2918
- hasRadius: true,
2919
- height: "8.4rem",
2920
- shrink: 0,
2921
- borderColor: "neutral200",
2922
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, alignItems: "center", justifyContent: "center", children: [
2923
- /* @__PURE__ */ jsx(ComponentIcon, { icon }),
2924
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral600", children: displayName })
2925
- ] })
2926
- },
2927
- uid
2928
- )) }) }) })
2929
- ] });
2930
- };
2931
- const Grid = styled.div`
2932
- display: grid;
2933
- grid-template-columns: repeat(auto-fit, 14rem);
2934
- grid-gap: ${({ theme }) => theme.spaces[1]};
2935
- `;
2936
- const ComponentBox = styled(Flex)`
2937
- &:focus,
2938
- &:hover {
2939
- border: 1px solid ${({ theme }) => theme.colors.primary200};
2940
- background: ${({ theme }) => theme.colors.primary100};
2941
-
2942
- ${Typography} {
2943
- color: ${({ theme }) => theme.colors.primary600};
2944
- }
2945
-
2946
- /* > Flex > ComponentIcon */
2947
- > div > div:first-child {
2948
- background: ${({ theme }) => theme.colors.primary200};
2949
- color: ${({ theme }) => theme.colors.primary600};
2950
- }
2715
+ border: 1px solid ${({ theme }) => theme.colors.primary200};
2716
+ background: ${({ theme }) => theme.colors.primary100};
2717
+ color: ${({ theme }) => theme.colors.primary600};
2951
2718
  }
2952
2719
  `;
2953
2720
  const ComponentPicker = ({
@@ -2956,19 +2723,8 @@ const ComponentPicker = ({
2956
2723
  onClickAddComponent
2957
2724
  }) => {
2958
2725
  const { formatMessage } = useIntl();
2959
- const [categoryToOpen, setCategoryToOpen] = React.useState("");
2960
- React.useEffect(() => {
2961
- const categoryKeys = Object.keys(dynamicComponentsByCategory);
2962
- if (isOpen && categoryKeys.length > 0) {
2963
- setCategoryToOpen(categoryKeys[0]);
2964
- }
2965
- }, [isOpen, dynamicComponentsByCategory]);
2966
2726
  const handleAddComponentToDz = (componentUid) => () => {
2967
2727
  onClickAddComponent(componentUid);
2968
- setCategoryToOpen("");
2969
- };
2970
- const handleClickToggle = (categoryName) => {
2971
- setCategoryToOpen((currentCat) => currentCat === categoryName ? "" : categoryName);
2972
2728
  };
2973
2729
  if (!isOpen) {
2974
2730
  return null;
@@ -2989,14 +2745,12 @@ const ComponentPicker = ({
2989
2745
  id: getTranslation("components.DynamicZone.ComponentPicker-label"),
2990
2746
  defaultMessage: "Pick one component"
2991
2747
  }) }) }),
2992
- /* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(KeyboardNavigable, { attributeName: "data-strapi-accordion-toggle", children: Object.entries(dynamicComponentsByCategory).map(([category, components], index) => /* @__PURE__ */ jsx(
2748
+ /* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(Accordion.Root, { defaultValue: Object.keys(dynamicComponentsByCategory)[0], children: Object.entries(dynamicComponentsByCategory).map(([category, components], index) => /* @__PURE__ */ jsx(
2993
2749
  ComponentCategory,
2994
2750
  {
2995
2751
  category,
2996
2752
  components,
2997
2753
  onAddComponent: handleAddComponentToDz,
2998
- isOpen: category === categoryToOpen,
2999
- onToggle: handleClickToggle,
3000
2754
  variant: index % 2 === 1 ? "primary" : "secondary"
3001
2755
  },
3002
2756
  category
@@ -3005,45 +2759,493 @@ const ComponentPicker = ({
3005
2759
  }
3006
2760
  );
3007
2761
  };
2762
+ const DynamicComponent = ({
2763
+ componentUid,
2764
+ disabled,
2765
+ index,
2766
+ name: name2,
2767
+ onRemoveComponentClick,
2768
+ onMoveComponent,
2769
+ onGrabItem,
2770
+ onDropItem,
2771
+ onCancel,
2772
+ dynamicComponentsByCategory = {},
2773
+ onAddComponent,
2774
+ children
2775
+ }) => {
2776
+ const { formatMessage } = useIntl();
2777
+ const formValues = useForm("DynamicComponent", (state) => state.values);
2778
+ const {
2779
+ edit: { components }
2780
+ } = useDocLayout();
2781
+ const title = React.useMemo(() => {
2782
+ const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
2783
+ const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
2784
+ const displayedValue = mainField === "id" || !mainFieldValue ? "" : String(mainFieldValue).trim();
2785
+ const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
2786
+ return mainValue;
2787
+ }, [componentUid, components, formValues, name2, index]);
2788
+ const { icon, displayName } = React.useMemo(() => {
2789
+ const [category] = componentUid.split(".");
2790
+ const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
2791
+ (component) => component.uid === componentUid
2792
+ ) ?? { icon: null, displayName: null };
2793
+ return { icon: icon2, displayName: displayName2 };
2794
+ }, [componentUid, dynamicComponentsByCategory]);
2795
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
2796
+ type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
2797
+ index,
2798
+ item: {
2799
+ index,
2800
+ displayedValue: `${displayName} ${title}`,
2801
+ icon
2802
+ },
2803
+ onMoveItem: onMoveComponent,
2804
+ onDropItem,
2805
+ onGrabItem,
2806
+ onCancel
2807
+ });
2808
+ React.useEffect(() => {
2809
+ dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
2810
+ }, [dragPreviewRef, index]);
2811
+ const accordionValue = React.useId();
2812
+ const { value = [], rawError } = useField(`${name2}.${index}`);
2813
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
2814
+ React.useEffect(() => {
2815
+ if (rawError && value) {
2816
+ setCollapseToOpen(accordionValue);
2817
+ }
2818
+ }, [rawError, value, accordionValue]);
2819
+ const composedBoxRefs = useComposedRefs(boxRef, dropRef);
2820
+ const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
2821
+ /* @__PURE__ */ jsx(
2822
+ IconButton,
2823
+ {
2824
+ variant: "ghost",
2825
+ label: formatMessage(
2826
+ {
2827
+ id: getTranslation("components.DynamicZone.delete-label"),
2828
+ defaultMessage: "Delete {name}"
2829
+ },
2830
+ { name: title }
2831
+ ),
2832
+ onClick: onRemoveComponentClick,
2833
+ children: /* @__PURE__ */ jsx(Trash, {})
2834
+ }
2835
+ ),
2836
+ /* @__PURE__ */ jsx(
2837
+ IconButton,
2838
+ {
2839
+ variant: "ghost",
2840
+ onClick: (e) => e.stopPropagation(),
2841
+ "data-handler-id": handlerId,
2842
+ ref: dragRef,
2843
+ label: formatMessage({
2844
+ id: getTranslation("components.DragHandle-label"),
2845
+ defaultMessage: "Drag"
2846
+ }),
2847
+ onKeyDown: handleKeyDown,
2848
+ children: /* @__PURE__ */ jsx(Drag, {})
2849
+ }
2850
+ ),
2851
+ /* @__PURE__ */ jsxs(Menu.Root, { children: [
2852
+ /* @__PURE__ */ jsx(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 0, paddingRight: 0, children: /* @__PURE__ */ jsx(
2853
+ IconButton,
2854
+ {
2855
+ variant: "ghost",
2856
+ label: formatMessage({
2857
+ id: getTranslation("components.DynamicZone.more-actions"),
2858
+ defaultMessage: "More actions"
2859
+ }),
2860
+ tag: "span",
2861
+ children: /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false })
2862
+ }
2863
+ ) }),
2864
+ /* @__PURE__ */ jsxs(Menu.Content, { children: [
2865
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2866
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2867
+ id: getTranslation("components.DynamicZone.add-item-above"),
2868
+ defaultMessage: "Add component above"
2869
+ }) }),
2870
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2871
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2872
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
2873
+ ] }, category)) })
2874
+ ] }),
2875
+ /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
2876
+ /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
2877
+ id: getTranslation("components.DynamicZone.add-item-below"),
2878
+ defaultMessage: "Add component below"
2879
+ }) }),
2880
+ /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
2881
+ /* @__PURE__ */ jsx(Menu.Label, { children: category }),
2882
+ components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
2883
+ ] }, category)) })
2884
+ ] })
2885
+ ] })
2886
+ ] })
2887
+ ] });
2888
+ const accordionTitle = title ? `${displayName} ${title}` : displayName;
2889
+ return /* @__PURE__ */ jsxs(ComponentContainer, { tag: "li", width: "100%", children: [
2890
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
2891
+ /* @__PURE__ */ jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsx(Preview$1, {}) : /* @__PURE__ */ jsx(Accordion.Root, { value: collapseToOpen, onValueChange: setCollapseToOpen, children: /* @__PURE__ */ jsxs(Accordion.Item, { value: accordionValue, children: [
2892
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
2893
+ /* @__PURE__ */ jsx(
2894
+ Accordion.Trigger,
2895
+ {
2896
+ icon: icon && COMPONENT_ICONS[icon] ? COMPONENT_ICONS[icon] : COMPONENT_ICONS.dashboard,
2897
+ children: accordionTitle
2898
+ }
2899
+ ),
2900
+ /* @__PURE__ */ jsx(Accordion.Actions, { children: accordionActions })
2901
+ ] }),
2902
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsx(Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsx(
2903
+ Grid$1.Item,
2904
+ {
2905
+ col: 12,
2906
+ s: 12,
2907
+ xs: 12,
2908
+ direction: "column",
2909
+ alignItems: "stretch",
2910
+ children: /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
2911
+ const fieldName = `${name2}.${index}.${field.name}`;
2912
+ const fieldWithTranslatedLabel = {
2913
+ ...field,
2914
+ label: formatMessage({
2915
+ id: `content-manager.components.${componentUid}.${field.name}`,
2916
+ defaultMessage: field.label
2917
+ })
2918
+ };
2919
+ return /* @__PURE__ */ jsx(
2920
+ ResponsiveGridItem,
2921
+ {
2922
+ col: size,
2923
+ s: 12,
2924
+ xs: 12,
2925
+ direction: "column",
2926
+ alignItems: "stretch",
2927
+ children: children ? children({ ...fieldWithTranslatedLabel, name: fieldName }) : /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel, name: fieldName })
2928
+ },
2929
+ fieldName
2930
+ );
2931
+ }) })
2932
+ },
2933
+ rowInd
2934
+ )) }) }) }) })
2935
+ ] }) }) })
2936
+ ] });
2937
+ };
2938
+ const StyledBox = styled(Box)`
2939
+ > div:first-child {
2940
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
2941
+ }
2942
+ `;
2943
+ const AccordionContentRadius = styled(Box)`
2944
+ border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
2945
+ `;
2946
+ const Rectangle = styled(Box)`
2947
+ width: ${({ theme }) => theme.spaces[2]};
2948
+ height: ${({ theme }) => theme.spaces[4]};
2949
+ `;
2950
+ const Preview$1 = styled.span`
2951
+ display: block;
2952
+ background-color: ${({ theme }) => theme.colors.primary100};
2953
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
2954
+ outline-offset: -1px;
2955
+ padding: ${({ theme }) => theme.spaces[6]};
2956
+ `;
2957
+ const ComponentContainer = styled(Box)`
2958
+ list-style: none;
2959
+ padding: 0;
2960
+ margin: 0;
2961
+ `;
2962
+ const DynamicZoneLabel = ({
2963
+ hint,
2964
+ label,
2965
+ labelAction,
2966
+ name: name2,
2967
+ numberOfComponents = 0,
2968
+ required
2969
+ }) => {
2970
+ return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
2971
+ Box,
2972
+ {
2973
+ paddingTop: 3,
2974
+ paddingBottom: 3,
2975
+ paddingRight: 4,
2976
+ paddingLeft: 4,
2977
+ borderRadius: "26px",
2978
+ background: "neutral0",
2979
+ shadow: "filterShadow",
2980
+ color: "neutral500",
2981
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
2982
+ /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
2983
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
2984
+ label || name2,
2985
+ " "
2986
+ ] }),
2987
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
2988
+ "(",
2989
+ numberOfComponents,
2990
+ ")"
2991
+ ] }),
2992
+ required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
2993
+ labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
2994
+ ] }),
2995
+ hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
2996
+ ] })
2997
+ }
2998
+ ) });
2999
+ };
3000
+ const [DynamicZoneProvider, useDynamicZone] = createContext(
3001
+ "DynamicZone",
3002
+ {
3003
+ isInDynamicZone: false
3004
+ }
3005
+ );
3006
+ const DynamicZone = ({
3007
+ attribute,
3008
+ disabled: disabledProp,
3009
+ hint,
3010
+ label,
3011
+ labelAction,
3012
+ name: name2,
3013
+ required = false,
3014
+ children
3015
+ }) => {
3016
+ const { max = Infinity, min = -Infinity } = attribute ?? {};
3017
+ const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
3018
+ const [liveText, setLiveText] = React.useState("");
3019
+ const { components, isLoading } = useDoc();
3020
+ const disabled = disabledProp || isLoading;
3021
+ const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
3022
+ "DynamicZone",
3023
+ ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
3024
+ addFieldRow: addFieldRow2,
3025
+ removeFieldRow: removeFieldRow2,
3026
+ moveFieldRow: moveFieldRow2
3027
+ })
3028
+ );
3029
+ const { value = [], error } = useField(name2);
3030
+ const dynamicComponentsByCategory = React.useMemo(() => {
3031
+ return attribute.components.reduce((acc, componentUid) => {
3032
+ const { category, info } = components[componentUid] ?? { info: {} };
3033
+ const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
3034
+ if (!acc[category]) {
3035
+ acc[category] = [];
3036
+ }
3037
+ acc[category] = [...acc[category], component];
3038
+ return acc;
3039
+ }, {});
3040
+ }, [attribute.components, components]);
3041
+ const { formatMessage } = useIntl();
3042
+ const { toggleNotification } = useNotification();
3043
+ const dynamicDisplayedComponentsLength = value.length;
3044
+ const handleAddComponent = (uid, position) => {
3045
+ setAddComponentIsOpen(false);
3046
+ const schema = components[uid];
3047
+ const form = createDefaultForm(schema, components);
3048
+ const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
3049
+ ...data2,
3050
+ __component: uid
3051
+ }));
3052
+ const data = transformations(form);
3053
+ addFieldRow(name2, data, position);
3054
+ };
3055
+ const handleClickOpenPicker = () => {
3056
+ if (dynamicDisplayedComponentsLength < max) {
3057
+ setAddComponentIsOpen((prev) => !prev);
3058
+ } else {
3059
+ toggleNotification({
3060
+ type: "info",
3061
+ message: formatMessage({
3062
+ id: getTranslation("components.notification.info.maximum-requirement")
3063
+ })
3064
+ });
3065
+ }
3066
+ };
3067
+ const handleMoveComponent = (newIndex, currentIndex) => {
3068
+ setLiveText(
3069
+ formatMessage(
3070
+ {
3071
+ id: getTranslation("dnd.reorder"),
3072
+ defaultMessage: "{item}, moved. New position in list: {position}."
3073
+ },
3074
+ {
3075
+ item: `${name2}.${currentIndex}`,
3076
+ position: getItemPos(newIndex)
3077
+ }
3078
+ )
3079
+ );
3080
+ moveFieldRow(name2, currentIndex, newIndex);
3081
+ };
3082
+ const getItemPos = (index) => `${index + 1} of ${value.length}`;
3083
+ const handleCancel = (index) => {
3084
+ setLiveText(
3085
+ formatMessage(
3086
+ {
3087
+ id: getTranslation("dnd.cancel-item"),
3088
+ defaultMessage: "{item}, dropped. Re-order cancelled."
3089
+ },
3090
+ {
3091
+ item: `${name2}.${index}`
3092
+ }
3093
+ )
3094
+ );
3095
+ };
3096
+ const handleGrabItem = (index) => {
3097
+ setLiveText(
3098
+ formatMessage(
3099
+ {
3100
+ id: getTranslation("dnd.grab-item"),
3101
+ defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
3102
+ },
3103
+ {
3104
+ item: `${name2}.${index}`,
3105
+ position: getItemPos(index)
3106
+ }
3107
+ )
3108
+ );
3109
+ };
3110
+ const handleDropItem = (index) => {
3111
+ setLiveText(
3112
+ formatMessage(
3113
+ {
3114
+ id: getTranslation("dnd.drop-item"),
3115
+ defaultMessage: `{item}, dropped. Final position in list: {position}.`
3116
+ },
3117
+ {
3118
+ item: `${name2}.${index}`,
3119
+ position: getItemPos(index)
3120
+ }
3121
+ )
3122
+ );
3123
+ };
3124
+ const handleRemoveComponent = (name22, currentIndex) => () => {
3125
+ removeFieldRow(name22, currentIndex);
3126
+ };
3127
+ const hasError = error !== void 0;
3128
+ const renderButtonLabel = () => {
3129
+ if (addComponentIsOpen) {
3130
+ return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
3131
+ }
3132
+ if (hasError && dynamicDisplayedComponentsLength > max) {
3133
+ return formatMessage(
3134
+ {
3135
+ id: getTranslation(`components.DynamicZone.extra-components`),
3136
+ defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
3137
+ },
3138
+ {
3139
+ number: dynamicDisplayedComponentsLength - max
3140
+ }
3141
+ );
3142
+ }
3143
+ if (hasError && dynamicDisplayedComponentsLength < min) {
3144
+ return formatMessage(
3145
+ {
3146
+ id: getTranslation(`components.DynamicZone.missing-components`),
3147
+ defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
3148
+ },
3149
+ { number: min - dynamicDisplayedComponentsLength }
3150
+ );
3151
+ }
3152
+ return formatMessage(
3153
+ {
3154
+ id: getTranslation("components.DynamicZone.add-component"),
3155
+ defaultMessage: "Add a component to {componentName}"
3156
+ },
3157
+ { componentName: label || name2 }
3158
+ );
3159
+ };
3160
+ const level = useComponent("DynamicZone", (state) => state.level);
3161
+ const ariaDescriptionId = React.useId();
3162
+ return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
3163
+ dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
3164
+ /* @__PURE__ */ jsx(
3165
+ DynamicZoneLabel,
3166
+ {
3167
+ hint,
3168
+ label,
3169
+ labelAction,
3170
+ name: name2,
3171
+ numberOfComponents: dynamicDisplayedComponentsLength,
3172
+ required
3173
+ }
3174
+ ),
3175
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
3176
+ id: getTranslation("dnd.instructions"),
3177
+ defaultMessage: `Press spacebar to grab and re-order`
3178
+ }) }),
3179
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
3180
+ /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
3181
+ ComponentProvider,
3182
+ {
3183
+ level: level + 1,
3184
+ uid: field.__component,
3185
+ id: field.id,
3186
+ type: "dynamiczone",
3187
+ children: /* @__PURE__ */ jsx(
3188
+ DynamicComponent,
3189
+ {
3190
+ disabled,
3191
+ name: name2,
3192
+ index,
3193
+ componentUid: field.__component,
3194
+ onMoveComponent: handleMoveComponent,
3195
+ onRemoveComponentClick: handleRemoveComponent(name2, index),
3196
+ onCancel: handleCancel,
3197
+ onDropItem: handleDropItem,
3198
+ onGrabItem: handleGrabItem,
3199
+ onAddComponent: handleAddComponent,
3200
+ dynamicComponentsByCategory,
3201
+ children
3202
+ }
3203
+ )
3204
+ },
3205
+ field.__temp_key__
3206
+ )) })
3207
+ ] }),
3208
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
3209
+ AddComponentButton,
3210
+ {
3211
+ hasError,
3212
+ isDisabled: disabled,
3213
+ isOpen: addComponentIsOpen,
3214
+ onClick: handleClickOpenPicker,
3215
+ children: renderButtonLabel()
3216
+ }
3217
+ ) }),
3218
+ /* @__PURE__ */ jsx(
3219
+ ComponentPicker,
3220
+ {
3221
+ dynamicComponentsByCategory,
3222
+ isOpen: addComponentIsOpen,
3223
+ onClickAddComponent: handleAddComponent
3224
+ }
3225
+ )
3226
+ ] }) });
3227
+ };
3008
3228
  const NotAllowedInput = ({ hint, label, required, name: name2 }) => {
3009
3229
  const { formatMessage } = useIntl();
3010
3230
  const placeholder = formatMessage({
3011
3231
  id: "components.NotAllowedInput.text",
3012
3232
  defaultMessage: "No permissions to see this field"
3013
3233
  });
3014
- return /* @__PURE__ */ jsx(
3015
- TextInput,
3016
- {
3017
- disabled: true,
3018
- label,
3019
- id: name2,
3020
- hint,
3021
- name: name2,
3022
- placeholder,
3023
- required,
3024
- startAction: /* @__PURE__ */ jsx(StyledIcon, {}),
3025
- type: "text",
3026
- value: ""
3027
- }
3028
- );
3234
+ return /* @__PURE__ */ jsxs(Field.Root, { id: name2, hint, name: name2, required, children: [
3235
+ /* @__PURE__ */ jsx(Field.Label, { children: label }),
3236
+ /* @__PURE__ */ jsx(
3237
+ TextInput,
3238
+ {
3239
+ disabled: true,
3240
+ placeholder,
3241
+ startAction: /* @__PURE__ */ jsx(EyeStriked, { fill: "neutral600" }),
3242
+ type: "text",
3243
+ value: ""
3244
+ }
3245
+ ),
3246
+ /* @__PURE__ */ jsx(Field.Hint, {})
3247
+ ] });
3029
3248
  };
3030
- const StyledIcon = styled(EyeStriked)`
3031
- & > path {
3032
- fill: ${({ theme }) => theme.colors.neutral600};
3033
- }
3034
- `;
3035
- function useDebounce(value, delay) {
3036
- const [debouncedValue, setDebouncedValue] = useState(value);
3037
- useEffect(() => {
3038
- const handler = setTimeout(() => {
3039
- setDebouncedValue(value);
3040
- }, delay);
3041
- return () => {
3042
- clearTimeout(handler);
3043
- };
3044
- }, [value, delay]);
3045
- return debouncedValue;
3046
- }
3047
3249
  const uidApi = contentManagerApi.injectEndpoints({
3048
3250
  endpoints: (builder) => ({
3049
3251
  getDefaultUID: builder.query({
@@ -3078,194 +3280,206 @@ const uidApi = contentManagerApi.injectEndpoints({
3078
3280
  config: {
3079
3281
  params
3080
3282
  }
3081
- })
3283
+ }),
3284
+ providesTags: (_res, _error, params) => [
3285
+ { type: "UidAvailability", id: params.contentTypeUID }
3286
+ ]
3082
3287
  })
3083
3288
  })
3084
3289
  });
3085
3290
  const { useGenerateUIDMutation, useGetDefaultUIDQuery, useGetAvailabilityQuery } = uidApi;
3086
3291
  const UID_REGEX = /^[A-Za-z0-9-_.~]*$/;
3087
- const UIDInput = React.forwardRef((props, ref) => {
3088
- const { model, id } = useDoc();
3089
- const allFormValues = useForm("InputUID", (form) => form.values);
3090
- const [availability, setAvailability] = React.useState();
3091
- const [showRegenerate, setShowRegenerate] = React.useState(false);
3092
- const field = useField(props.name);
3093
- const debouncedValue = useDebounce(field.value, 300);
3094
- const { toggleNotification } = useNotification();
3095
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
3096
- const { formatMessage } = useIntl();
3097
- const [{ query }] = useQueryParams();
3098
- const params = React.useMemo(() => buildValidParams(query), [query]);
3099
- const {
3100
- data: defaultGeneratedUID,
3101
- isLoading: isGeneratingDefaultUID,
3102
- error: apiError
3103
- } = useGetDefaultUIDQuery(
3104
- {
3105
- contentTypeUID: model,
3106
- field: props.name,
3107
- data: {
3108
- id: id ?? "",
3109
- ...allFormValues
3110
- },
3111
- params
3112
- },
3113
- {
3114
- skip: field.value || !props.required
3115
- }
3116
- );
3117
- React.useEffect(() => {
3118
- if (apiError) {
3119
- toggleNotification({
3120
- type: "warning",
3121
- message: formatAPIError(apiError)
3122
- });
3123
- }
3124
- }, [apiError, formatAPIError, toggleNotification]);
3125
- React.useEffect(() => {
3126
- if (defaultGeneratedUID && field.value === void 0) {
3127
- field.onChange(props.name, defaultGeneratedUID);
3128
- }
3129
- }, [defaultGeneratedUID, field, props.name]);
3130
- const [generateUID, { isLoading: isGeneratingUID }] = useGenerateUIDMutation();
3131
- const handleRegenerateClick = async () => {
3132
- try {
3133
- const res = await generateUID({
3292
+ const UIDInput = React.forwardRef(
3293
+ ({ hint, label, labelAction, name: name2, required, ...props }, ref) => {
3294
+ const { model, id } = useDoc();
3295
+ const allFormValues = useForm("InputUID", (form) => form.values);
3296
+ const [availability, setAvailability] = React.useState();
3297
+ const [showRegenerate, setShowRegenerate] = React.useState(false);
3298
+ const isCloning = useMatch(CLONE_PATH) !== null;
3299
+ const field = useField(name2);
3300
+ const debouncedValue = useDebounce(field.value, 300);
3301
+ const hasChanged = debouncedValue !== field.initialValue;
3302
+ const { toggleNotification } = useNotification();
3303
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
3304
+ const { formatMessage } = useIntl();
3305
+ const [{ query }] = useQueryParams();
3306
+ const params = React.useMemo(() => buildValidParams(query), [query]);
3307
+ const {
3308
+ data: defaultGeneratedUID,
3309
+ isLoading: isGeneratingDefaultUID,
3310
+ error: apiError
3311
+ } = useGetDefaultUIDQuery(
3312
+ {
3134
3313
  contentTypeUID: model,
3135
- field: props.name,
3136
- data: { id: id ?? "", ...allFormValues },
3314
+ field: name2,
3315
+ data: {
3316
+ id: id ?? "",
3317
+ ...allFormValues
3318
+ },
3137
3319
  params
3138
- });
3139
- if ("data" in res) {
3140
- field.onChange(props.name, res.data);
3141
- } else {
3320
+ },
3321
+ {
3322
+ skip: field.value || !required
3323
+ }
3324
+ );
3325
+ React.useEffect(() => {
3326
+ if (apiError) {
3142
3327
  toggleNotification({
3143
- type: "danger",
3144
- message: formatAPIError(res.error)
3328
+ type: "warning",
3329
+ message: formatAPIError(apiError)
3145
3330
  });
3146
3331
  }
3147
- } catch (err) {
3148
- toggleNotification({
3149
- type: "danger",
3150
- message: formatMessage({
3151
- id: "notification.error",
3152
- defaultMessage: "An error occurred."
3153
- })
3154
- });
3155
- }
3156
- };
3157
- const {
3158
- data: availabilityData,
3159
- isLoading: isCheckingAvailability,
3160
- error: availabilityError
3161
- } = useGetAvailabilityQuery(
3162
- {
3163
- contentTypeUID: model,
3164
- field: props.name,
3165
- value: debouncedValue ? debouncedValue.trim() : "",
3166
- params
3167
- },
3168
- {
3169
- skip: !Boolean(
3170
- debouncedValue !== field.initialValue && debouncedValue && UID_REGEX.test(debouncedValue.trim())
3171
- )
3172
- }
3173
- );
3174
- React.useEffect(() => {
3175
- if (availabilityError) {
3176
- toggleNotification({
3177
- type: "warning",
3178
- message: formatAPIError(availabilityError)
3179
- });
3180
- }
3181
- }, [availabilityError, formatAPIError, toggleNotification]);
3182
- React.useEffect(() => {
3183
- setAvailability(availabilityData);
3184
- let timer;
3185
- if (availabilityData?.isAvailable) {
3186
- timer = window.setTimeout(() => {
3187
- setAvailability(void 0);
3188
- }, 4e3);
3189
- }
3190
- return () => {
3191
- if (timer) {
3192
- clearTimeout(timer);
3332
+ }, [apiError, formatAPIError, toggleNotification]);
3333
+ React.useEffect(() => {
3334
+ if (defaultGeneratedUID && field.value === void 0) {
3335
+ field.onChange(name2, defaultGeneratedUID);
3336
+ }
3337
+ }, [defaultGeneratedUID, field, name2]);
3338
+ const [generateUID, { isLoading: isGeneratingUID }] = useGenerateUIDMutation();
3339
+ const handleRegenerateClick = async () => {
3340
+ try {
3341
+ const res = await generateUID({
3342
+ contentTypeUID: model,
3343
+ field: name2,
3344
+ data: { id: id ?? "", ...allFormValues },
3345
+ params
3346
+ });
3347
+ if ("data" in res) {
3348
+ field.onChange(name2, res.data);
3349
+ } else {
3350
+ toggleNotification({
3351
+ type: "danger",
3352
+ message: formatAPIError(res.error)
3353
+ });
3354
+ }
3355
+ } catch (err) {
3356
+ toggleNotification({
3357
+ type: "danger",
3358
+ message: formatMessage({
3359
+ id: "notification.error",
3360
+ defaultMessage: "An error occurred."
3361
+ })
3362
+ });
3193
3363
  }
3194
3364
  };
3195
- }, [availabilityData]);
3196
- const isLoading = isGeneratingDefaultUID || isGeneratingUID || isCheckingAvailability;
3197
- const fieldRef = useFocusInputField(props.name);
3198
- const composedRefs = useComposedRefs(ref, fieldRef);
3199
- return (
3200
- // @ts-expect-error – label _could_ be a ReactNode since it's a child, this should be fixed in the DS.
3201
- /* @__PURE__ */ jsx(
3202
- TextInput,
3365
+ const {
3366
+ data: availabilityData,
3367
+ isLoading: isCheckingAvailability,
3368
+ error: availabilityError
3369
+ } = useGetAvailabilityQuery(
3203
3370
  {
3204
- ref: composedRefs,
3205
- disabled: props.disabled,
3206
- error: field.error,
3207
- endAction: /* @__PURE__ */ jsxs(Flex, { position: "relative", gap: 1, children: [
3208
- availability && !showRegenerate && /* @__PURE__ */ jsxs(
3209
- TextValidation,
3210
- {
3211
- alignItems: "center",
3212
- gap: 1,
3213
- justifyContent: "flex-end",
3214
- available: !!availability?.isAvailable,
3215
- "data-not-here-outer": true,
3216
- position: "absolute",
3217
- pointerEvents: "none",
3218
- right: 6,
3219
- width: "100px",
3220
- children: [
3221
- availability?.isAvailable ? /* @__PURE__ */ jsx(CheckCircle, {}) : /* @__PURE__ */ jsx(WarningCircle, {}),
3222
- /* @__PURE__ */ jsx(
3223
- Typography,
3224
- {
3225
- textColor: availability.isAvailable ? "success600" : "danger600",
3226
- variant: "pi",
3227
- children: formatMessage(
3228
- availability.isAvailable ? {
3229
- id: "content-manager.components.uid.available",
3230
- defaultMessage: "Available"
3231
- } : {
3232
- id: "content-manager.components.uid.unavailable",
3233
- defaultMessage: "Unavailable"
3234
- }
3235
- )
3236
- }
3237
- )
3238
- ]
3239
- }
3240
- ),
3241
- !props.disabled && /* @__PURE__ */ jsxs(Fragment, { children: [
3242
- showRegenerate && /* @__PURE__ */ jsx(TextValidation, { alignItems: "center", justifyContent: "flex-end", gap: 1, children: /* @__PURE__ */ jsx(Typography, { textColor: "primary600", variant: "pi", children: formatMessage({
3243
- id: "content-manager.components.uid.regenerate",
3244
- defaultMessage: "Regenerate"
3245
- }) }) }),
3246
- /* @__PURE__ */ jsx(
3247
- FieldActionWrapper,
3371
+ contentTypeUID: model,
3372
+ field: name2,
3373
+ value: debouncedValue ? debouncedValue.trim() : "",
3374
+ params
3375
+ },
3376
+ {
3377
+ // Don't check availability if the value is empty or wasn't changed
3378
+ skip: !Boolean(
3379
+ (hasChanged || isCloning) && debouncedValue && UID_REGEX.test(debouncedValue.trim())
3380
+ )
3381
+ }
3382
+ );
3383
+ React.useEffect(() => {
3384
+ if (availabilityError) {
3385
+ toggleNotification({
3386
+ type: "warning",
3387
+ message: formatAPIError(availabilityError)
3388
+ });
3389
+ }
3390
+ }, [availabilityError, formatAPIError, toggleNotification]);
3391
+ React.useEffect(() => {
3392
+ setAvailability(availabilityData);
3393
+ let timer;
3394
+ if (availabilityData?.isAvailable) {
3395
+ timer = window.setTimeout(() => {
3396
+ setAvailability(void 0);
3397
+ }, 4e3);
3398
+ }
3399
+ return () => {
3400
+ if (timer) {
3401
+ clearTimeout(timer);
3402
+ }
3403
+ };
3404
+ }, [availabilityData]);
3405
+ const isLoading = isGeneratingDefaultUID || isGeneratingUID || isCheckingAvailability;
3406
+ const fieldRef = useFocusInputField(name2);
3407
+ const composedRefs = useComposedRefs(ref, fieldRef);
3408
+ const shouldShowAvailability = (hasChanged || isCloning) && debouncedValue != null && availability && !showRegenerate;
3409
+ return /* @__PURE__ */ jsxs(Field.Root, { hint, name: name2, error: field.error, required, children: [
3410
+ /* @__PURE__ */ jsx(Field.Label, { action: labelAction, children: label }),
3411
+ /* @__PURE__ */ jsx(
3412
+ TextInput,
3413
+ {
3414
+ ref: composedRefs,
3415
+ disabled: props.disabled,
3416
+ endAction: /* @__PURE__ */ jsxs(Flex, { position: "relative", gap: 1, children: [
3417
+ shouldShowAvailability && /* @__PURE__ */ jsxs(
3418
+ TextValidation,
3248
3419
  {
3249
- onClick: handleRegenerateClick,
3250
- label: formatMessage({
3251
- id: "content-manager.components.uid.regenerate",
3252
- defaultMessage: "Regenerate"
3253
- }),
3254
- onMouseEnter: () => setShowRegenerate(true),
3255
- onMouseLeave: () => setShowRegenerate(false),
3256
- children: isLoading ? /* @__PURE__ */ jsx(LoadingWrapper, { "data-testid": "loading-wrapper", children: /* @__PURE__ */ jsx(Loader, {}) }) : /* @__PURE__ */ jsx(ArrowClockwise, {})
3420
+ alignItems: "center",
3421
+ gap: 1,
3422
+ justifyContent: "flex-end",
3423
+ $available: !!availability?.isAvailable,
3424
+ "data-not-here-outer": true,
3425
+ position: "absolute",
3426
+ pointerEvents: "none",
3427
+ right: 6,
3428
+ width: "100px",
3429
+ children: [
3430
+ availability?.isAvailable ? /* @__PURE__ */ jsx(CheckCircle, {}) : /* @__PURE__ */ jsx(WarningCircle, {}),
3431
+ /* @__PURE__ */ jsx(
3432
+ Typography,
3433
+ {
3434
+ textColor: availability.isAvailable ? "success600" : "danger600",
3435
+ variant: "pi",
3436
+ children: formatMessage(
3437
+ availability.isAvailable ? {
3438
+ id: "content-manager.components.uid.available",
3439
+ defaultMessage: "Available"
3440
+ } : {
3441
+ id: "content-manager.components.uid.unavailable",
3442
+ defaultMessage: "Unavailable"
3443
+ }
3444
+ )
3445
+ }
3446
+ )
3447
+ ]
3257
3448
  }
3258
- )
3259
- ] })
3260
- ] }),
3261
- onChange: field.onChange,
3262
- value: field.value ?? "",
3263
- ...props
3264
- }
3265
- )
3266
- );
3267
- });
3268
- const FieldActionWrapper = styled(FieldAction)`
3449
+ ),
3450
+ !props.disabled && /* @__PURE__ */ jsxs(Fragment, { children: [
3451
+ showRegenerate && /* @__PURE__ */ jsx(TextValidation, { alignItems: "center", justifyContent: "flex-end", gap: 1, children: /* @__PURE__ */ jsx(Typography, { textColor: "primary600", variant: "pi", children: formatMessage({
3452
+ id: "content-manager.components.uid.regenerate",
3453
+ defaultMessage: "Regenerate"
3454
+ }) }) }),
3455
+ /* @__PURE__ */ jsx(
3456
+ FieldActionWrapper,
3457
+ {
3458
+ onClick: handleRegenerateClick,
3459
+ label: formatMessage({
3460
+ id: "content-manager.components.uid.regenerate",
3461
+ defaultMessage: "Regenerate"
3462
+ }),
3463
+ onMouseEnter: () => setShowRegenerate(true),
3464
+ onMouseLeave: () => setShowRegenerate(false),
3465
+ children: isLoading ? /* @__PURE__ */ jsx(LoadingWrapper, { "data-testid": "loading-wrapper", children: /* @__PURE__ */ jsx(Loader, {}) }) : /* @__PURE__ */ jsx(ArrowClockwise, {})
3466
+ }
3467
+ )
3468
+ ] })
3469
+ ] }),
3470
+ onChange: field.onChange,
3471
+ value: field.value ?? "",
3472
+ ...props
3473
+ }
3474
+ ),
3475
+ /* @__PURE__ */ jsx(Field.Error, {}),
3476
+ /* @__PURE__ */ jsx(Field.Hint, {})
3477
+ ] });
3478
+ }
3479
+ );
3480
+ const FieldActionWrapper = styled(Field.Action)`
3481
+ width: 1.6rem;
3482
+
3269
3483
  svg {
3270
3484
  height: 1.6rem;
3271
3485
  width: 1.6rem;
@@ -3286,7 +3500,7 @@ const TextValidation = styled(Flex)`
3286
3500
  width: 1.2rem;
3287
3501
 
3288
3502
  path {
3289
- fill: ${({ theme, available }) => available ? theme.colors.success600 : theme.colors.danger600};
3503
+ fill: ${({ theme, $available }) => $available ? theme.colors.success600 : theme.colors.danger600};
3290
3504
  }
3291
3505
  }
3292
3506
  `;
@@ -3301,6 +3515,7 @@ const rotation = keyframes`
3301
3515
  const LoadingWrapper = styled(Flex)`
3302
3516
  animation: ${rotation} 2s infinite linear;
3303
3517
  `;
3518
+ const MemoizedUIDInput = React.memo(UIDInput);
3304
3519
  const md = new Markdown({
3305
3520
  html: true,
3306
3521
  // Enable HTML tags in source
@@ -3488,8 +3703,7 @@ const Wrapper = styled.div`
3488
3703
  `;
3489
3704
  var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, unorderedListRE = /[*+-]\s/;
3490
3705
  function newlineAndIndentContinueMarkdownList(cm) {
3491
- if (cm.getOption("disableInput"))
3492
- return CodeMirror.Pass;
3706
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
3493
3707
  var ranges = cm.listSelections(), replacements = [];
3494
3708
  for (var i = 0; i < ranges.length; i++) {
3495
3709
  var pos = ranges[i].head;
@@ -3523,8 +3737,7 @@ function newlineAndIndentContinueMarkdownList(cm) {
3523
3737
  var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
3524
3738
  var bullet = numbered ? parseInt(match[3], 10) + 1 + match[4] : match[2].replace("x", " ");
3525
3739
  replacements[i] = "\n" + indent + bullet + after;
3526
- if (numbered)
3527
- incrementRemainingMarkdownListNumbers(cm, pos);
3740
+ if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
3528
3741
  }
3529
3742
  }
3530
3743
  cm.replaceSelections(replacements);
@@ -3542,10 +3755,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3542
3755
  var newNumber = parseInt(startItem[3], 10) + lookAhead - skipCount;
3543
3756
  var nextNumber = parseInt(nextItem[3], 10), itemNumber = nextNumber;
3544
3757
  if (startIndent === nextIndent && !isNaN(nextNumber)) {
3545
- if (newNumber === nextNumber)
3546
- itemNumber = nextNumber + 1;
3547
- if (newNumber > nextNumber)
3548
- itemNumber = newNumber + 1;
3758
+ if (newNumber === nextNumber) itemNumber = nextNumber + 1;
3759
+ if (newNumber > nextNumber) itemNumber = newNumber + 1;
3549
3760
  cm.replaceRange(
3550
3761
  nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
3551
3762
  {
@@ -3558,10 +3769,8 @@ function incrementRemainingMarkdownListNumbers(cm, pos) {
3558
3769
  }
3559
3770
  );
3560
3771
  } else {
3561
- if (startIndent.length > nextIndent.length)
3562
- return;
3563
- if (startIndent.length < nextIndent.length && lookAhead === 1)
3564
- return;
3772
+ if (startIndent.length > nextIndent.length) return;
3773
+ if (startIndent.length < nextIndent.length && lookAhead === 1) return;
3565
3774
  skipCount += 1;
3566
3775
  }
3567
3776
  }
@@ -3635,7 +3844,7 @@ const Editor = React.forwardRef(
3635
3844
  [editorRef]
3636
3845
  );
3637
3846
  return /* @__PURE__ */ jsxs(EditorAndPreviewWrapper, { children: [
3638
- /* @__PURE__ */ jsx(EditorStylesContainer, { isExpandMode, disabled: disabled || isPreviewMode, children: /* @__PURE__ */ jsx("textarea", { ref: textareaRef }) }),
3847
+ /* @__PURE__ */ jsx(EditorStylesContainer, { $isExpandMode: isExpandMode, $disabled: disabled || isPreviewMode, children: /* @__PURE__ */ jsx("textarea", { ref: textareaRef }) }),
3639
3848
  isPreviewMode && /* @__PURE__ */ jsx(PreviewWysiwyg, { data: value })
3640
3849
  ] });
3641
3850
  }
@@ -3645,7 +3854,7 @@ const EditorAndPreviewWrapper = styled.div`
3645
3854
  height: calc(100% - 48px);
3646
3855
  `;
3647
3856
  const EditorStylesContainer = styled.div`
3648
- cursor: ${({ disabled }) => disabled ? "not-allowed !important" : "auto"};
3857
+ cursor: ${({ $disabled }) => $disabled ? "not-allowed !important" : "auto"};
3649
3858
  height: 100%;
3650
3859
  /* BASICS */
3651
3860
  .CodeMirror-placeholder {
@@ -3655,7 +3864,7 @@ const EditorStylesContainer = styled.div`
3655
3864
  .CodeMirror {
3656
3865
  /* Set height, width, borders, and global font properties here */
3657
3866
  font-size: 1.4rem;
3658
- height: ${({ isExpandMode }) => isExpandMode ? "100%" : "410px"}; // 512px(total height) - 48px (header) - 52px(footer) - 2px border
3867
+ height: ${({ $isExpandMode }) => $isExpandMode ? "100%" : "410px"}; // 512px(total height) - 48px (header) - 52px(footer) - 2px border
3659
3868
  color: ${({ theme }) => theme.colors.neutral800};
3660
3869
  direction: ltr;
3661
3870
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
@@ -4033,7 +4242,7 @@ const EditorLayout = ({
4033
4242
  justifyContent: "flex-end",
4034
4243
  shrink: 0,
4035
4244
  width: "100%",
4036
- children: /* @__PURE__ */ jsxs(ExpandButton$1, { onClick: onCollapse, children: [
4245
+ children: /* @__PURE__ */ jsxs(ExpandButton$1, { onClick: onCollapse, variant: "tertiary", size: "M", children: [
4037
4246
  /* @__PURE__ */ jsx(Typography, { children: formatMessage({
4038
4247
  id: "components.Wysiwyg.collapse",
4039
4248
  defaultMessage: "Collapse"
@@ -4051,12 +4260,14 @@ const EditorLayout = ({
4051
4260
  ) }) });
4052
4261
  }
4053
4262
  return /* @__PURE__ */ jsx(
4054
- Box,
4263
+ Flex,
4055
4264
  {
4056
4265
  borderColor: error ? "danger600" : "neutral200",
4057
4266
  borderStyle: "solid",
4058
4267
  borderWidth: "1px",
4059
4268
  hasRadius: true,
4269
+ direction: "column",
4270
+ alignItems: "stretch",
4060
4271
  children
4061
4272
  }
4062
4273
  );
@@ -4067,11 +4278,19 @@ const ExpandWrapper = styled(Flex)`
4067
4278
  const BoxWithBorder = styled(Box)`
4068
4279
  border-right: 1px solid ${({ theme }) => theme.colors.neutral200};
4069
4280
  `;
4070
- const ExpandButton$1 = styled(BaseButton)`
4281
+ const ExpandButton$1 = styled(Button)`
4071
4282
  background-color: transparent;
4072
4283
  border: none;
4073
4284
  align-items: center;
4074
4285
 
4286
+ & > span {
4287
+ display: flex;
4288
+ justify-content: space-between;
4289
+ align-items: center;
4290
+ width: 100%;
4291
+ font-weight: ${({ theme }) => theme.fontWeights.regular};
4292
+ }
4293
+
4075
4294
  svg {
4076
4295
  margin-left: ${({ theme }) => `${theme.spaces[2]}`};
4077
4296
 
@@ -4338,42 +4557,28 @@ const quoteAndCodeHandler = (editor, markdownType) => {
4338
4557
  insertWithoutTextToEdit(editor, markdownType, line, contentLength);
4339
4558
  }
4340
4559
  };
4341
- const CustomIconButton = styled(IconButton)`
4342
- padding: ${({ theme }) => theme.spaces[2]};
4343
- /* Trick to prevent the outline from overflowing because of the general outline-offset */
4344
- outline-offset: -2px !important;
4345
-
4346
- svg {
4347
- width: 1.8rem;
4348
- height: 1.8rem;
4349
- }
4350
- `;
4351
- const CustomLinkIconButton = styled(CustomIconButton)`
4352
- svg {
4353
- width: 0.8rem;
4354
- height: 0.8rem;
4355
- }
4356
- `;
4357
4560
  const MainButtons = styled(IconButtonGroup)`
4358
4561
  margin-left: ${({ theme }) => theme.spaces[4]};
4359
4562
  `;
4360
4563
  const MoreButton = styled(IconButton)`
4361
4564
  margin: ${({ theme }) => `0 ${theme.spaces[2]}`};
4362
- padding: ${({ theme }) => theme.spaces[2]};
4363
-
4364
- svg {
4365
- width: 1.8rem;
4366
- height: 1.8rem;
4367
- }
4368
4565
  `;
4369
4566
  const IconButtonGroupMargin = styled(IconButtonGroup)`
4370
4567
  margin-right: ${({ theme }) => `${theme.spaces[2]}`};
4371
4568
  `;
4372
- const ExpandButton = styled(BaseButton)`
4569
+ const ExpandButton = styled(Button)`
4373
4570
  background-color: transparent;
4374
4571
  border: none;
4375
4572
  align-items: center;
4376
4573
 
4574
+ & > span {
4575
+ display: flex;
4576
+ justify-content: space-between;
4577
+ align-items: center;
4578
+ width: 100%;
4579
+ font-weight: ${({ theme }) => theme.fontWeights.regular};
4580
+ }
4581
+
4377
4582
  svg {
4378
4583
  margin-left: ${({ theme }) => `${theme.spaces[2]}`};
4379
4584
  path {
@@ -4385,8 +4590,8 @@ const ExpandButton = styled(BaseButton)`
4385
4590
  `;
4386
4591
  const WysiwygFooter = ({ onToggleExpand }) => {
4387
4592
  const { formatMessage } = useIntl();
4388
- return /* @__PURE__ */ jsx(Box, { padding: 2, background: "neutral100", borderRadius: `0 0 0.4rem 0.4rem`, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", alignItems: "flex-end", children: /* @__PURE__ */ jsxs(ExpandButton, { id: "expand", onClick: onToggleExpand, children: [
4389
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
4593
+ return /* @__PURE__ */ jsx(Box, { padding: 2, background: "neutral100", borderRadius: `0 0 0.4rem 0.4rem`, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", alignItems: "flex-end", children: /* @__PURE__ */ jsxs(ExpandButton, { id: "expand", onClick: onToggleExpand, variant: "tertiary", size: "M", children: [
4594
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", children: formatMessage({
4390
4595
  id: "components.WysiwygBottomControls.fullscreen",
4391
4596
  defaultMessage: "Expand"
4392
4597
  }) }),
@@ -4408,7 +4613,7 @@ const WysiwygNav = ({
4408
4613
  id: "components.Wysiwyg.selectOptions.title",
4409
4614
  defaultMessage: "Add a title"
4410
4615
  });
4411
- const buttonMoreRef = React.useRef(null);
4616
+ React.useRef(null);
4412
4617
  const handleTogglePopover = () => {
4413
4618
  setVisiblePopover((prev) => !prev);
4414
4619
  };
@@ -4421,21 +4626,30 @@ const WysiwygNav = ({
4421
4626
  justifyContent: "space-between",
4422
4627
  borderRadius: `0.4rem 0.4rem 0 0`,
4423
4628
  children: [
4424
- /* @__PURE__ */ jsxs(StyledFlex, { children: [
4425
- /* @__PURE__ */ jsxs(SingleSelect, { disabled: true, placeholder: selectPlaceholder, size: "S", label: selectPlaceholder, children: [
4426
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4427
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4428
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4429
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4430
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4431
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4432
- ] }),
4629
+ /* @__PURE__ */ jsxs(Flex, { children: [
4630
+ /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsxs(
4631
+ SingleSelect,
4632
+ {
4633
+ disabled: true,
4634
+ placeholder: selectPlaceholder,
4635
+ "aria-label": selectPlaceholder,
4636
+ size: "S",
4637
+ children: [
4638
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4639
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4640
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4641
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4642
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4643
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4644
+ ]
4645
+ }
4646
+ ) }),
4433
4647
  /* @__PURE__ */ jsxs(MainButtons, { children: [
4434
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Bold", name: "Bold", icon: /* @__PURE__ */ jsx(Bold, {}) }),
4435
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Italic", name: "Italic", icon: /* @__PURE__ */ jsx(Italic, {}) }),
4436
- /* @__PURE__ */ jsx(CustomIconButton, { disabled: true, label: "Underline", name: "Underline", icon: /* @__PURE__ */ jsx(Underline, {}) })
4648
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Bold", name: "Bold", children: /* @__PURE__ */ jsx(Bold, {}) }),
4649
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Italic", name: "Italic", children: /* @__PURE__ */ jsx(Italic, {}) }),
4650
+ /* @__PURE__ */ jsx(IconButton, { disabled: true, label: "Underline", name: "Underline", children: /* @__PURE__ */ jsx(Underline, {}) })
4437
4651
  ] }),
4438
- /* @__PURE__ */ jsx(MoreButton, { disabled: true, label: "More", icon: /* @__PURE__ */ jsx(More, {}) })
4652
+ /* @__PURE__ */ jsx(MoreButton, { disabled: true, label: "More", children: /* @__PURE__ */ jsx(More, {}) })
4439
4653
  ] }),
4440
4654
  !isExpandMode && /* @__PURE__ */ jsx(Button, { onClick: onTogglePreviewMode, variant: "tertiary", children: formatMessage({
4441
4655
  id: "components.Wysiwyg.ToggleMode.markdown-mode",
@@ -4453,134 +4667,120 @@ const WysiwygNav = ({
4453
4667
  justifyContent: "space-between",
4454
4668
  borderRadius: `0.4rem 0.4rem 0 0`,
4455
4669
  children: [
4456
- /* @__PURE__ */ jsxs(StyledFlex, { children: [
4457
- /* @__PURE__ */ jsxs(
4670
+ /* @__PURE__ */ jsxs(Flex, { children: [
4671
+ /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsxs(
4458
4672
  SingleSelect,
4459
4673
  {
4460
4674
  placeholder: selectPlaceholder,
4461
- label: selectPlaceholder,
4462
- size: "S",
4675
+ "aria-label": selectPlaceholder,
4463
4676
  onChange: (value) => onActionClick(value, editorRef),
4464
- children: [
4465
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4466
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4467
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4468
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4469
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4470
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4471
- ]
4472
- }
4473
- ),
4474
- /* @__PURE__ */ jsxs(MainButtons, { children: [
4475
- /* @__PURE__ */ jsx(
4476
- CustomIconButton,
4477
- {
4478
- onClick: () => onActionClick("Bold", editorRef),
4479
- label: "Bold",
4480
- name: "Bold",
4481
- icon: /* @__PURE__ */ jsx(Bold, {})
4482
- }
4483
- ),
4484
- /* @__PURE__ */ jsx(
4485
- CustomIconButton,
4486
- {
4487
- onClick: () => onActionClick("Italic", editorRef),
4488
- label: "Italic",
4489
- name: "Italic",
4490
- icon: /* @__PURE__ */ jsx(Italic, {})
4491
- }
4492
- ),
4493
- /* @__PURE__ */ jsx(
4494
- CustomIconButton,
4495
- {
4496
- onClick: () => onActionClick("Underline", editorRef),
4497
- label: "Underline",
4498
- name: "Underline",
4499
- icon: /* @__PURE__ */ jsx(Underline, {})
4500
- }
4501
- )
4502
- ] }),
4503
- /* @__PURE__ */ jsx(
4504
- MoreButton,
4505
- {
4506
- ref: buttonMoreRef,
4507
- onClick: handleTogglePopover,
4508
- label: "More",
4509
- icon: /* @__PURE__ */ jsx(More, {})
4510
- }
4511
- ),
4512
- visiblePopover && /* @__PURE__ */ jsx(Popover, { onDismiss: handleTogglePopover, centered: true, source: buttonMoreRef, spacing: 4, children: /* @__PURE__ */ jsxs(Flex, { children: [
4513
- /* @__PURE__ */ jsxs(IconButtonGroupMargin, { children: [
4514
- /* @__PURE__ */ jsx(
4515
- CustomIconButton,
4516
- {
4517
- onClick: () => onActionClick("Strikethrough", editorRef, handleTogglePopover),
4518
- label: "Strikethrough",
4519
- name: "Strikethrough",
4520
- icon: /* @__PURE__ */ jsx(StrikeThrough, {})
4521
- }
4522
- ),
4523
- /* @__PURE__ */ jsx(
4524
- CustomIconButton,
4525
- {
4526
- onClick: () => onActionClick("BulletList", editorRef, handleTogglePopover),
4527
- label: "BulletList",
4528
- name: "BulletList",
4529
- icon: /* @__PURE__ */ jsx(BulletList, {})
4530
- }
4531
- ),
4532
- /* @__PURE__ */ jsx(
4533
- CustomIconButton,
4534
- {
4535
- onClick: () => onActionClick("NumberList", editorRef, handleTogglePopover),
4536
- label: "NumberList",
4537
- name: "NumberList",
4538
- icon: /* @__PURE__ */ jsx(NumberList, {})
4539
- }
4540
- )
4541
- ] }),
4542
- /* @__PURE__ */ jsxs(IconButtonGroup, { children: [
4543
- /* @__PURE__ */ jsx(
4544
- CustomIconButton,
4545
- {
4546
- onClick: () => onActionClick("Code", editorRef, handleTogglePopover),
4547
- label: "Code",
4548
- name: "Code",
4549
- icon: /* @__PURE__ */ jsx(Code, {})
4550
- }
4551
- ),
4552
- /* @__PURE__ */ jsx(
4553
- CustomIconButton,
4554
- {
4555
- onClick: () => {
4556
- handleTogglePopover();
4557
- onToggleMediaLib();
4558
- },
4559
- label: "Image",
4560
- name: "Image",
4561
- icon: /* @__PURE__ */ jsx(Image$1, {})
4562
- }
4563
- ),
4564
- /* @__PURE__ */ jsx(
4565
- CustomLinkIconButton,
4566
- {
4567
- onClick: () => onActionClick("Link", editorRef, handleTogglePopover),
4568
- label: "Link",
4569
- name: "Link",
4570
- icon: /* @__PURE__ */ jsx(Link$1, {})
4571
- }
4572
- ),
4573
- /* @__PURE__ */ jsx(
4574
- CustomIconButton,
4575
- {
4576
- onClick: () => onActionClick("Quote", editorRef, handleTogglePopover),
4577
- label: "Quote",
4578
- name: "Quote",
4579
- icon: /* @__PURE__ */ jsx(Quotes, {})
4580
- }
4581
- )
4582
- ] })
4583
- ] }) })
4677
+ size: "S",
4678
+ children: [
4679
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h1", children: "h1" }),
4680
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h2", children: "h2" }),
4681
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h3", children: "h3" }),
4682
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h4", children: "h4" }),
4683
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h5", children: "h5" }),
4684
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "h6", children: "h6" })
4685
+ ]
4686
+ }
4687
+ ) }),
4688
+ /* @__PURE__ */ jsxs(MainButtons, { children: [
4689
+ /* @__PURE__ */ jsx(IconButton, { onClick: () => onActionClick("Bold", editorRef), label: "Bold", name: "Bold", children: /* @__PURE__ */ jsx(Bold, {}) }),
4690
+ /* @__PURE__ */ jsx(
4691
+ IconButton,
4692
+ {
4693
+ onClick: () => onActionClick("Italic", editorRef),
4694
+ label: "Italic",
4695
+ name: "Italic",
4696
+ children: /* @__PURE__ */ jsx(Italic, {})
4697
+ }
4698
+ ),
4699
+ /* @__PURE__ */ jsx(
4700
+ IconButton,
4701
+ {
4702
+ onClick: () => onActionClick("Underline", editorRef),
4703
+ label: "Underline",
4704
+ name: "Underline",
4705
+ children: /* @__PURE__ */ jsx(Underline, {})
4706
+ }
4707
+ )
4708
+ ] }),
4709
+ /* @__PURE__ */ jsxs(Popover.Root, { children: [
4710
+ /* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(MoreButton, { label: "More", children: /* @__PURE__ */ jsx(More, {}) }) }),
4711
+ /* @__PURE__ */ jsx(Popover.Content, { sideOffset: 12, children: /* @__PURE__ */ jsxs(Flex, { padding: 2, children: [
4712
+ /* @__PURE__ */ jsxs(IconButtonGroupMargin, { children: [
4713
+ /* @__PURE__ */ jsx(
4714
+ IconButton,
4715
+ {
4716
+ onClick: () => onActionClick("Strikethrough", editorRef, handleTogglePopover),
4717
+ label: "Strikethrough",
4718
+ name: "Strikethrough",
4719
+ children: /* @__PURE__ */ jsx(StrikeThrough, {})
4720
+ }
4721
+ ),
4722
+ /* @__PURE__ */ jsx(
4723
+ IconButton,
4724
+ {
4725
+ onClick: () => onActionClick("BulletList", editorRef, handleTogglePopover),
4726
+ label: "BulletList",
4727
+ name: "BulletList",
4728
+ children: /* @__PURE__ */ jsx(BulletList, {})
4729
+ }
4730
+ ),
4731
+ /* @__PURE__ */ jsx(
4732
+ IconButton,
4733
+ {
4734
+ onClick: () => onActionClick("NumberList", editorRef, handleTogglePopover),
4735
+ label: "NumberList",
4736
+ name: "NumberList",
4737
+ children: /* @__PURE__ */ jsx(NumberList, {})
4738
+ }
4739
+ )
4740
+ ] }),
4741
+ /* @__PURE__ */ jsxs(IconButtonGroup, { children: [
4742
+ /* @__PURE__ */ jsx(
4743
+ IconButton,
4744
+ {
4745
+ onClick: () => onActionClick("Code", editorRef, handleTogglePopover),
4746
+ label: "Code",
4747
+ name: "Code",
4748
+ children: /* @__PURE__ */ jsx(Code, {})
4749
+ }
4750
+ ),
4751
+ /* @__PURE__ */ jsx(
4752
+ IconButton,
4753
+ {
4754
+ onClick: () => {
4755
+ handleTogglePopover();
4756
+ onToggleMediaLib();
4757
+ },
4758
+ label: "Image",
4759
+ name: "Image",
4760
+ children: /* @__PURE__ */ jsx(Image$1, {})
4761
+ }
4762
+ ),
4763
+ /* @__PURE__ */ jsx(
4764
+ IconButton,
4765
+ {
4766
+ onClick: () => onActionClick("Link", editorRef, handleTogglePopover),
4767
+ label: "Link",
4768
+ name: "Link",
4769
+ children: /* @__PURE__ */ jsx(Link$1, {})
4770
+ }
4771
+ ),
4772
+ /* @__PURE__ */ jsx(
4773
+ IconButton,
4774
+ {
4775
+ onClick: () => onActionClick("Quote", editorRef, handleTogglePopover),
4776
+ label: "Quote",
4777
+ name: "Quote",
4778
+ children: /* @__PURE__ */ jsx(Quotes, {})
4779
+ }
4780
+ )
4781
+ ] })
4782
+ ] }) })
4783
+ ] })
4584
4784
  ] }),
4585
4785
  onTogglePreviewMode && /* @__PURE__ */ jsx(Button, { onClick: onTogglePreviewMode, variant: "tertiary", children: formatMessage({
4586
4786
  id: "components.Wysiwyg.ToggleMode.preview-mode",
@@ -4590,19 +4790,6 @@ const WysiwygNav = ({
4590
4790
  }
4591
4791
  );
4592
4792
  };
4593
- const StyledFlex = styled(Flex)`
4594
- /* Hide the label, every input needs a label. */
4595
- label {
4596
- border: 0;
4597
- clip: rect(0 0 0 0);
4598
- height: 1px;
4599
- margin: -1px;
4600
- overflow: hidden;
4601
- padding: 0;
4602
- position: absolute;
4603
- width: 1px;
4604
- }
4605
- `;
4606
4793
  const Wysiwyg = React.forwardRef(
4607
4794
  ({ hint, disabled, label, name: name2, placeholder, required, labelAction }, forwardedRef) => {
4608
4795
  const field = useField(name2);
@@ -4667,9 +4854,9 @@ const Wysiwyg = React.forwardRef(
4667
4854
  insertFile(editorRef, formattedFiles);
4668
4855
  setMediaLibVisible(false);
4669
4856
  };
4670
- return /* @__PURE__ */ jsxs(Field, { name: name2, hint, error: field.error, required, children: [
4857
+ return /* @__PURE__ */ jsxs(Field.Root, { name: name2, hint, error: field.error, required, children: [
4671
4858
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
4672
- /* @__PURE__ */ jsx(FieldLabel, { action: labelAction, children: label }),
4859
+ /* @__PURE__ */ jsx(Field.Label, { action: labelAction, children: label }),
4673
4860
  /* @__PURE__ */ jsxs(
4674
4861
  EditorLayout,
4675
4862
  {
@@ -4710,24 +4897,29 @@ const Wysiwyg = React.forwardRef(
4710
4897
  ]
4711
4898
  }
4712
4899
  ),
4713
- /* @__PURE__ */ jsx(FieldHint, {}),
4714
- /* @__PURE__ */ jsx(FieldError, {})
4900
+ /* @__PURE__ */ jsx(Field.Hint, {}),
4901
+ /* @__PURE__ */ jsx(Field.Error, {})
4715
4902
  ] }),
4716
4903
  mediaLibVisible && // @ts-expect-error – TODO: fix this way of injecting because it's not really typeable without a registry.
4717
4904
  /* @__PURE__ */ jsx(MediaLibraryDialog, { onClose: handleToggleMediaLib, onSelectAssets: handleSelectAssets })
4718
4905
  ] });
4719
4906
  }
4720
4907
  );
4908
+ const MemoizedWysiwyg = React.memo(Wysiwyg);
4721
4909
  const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4722
- const { id } = useDoc();
4910
+ const { id, document: document2, collectionType } = useDoc();
4723
4911
  const isFormDisabled = useForm("InputRenderer", (state) => state.disabled);
4724
4912
  const isInDynamicZone = useDynamicZone("isInDynamicZone", (state) => state.isInDynamicZone);
4725
4913
  const canCreateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canCreateFields);
4726
4914
  const canReadFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canReadFields);
4727
4915
  const canUpdateFields = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUpdateFields);
4728
4916
  const canUserAction = useDocumentRBAC("InputRenderer", (rbac) => rbac.canUserAction);
4729
- const editableFields = id ? canUpdateFields : canCreateFields;
4730
- const readableFields = id ? canReadFields : canCreateFields;
4917
+ let idToCheck = id;
4918
+ if (collectionType === SINGLE_TYPES) {
4919
+ idToCheck = document2?.documentId;
4920
+ }
4921
+ const editableFields = idToCheck ? canUpdateFields : canCreateFields;
4922
+ const readableFields = idToCheck ? canReadFields : canCreateFields;
4731
4923
  const canUserReadField = canUserAction(props.name, readableFields, props.type);
4732
4924
  const canUserEditField = canUserAction(props.name, editableFields, props.type);
4733
4925
  const fields = useStrapiApp("InputRenderer", (app) => app.fields);
@@ -4738,6 +4930,7 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4738
4930
  const {
4739
4931
  edit: { components }
4740
4932
  } = useDocLayout();
4933
+ const field = useField(props.name);
4741
4934
  if (!visible) {
4742
4935
  return null;
4743
4936
  }
@@ -4748,7 +4941,7 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4748
4941
  if (attributeHasCustomFieldProperty(props.attribute)) {
4749
4942
  const CustomInput = lazyComponentStore[props.attribute.customField];
4750
4943
  if (CustomInput) {
4751
- return /* @__PURE__ */ jsx(CustomInput, { ...props, hint, disabled: fieldIsDisabled });
4944
+ return /* @__PURE__ */ jsx(CustomInput, { ...props, ...field, hint, disabled: fieldIsDisabled });
4752
4945
  }
4753
4946
  return /* @__PURE__ */ jsx(
4754
4947
  InputRenderer$1,
@@ -4767,371 +4960,287 @@ const InputRenderer = ({ visible, hint: providedHint, ...props }) => {
4767
4960
  }
4768
4961
  switch (props.type) {
4769
4962
  case "blocks":
4770
- return /* @__PURE__ */ jsx(BlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4771
- case "component":
4772
- return /* @__PURE__ */ jsx(
4773
- ComponentInput,
4774
- {
4775
- ...props,
4776
- hint,
4777
- layout: components[props.attribute.component].layout,
4778
- disabled: fieldIsDisabled,
4779
- children: (inputProps) => /* @__PURE__ */ jsx(InputRenderer, { ...inputProps })
4780
- }
4781
- );
4782
- case "dynamiczone":
4783
- return /* @__PURE__ */ jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
4784
- case "relation":
4785
- return /* @__PURE__ */ jsx(RelationsField, { ...props, hint, disabled: fieldIsDisabled });
4786
- case "richtext":
4787
- return /* @__PURE__ */ jsx(Wysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4788
- case "uid":
4789
- return /* @__PURE__ */ jsx(UIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4790
- case "enumeration":
4791
- return /* @__PURE__ */ jsx(
4792
- InputRenderer$1,
4793
- {
4794
- ...props,
4795
- hint,
4796
- options: props.attribute.enum.map((value) => ({ value })),
4797
- type: props.customField ? "custom-field" : props.type,
4798
- disabled: fieldIsDisabled
4799
- }
4800
- );
4801
- default:
4802
- const { unique: _unique, mainField: _mainField, ...restProps } = props;
4803
- return /* @__PURE__ */ jsx(
4804
- InputRenderer$1,
4805
- {
4806
- ...restProps,
4807
- hint,
4808
- type: props.customField ? "custom-field" : props.type,
4809
- disabled: fieldIsDisabled
4810
- }
4811
- );
4812
- }
4813
- };
4814
- const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
4815
- const useFieldHint = (hint = void 0, attribute) => {
4816
- const { formatMessage } = useIntl();
4817
- const { maximum, minimum } = getMinMax(attribute);
4818
- if (!maximum && !minimum) {
4819
- return hint;
4820
- }
4821
- const units = !["biginteger", "integer", "number"].includes(attribute.type) ? formatMessage(
4822
- {
4823
- id: "content-manager.form.Input.hint.character.unit",
4824
- defaultMessage: "{maxValue, plural, one { character} other { characters}}"
4825
- },
4826
- {
4827
- maxValue: Math.max(minimum || 0, maximum || 0)
4828
- }
4829
- ) : null;
4830
- const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
4831
- return formatMessage(
4832
- {
4833
- id: "content-manager.form.Input.hint.text",
4834
- defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
4835
- },
4836
- {
4837
- min: minimum,
4838
- max: maximum,
4839
- description: hint,
4840
- unit: units,
4841
- divider: hasMinAndMax ? formatMessage({
4842
- id: "content-manager.form.Input.hint.minMaxDivider",
4843
- defaultMessage: " / "
4844
- }) : null,
4845
- br: /* @__PURE__ */ jsx("br", {})
4846
- }
4847
- );
4848
- };
4849
- const getMinMax = (attribute) => {
4850
- if ("min" in attribute || "max" in attribute) {
4851
- return {
4852
- maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
4853
- minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
4854
- };
4855
- } else if ("maxLength" in attribute || "minLength" in attribute) {
4856
- return { maximum: attribute.maxLength, minimum: attribute.minLength };
4857
- } else {
4858
- return { maximum: void 0, minimum: void 0 };
4859
- }
4860
- };
4861
- const DynamicComponent = ({
4862
- componentUid,
4863
- disabled,
4864
- index,
4865
- name: name2,
4866
- onRemoveComponentClick,
4867
- onMoveComponent,
4868
- onGrabItem,
4869
- onDropItem,
4870
- onCancel,
4871
- dynamicComponentsByCategory = {},
4872
- onAddComponent
4873
- }) => {
4874
- const [isOpen, setIsOpen] = React.useState(true);
4875
- const { formatMessage } = useIntl();
4876
- const formValues = useForm("DynamicComponent", (state) => state.values);
4877
- const {
4878
- edit: { components }
4879
- } = useDocLayout();
4880
- const title = React.useMemo(() => {
4881
- const { mainField } = components[componentUid]?.settings ?? { mainField: "id" };
4882
- const mainFieldValue = getIn(formValues, `${name2}.${index}.${mainField}`);
4883
- const displayedValue = mainField === "id" ? "" : String(mainFieldValue).trim();
4884
- const mainValue = displayedValue.length > 0 ? `- ${displayedValue}` : displayedValue;
4885
- return mainValue;
4886
- }, [componentUid, components, formValues, name2, index]);
4887
- const { icon, displayName } = React.useMemo(() => {
4888
- const [category] = componentUid.split(".");
4889
- const { icon: icon2, displayName: displayName2 } = (dynamicComponentsByCategory[category] ?? []).find(
4890
- (component) => component.uid === componentUid
4891
- ) ?? { icon: null, displayName: null };
4892
- return { icon: icon2, displayName: displayName2 };
4893
- }, [componentUid, dynamicComponentsByCategory]);
4894
- const handleToggle = () => {
4895
- setIsOpen((s) => !s);
4896
- };
4897
- const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
4898
- type: `${ItemTypes.DYNAMIC_ZONE}_${name2}`,
4899
- index,
4900
- item: {
4901
- index,
4902
- displayedValue: `${displayName} ${title}`,
4903
- icon
4904
- },
4905
- onMoveItem: onMoveComponent,
4906
- onDropItem,
4907
- onGrabItem,
4908
- onCancel
4909
- });
4910
- React.useEffect(() => {
4911
- dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
4912
- }, [dragPreviewRef, index]);
4913
- const composedBoxRefs = useComposedRefs(boxRef, dropRef);
4914
- const accordionActions = disabled ? null : /* @__PURE__ */ jsxs(ActionsFlex, { gap: 0, children: [
4915
- /* @__PURE__ */ jsx(
4916
- IconButtonCustom,
4917
- {
4918
- borderWidth: 0,
4919
- label: formatMessage(
4920
- {
4921
- id: getTranslation("components.DynamicZone.delete-label"),
4922
- defaultMessage: "Delete {name}"
4923
- },
4924
- { name: title }
4925
- ),
4926
- onClick: onRemoveComponentClick,
4927
- children: /* @__PURE__ */ jsx(Trash, {})
4928
- }
4929
- ),
4930
- /* @__PURE__ */ jsx(
4931
- IconButton,
4932
- {
4933
- forwardedAs: "div",
4934
- role: "button",
4935
- borderWidth: 0,
4936
- tabIndex: 0,
4937
- onClick: (e) => e.stopPropagation(),
4938
- "data-handler-id": handlerId,
4939
- ref: dragRef,
4940
- label: formatMessage({
4941
- id: getTranslation("components.DragHandle-label"),
4942
- defaultMessage: "Drag"
4943
- }),
4944
- onKeyDown: handleKeyDown,
4945
- children: /* @__PURE__ */ jsx(Drag, {})
4946
- }
4947
- ),
4948
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
4949
- /* @__PURE__ */ jsxs(Menu.Trigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
4950
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
4951
- /* @__PURE__ */ jsx(VisuallyHidden, { as: "span", children: formatMessage({
4952
- id: getTranslation("components.DynamicZone.more-actions"),
4953
- defaultMessage: "More actions"
4954
- }) })
4955
- ] }),
4956
- /* @__PURE__ */ jsxs(Menu.Content, { children: [
4957
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
4958
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
4959
- id: getTranslation("components.DynamicZone.add-item-above"),
4960
- defaultMessage: "Add component above"
4961
- }) }),
4962
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
4963
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
4964
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index), children: displayName2 }, componentUid))
4965
- ] }, category)) })
4966
- ] }),
4967
- /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
4968
- /* @__PURE__ */ jsx(Menu.SubTrigger, { children: formatMessage({
4969
- id: getTranslation("components.DynamicZone.add-item-below"),
4970
- defaultMessage: "Add component below"
4971
- }) }),
4972
- /* @__PURE__ */ jsx(Menu.SubContent, { children: Object.entries(dynamicComponentsByCategory).map(([category, components2]) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
4973
- /* @__PURE__ */ jsx(Menu.Label, { children: category }),
4974
- components2.map(({ displayName: displayName2, uid }) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => onAddComponent(uid, index + 1), children: displayName2 }, componentUid))
4975
- ] }, category)) })
4976
- ] })
4977
- ] })
4978
- ] })
4979
- ] });
4980
- return /* @__PURE__ */ jsxs(ComponentContainer, { as: "li", width: "100%", children: [
4981
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Rectangle, { background: "neutral200" }) }),
4982
- /* @__PURE__ */ jsx(StyledBox, { ref: composedBoxRefs, hasRadius: true, children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsxs(Accordion, { expanded: isOpen, onToggle: handleToggle, size: "S", children: [
4983
- /* @__PURE__ */ jsx(
4984
- AccordionToggle,
4963
+ return /* @__PURE__ */ jsx(MemoizedBlocksInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4964
+ case "component":
4965
+ return /* @__PURE__ */ jsx(
4966
+ MemoizedComponentInput,
4985
4967
  {
4986
- startIcon: /* @__PURE__ */ jsx(ComponentIcon, { icon, showBackground: false, size: "S" }),
4987
- action: accordionActions,
4988
- title: `${displayName} ${title}`,
4989
- togglePosition: "left"
4968
+ ...props,
4969
+ hint,
4970
+ layout: components[props.attribute.component].layout,
4971
+ disabled: fieldIsDisabled,
4972
+ children: (inputProps) => /* @__PURE__ */ jsx(InputRenderer, { ...inputProps })
4990
4973
  }
4991
- ),
4992
- /* @__PURE__ */ jsx(AccordionContent$1, { children: /* @__PURE__ */ jsx(AccordionContentRadius, { background: "neutral0", children: /* @__PURE__ */ jsx(Box, { paddingLeft: 6, paddingRight: 6, paddingTop: 6, paddingBottom: 6, children: components[componentUid]?.layout?.map((row, rowInd) => /* @__PURE__ */ jsx(Grid$1, { gap: 4, children: row.map(({ size, ...field }) => {
4993
- const fieldName = `${name2}.${index}.${field.name}`;
4994
- return /* @__PURE__ */ jsx(GridItem, { col: size, s: 12, xs: 12, children: /* @__PURE__ */ jsx(InputRenderer, { ...field, name: fieldName }) }, fieldName);
4995
- }) }, rowInd)) }) }) })
4996
- ] }) })
4997
- ] });
4974
+ );
4975
+ case "dynamiczone":
4976
+ return /* @__PURE__ */ jsx(DynamicZone, { ...props, hint, disabled: fieldIsDisabled });
4977
+ case "relation":
4978
+ return /* @__PURE__ */ jsx(MemoizedRelationsField, { ...props, hint, disabled: fieldIsDisabled });
4979
+ case "richtext":
4980
+ return /* @__PURE__ */ jsx(MemoizedWysiwyg, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4981
+ case "uid":
4982
+ return /* @__PURE__ */ jsx(MemoizedUIDInput, { ...props, hint, type: props.type, disabled: fieldIsDisabled });
4983
+ case "enumeration":
4984
+ return /* @__PURE__ */ jsx(
4985
+ InputRenderer$1,
4986
+ {
4987
+ ...props,
4988
+ hint,
4989
+ options: props.attribute.enum.map((value) => ({ value })),
4990
+ type: props.customField ? "custom-field" : props.type,
4991
+ disabled: fieldIsDisabled
4992
+ }
4993
+ );
4994
+ default:
4995
+ const { unique: _unique, mainField: _mainField, ...restProps } = props;
4996
+ return /* @__PURE__ */ jsx(
4997
+ InputRenderer$1,
4998
+ {
4999
+ ...restProps,
5000
+ hint,
5001
+ type: props.customField ? "custom-field" : props.type,
5002
+ disabled: fieldIsDisabled
5003
+ }
5004
+ );
5005
+ }
4998
5006
  };
4999
- const ActionsFlex = styled(Flex)`
5000
- /*
5001
- we need to remove the background from the button but we can't
5002
- wrap the element in styled because it breaks the forwardedAs which
5003
- we need for drag handler to work on firefox
5004
- */
5005
- div[role='button'] {
5006
- background: transparent;
5007
+ const attributeHasCustomFieldProperty = (attribute) => "customField" in attribute && typeof attribute.customField === "string";
5008
+ const useFieldHint = (hint = void 0, attribute) => {
5009
+ const { formatMessage } = useIntl();
5010
+ const { maximum, minimum } = getMinMax(attribute);
5011
+ if (!maximum && !minimum) {
5012
+ return hint;
5007
5013
  }
5008
- `;
5009
- const IconButtonCustom = styled(IconButton)`
5010
- background-color: transparent;
5011
-
5012
- svg path {
5013
- fill: ${({ theme, expanded }) => expanded ? theme.colors.primary600 : theme.colors.neutral600};
5014
+ const units = !["biginteger", "integer", "number", "dynamiczone", "component"].includes(
5015
+ attribute.type
5016
+ ) ? formatMessage(
5017
+ {
5018
+ id: "content-manager.form.Input.hint.character.unit",
5019
+ defaultMessage: "{maxValue, plural, one { character} other { characters}}"
5020
+ },
5021
+ {
5022
+ maxValue: Math.max(minimum || 0, maximum || 0)
5023
+ }
5024
+ ) : null;
5025
+ const hasMinAndMax = typeof minimum === "number" && typeof maximum === "number";
5026
+ return formatMessage(
5027
+ {
5028
+ id: "content-manager.form.Input.hint.text",
5029
+ defaultMessage: "{min, select, undefined {} other {min. {min}}}{divider}{max, select, undefined {} other {max. {max}}}{unit}{br}{description}"
5030
+ },
5031
+ {
5032
+ min: minimum,
5033
+ max: maximum,
5034
+ description: hint,
5035
+ unit: units,
5036
+ divider: hasMinAndMax ? formatMessage({
5037
+ id: "content-manager.form.Input.hint.minMaxDivider",
5038
+ defaultMessage: " / "
5039
+ }) : null,
5040
+ br: /* @__PURE__ */ jsx("br", {})
5041
+ }
5042
+ );
5043
+ };
5044
+ const getMinMax = (attribute) => {
5045
+ if ("min" in attribute || "max" in attribute) {
5046
+ return {
5047
+ maximum: !Number.isNaN(Number(attribute.max)) ? Number(attribute.max) : void 0,
5048
+ minimum: !Number.isNaN(Number(attribute.min)) ? Number(attribute.min) : void 0
5049
+ };
5050
+ } else if ("maxLength" in attribute || "minLength" in attribute) {
5051
+ return { maximum: attribute.maxLength, minimum: attribute.minLength };
5052
+ } else {
5053
+ return { maximum: void 0, minimum: void 0 };
5014
5054
  }
5055
+ };
5056
+ const MemoizedInputRenderer = memo(InputRenderer);
5057
+ const RESPONSIVE_CONTAINER_BREAKPOINTS = {
5058
+ sm: "27.5rem"
5059
+ // 440px
5060
+ };
5061
+ const ResponsiveGridRoot = styled(Grid$1.Root)`
5062
+ container-type: inline-size;
5015
5063
  `;
5016
- const StyledBox = styled(Box)`
5017
- > div:first-child {
5018
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
5064
+ const ResponsiveGridItem = styled(Grid$1.Item)`
5065
+ grid-column: span 12;
5066
+
5067
+ @container (min-width: ${RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
5068
+ ${({ col }) => col && `grid-column: span ${col};`}
5019
5069
  }
5020
5070
  `;
5021
- const AccordionContentRadius = styled(Box)`
5022
- border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
5023
- `;
5024
- const Rectangle = styled(Box)`
5025
- width: ${({ theme }) => theme.spaces[2]};
5026
- height: ${({ theme }) => theme.spaces[4]};
5027
- `;
5028
- const Preview = styled.span`
5029
- display: block;
5030
- background-color: ${({ theme }) => theme.colors.primary100};
5031
- outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5032
- outline-offset: -1px;
5033
- padding: ${({ theme }) => theme.spaces[6]};
5034
- `;
5035
- const ComponentContainer = styled(Box)`
5036
- list-style: none;
5037
- padding: 0;
5038
- margin: 0;
5039
- `;
5040
- const DynamicZoneLabel = ({
5041
- hint,
5042
- label,
5043
- labelAction,
5071
+ const FormLayout = ({ layout }) => {
5072
+ const { formatMessage } = useIntl();
5073
+ const { model } = useDoc();
5074
+ return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((panel, index) => {
5075
+ if (panel.some((row) => row.some((field) => field.type === "dynamiczone"))) {
5076
+ const [row] = panel;
5077
+ const [field] = row;
5078
+ const fieldWithTranslatedLabel = {
5079
+ ...field,
5080
+ label: formatMessage({
5081
+ id: `content-manager.content-types.${model}.${field.name}`,
5082
+ defaultMessage: field.label
5083
+ })
5084
+ };
5085
+ return /* @__PURE__ */ jsx(Grid$1.Root, { gap: 4, children: /* @__PURE__ */ jsx(Grid$1.Item, { col: 12, s: 12, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel }) }) }, field.name);
5086
+ }
5087
+ return /* @__PURE__ */ jsx(
5088
+ Box,
5089
+ {
5090
+ hasRadius: true,
5091
+ background: "neutral0",
5092
+ shadow: "tableShadow",
5093
+ paddingLeft: 6,
5094
+ paddingRight: 6,
5095
+ paddingTop: 6,
5096
+ paddingBottom: 6,
5097
+ borderColor: "neutral150",
5098
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: panel.map((row, gridRowIndex) => /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5099
+ const fieldWithTranslatedLabel = {
5100
+ ...field,
5101
+ label: formatMessage({
5102
+ id: `content-manager.content-types.${model}.${field.name}`,
5103
+ defaultMessage: field.label
5104
+ })
5105
+ };
5106
+ return /* @__PURE__ */ jsx(
5107
+ ResponsiveGridItem,
5108
+ {
5109
+ col: size,
5110
+ s: 12,
5111
+ xs: 12,
5112
+ direction: "column",
5113
+ alignItems: "stretch",
5114
+ children: /* @__PURE__ */ jsx(MemoizedInputRenderer, { ...fieldWithTranslatedLabel })
5115
+ },
5116
+ field.name
5117
+ );
5118
+ }) }, gridRowIndex)) })
5119
+ },
5120
+ index
5121
+ );
5122
+ }) });
5123
+ };
5124
+ const NonRepeatableComponent = ({
5125
+ attribute,
5044
5126
  name: name2,
5045
- numberOfComponents = 0,
5046
- required
5127
+ children,
5128
+ layout
5047
5129
  }) => {
5048
- return /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5130
+ const { formatMessage } = useIntl();
5131
+ const { value } = useField(name2);
5132
+ const level = useComponent("NonRepeatableComponent", (state) => state.level);
5133
+ const isNested = level > 0;
5134
+ return /* @__PURE__ */ jsx(ComponentProvider, { id: value?.id, uid: attribute.component, level: level + 1, type: "component", children: /* @__PURE__ */ jsx(
5049
5135
  Box,
5050
5136
  {
5051
- paddingTop: 3,
5052
- paddingBottom: 3,
5053
- paddingRight: 4,
5054
- paddingLeft: 4,
5055
- borderRadius: "26px",
5056
- background: "neutral0",
5057
- shadow: "filterShadow",
5058
- color: "neutral500",
5059
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", justifyContent: "center", children: [
5060
- /* @__PURE__ */ jsxs(Flex, { maxWidth: "35.6rem", children: [
5061
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", ellipsis: true, children: [
5062
- label || name2,
5063
- " "
5064
- ] }),
5065
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: [
5066
- "(",
5067
- numberOfComponents,
5068
- ")"
5069
- ] }),
5070
- required && /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: "*" }),
5071
- labelAction && /* @__PURE__ */ jsx(Box, { paddingLeft: 1, children: labelAction })
5072
- ] }),
5073
- hint && /* @__PURE__ */ jsx(Box, { paddingTop: 1, maxWidth: "35.6rem", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: hint }) })
5074
- ] })
5137
+ background: "neutral100",
5138
+ paddingLeft: 6,
5139
+ paddingRight: 6,
5140
+ paddingTop: 6,
5141
+ paddingBottom: 6,
5142
+ hasRadius: isNested,
5143
+ borderColor: isNested ? "neutral200" : void 0,
5144
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: layout.map((row, index) => {
5145
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5146
+ const completeFieldName = `${name2}.${field.name}`;
5147
+ const translatedLabel = formatMessage({
5148
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5149
+ defaultMessage: field.label
5150
+ });
5151
+ return /* @__PURE__ */ jsx(
5152
+ ResponsiveGridItem,
5153
+ {
5154
+ col: size,
5155
+ s: 12,
5156
+ xs: 12,
5157
+ direction: "column",
5158
+ alignItems: "stretch",
5159
+ children: children({ ...field, label: translatedLabel, name: completeFieldName })
5160
+ },
5161
+ completeFieldName
5162
+ );
5163
+ }) }, index);
5164
+ }) })
5075
5165
  }
5076
5166
  ) });
5077
5167
  };
5078
- const [DynamicZoneProvider, useDynamicZone] = createContext(
5079
- "DynamicZone",
5080
- {
5081
- isInDynamicZone: false
5082
- }
5083
- );
5084
- const DynamicZone = ({
5168
+ const RepeatableComponent = ({
5085
5169
  attribute,
5086
5170
  disabled,
5087
- hint,
5088
- label,
5089
- labelAction,
5090
5171
  name: name2,
5091
- required = false
5172
+ mainField,
5173
+ children,
5174
+ layout
5092
5175
  }) => {
5093
- const { max = Infinity, min = -Infinity } = attribute ?? {};
5094
- const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
5095
- const [liveText, setLiveText] = React.useState("");
5176
+ const { toggleNotification } = useNotification();
5177
+ const { formatMessage } = useIntl();
5178
+ const { search: searchString } = useLocation();
5179
+ const search = React.useMemo(() => new URLSearchParams(searchString), [searchString]);
5096
5180
  const { components } = useDoc();
5097
- const { addFieldRow, removeFieldRow, moveFieldRow } = useForm(
5098
- "DynamicZone",
5099
- ({ addFieldRow: addFieldRow2, removeFieldRow: removeFieldRow2, moveFieldRow: moveFieldRow2 }) => ({
5100
- addFieldRow: addFieldRow2,
5101
- removeFieldRow: removeFieldRow2,
5102
- moveFieldRow: moveFieldRow2
5103
- })
5104
- );
5105
- const { value = [], error } = useField(name2);
5106
- const dynamicComponentsByCategory = React.useMemo(() => {
5107
- return attribute.components.reduce((acc, componentUid) => {
5108
- const { category, info } = components[componentUid] ?? { info: {} };
5109
- const component = { uid: componentUid, displayName: info.displayName, icon: info.icon };
5110
- if (!acc[category]) {
5111
- acc[category] = [];
5181
+ const {
5182
+ value = [],
5183
+ error,
5184
+ rawError
5185
+ } = useField(name2);
5186
+ const addFieldRow = useForm("RepeatableComponent", (state) => state.addFieldRow);
5187
+ const moveFieldRow = useForm("RepeatableComponent", (state) => state.moveFieldRow);
5188
+ const removeFieldRow = useForm("RepeatableComponent", (state) => state.removeFieldRow);
5189
+ const { max = Infinity } = attribute;
5190
+ const [collapseToOpen, setCollapseToOpen] = React.useState("");
5191
+ const [liveText, setLiveText] = React.useState("");
5192
+ React.useEffect(() => {
5193
+ const hasNestedErrors = rawError && Array.isArray(rawError) && rawError.length > 0;
5194
+ const hasNestedValue = value && Array.isArray(value) && value.length > 0;
5195
+ if (hasNestedErrors && hasNestedValue) {
5196
+ const errorOpenItems = rawError.map((_, idx) => {
5197
+ return value[idx] ? value[idx].__temp_key__ : null;
5198
+ }).filter((value2) => !!value2);
5199
+ if (errorOpenItems && errorOpenItems.length > 0) {
5200
+ setCollapseToOpen((collapseToOpen2) => {
5201
+ if (!errorOpenItems.includes(collapseToOpen2)) {
5202
+ return errorOpenItems[0];
5203
+ }
5204
+ return collapseToOpen2;
5205
+ });
5112
5206
  }
5113
- acc[category] = [...acc[category], component];
5114
- return acc;
5115
- }, {});
5116
- }, [attribute.components, components]);
5117
- const { formatMessage } = useIntl();
5118
- const { toggleNotification } = useNotification();
5119
- const dynamicDisplayedComponentsLength = value.length;
5120
- const handleAddComponent = (uid, position) => {
5121
- setAddComponentIsOpen(false);
5122
- const schema = components[uid];
5123
- const form = createDefaultForm(schema, components);
5124
- const transformations = pipe$1(transformDocument(schema, components), (data2) => ({
5125
- ...data2,
5126
- __component: uid
5127
- }));
5128
- const data = transformations(form);
5129
- addFieldRow(name2, data, position);
5207
+ }
5208
+ }, [rawError, value]);
5209
+ const componentTmpKeyWithFocussedField = React.useMemo(() => {
5210
+ if (search.has("field")) {
5211
+ const fieldParam = search.get("field");
5212
+ if (!fieldParam) {
5213
+ return void 0;
5214
+ }
5215
+ const [, path] = fieldParam.split(`${name2}.`);
5216
+ if (getIn(value, path, void 0) !== void 0) {
5217
+ const [subpath] = path.split(".");
5218
+ return getIn(value, subpath, void 0)?.__temp_key__;
5219
+ }
5220
+ }
5221
+ return void 0;
5222
+ }, [search, name2, value]);
5223
+ const prevValue = usePrev(value);
5224
+ React.useEffect(() => {
5225
+ if (prevValue && prevValue.length < value.length) {
5226
+ setCollapseToOpen(value[value.length - 1].__temp_key__);
5227
+ }
5228
+ }, [value, prevValue]);
5229
+ React.useEffect(() => {
5230
+ if (typeof componentTmpKeyWithFocussedField === "string") {
5231
+ setCollapseToOpen(componentTmpKeyWithFocussedField);
5232
+ }
5233
+ }, [componentTmpKeyWithFocussedField]);
5234
+ const toggleCollapses = () => {
5235
+ setCollapseToOpen("");
5130
5236
  };
5131
- const handleClickOpenPicker = () => {
5132
- if (dynamicDisplayedComponentsLength < max) {
5133
- setAddComponentIsOpen((prev) => !prev);
5134
- } else {
5237
+ const handleClick = () => {
5238
+ if (value.length < max) {
5239
+ const schema = components[attribute.component];
5240
+ const form = createDefaultForm(schema, components);
5241
+ const data = transformDocument(schema, components)(form);
5242
+ addFieldRow(name2, data);
5243
+ } else if (value.length >= max) {
5135
5244
  toggleNotification({
5136
5245
  type: "info",
5137
5246
  message: formatMessage({
@@ -5140,7 +5249,7 @@ const DynamicZone = ({
5140
5249
  });
5141
5250
  }
5142
5251
  };
5143
- const handleMoveComponent = (newIndex, currentIndex) => {
5252
+ const handleMoveComponentField = (newIndex, currentIndex) => {
5144
5253
  setLiveText(
5145
5254
  formatMessage(
5146
5255
  {
@@ -5155,6 +5264,9 @@ const DynamicZone = ({
5155
5264
  );
5156
5265
  moveFieldRow(name2, currentIndex, newIndex);
5157
5266
  };
5267
+ const handleValueChange = (key) => {
5268
+ setCollapseToOpen(key);
5269
+ };
5158
5270
  const getItemPos = (index) => `${index + 1} of ${value.length}`;
5159
5271
  const handleCancel = (index) => {
5160
5272
  setLiveText(
@@ -5197,123 +5309,277 @@ const DynamicZone = ({
5197
5309
  )
5198
5310
  );
5199
5311
  };
5200
- const handleRemoveComponent = (name22, currentIndex) => () => {
5201
- removeFieldRow(name22, currentIndex);
5202
- };
5203
- const hasError = error !== void 0 || dynamicDisplayedComponentsLength < min || dynamicDisplayedComponentsLength > max;
5204
- const renderButtonLabel = () => {
5205
- if (addComponentIsOpen) {
5206
- return formatMessage({ id: "app.utils.close-label", defaultMessage: "Close" });
5207
- }
5208
- if (hasError && dynamicDisplayedComponentsLength > max) {
5209
- return formatMessage(
5210
- {
5211
- id: getTranslation(`components.DynamicZone.extra-components`),
5212
- defaultMessage: "There {number, plural, =0 {are # extra components} one {is # extra component} other {are # extra components}}"
5213
- },
5214
- {
5215
- number: dynamicDisplayedComponentsLength - max
5216
- }
5217
- );
5218
- }
5219
- if (hasError && dynamicDisplayedComponentsLength < min) {
5220
- return formatMessage(
5221
- {
5222
- id: getTranslation(`components.DynamicZone.missing-components`),
5223
- defaultMessage: "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}"
5224
- },
5225
- { number: min - dynamicDisplayedComponentsLength }
5226
- );
5227
- }
5228
- return formatMessage(
5229
- {
5230
- id: getTranslation("components.DynamicZone.add-component"),
5231
- defaultMessage: "Add a component to {componentName}"
5232
- },
5233
- { componentName: label || name2 }
5234
- );
5235
- };
5236
- const level = useComponent("DynamicZone", (state) => state.level);
5237
5312
  const ariaDescriptionId = React.useId();
5238
- return /* @__PURE__ */ jsx(DynamicZoneProvider, { isInDynamicZone: true, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
5239
- dynamicDisplayedComponentsLength > 0 && /* @__PURE__ */ jsxs(Box, { children: [
5240
- /* @__PURE__ */ jsx(
5241
- DynamicZoneLabel,
5242
- {
5243
- hint,
5244
- label,
5245
- labelAction,
5246
- name: name2,
5247
- numberOfComponents: dynamicDisplayedComponentsLength,
5248
- required
5249
- }
5250
- ),
5251
- /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5252
- id: getTranslation("dnd.instructions"),
5253
- defaultMessage: `Press spacebar to grab and re-order`
5254
- }) }),
5255
- /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5256
- /* @__PURE__ */ jsx("ol", { "aria-describedby": ariaDescriptionId, children: value.map((field, index) => /* @__PURE__ */ jsx(
5257
- ComponentProvider,
5258
- {
5259
- level: level + 1,
5260
- uid: field.__component,
5261
- id: field.id,
5262
- type: "dynamiczone",
5263
- children: /* @__PURE__ */ jsx(
5264
- DynamicComponent,
5265
- {
5266
- disabled,
5267
- name: name2,
5268
- index,
5269
- componentUid: field.__component,
5270
- onMoveComponent: handleMoveComponent,
5271
- onRemoveComponentClick: handleRemoveComponent(name2, index),
5272
- onCancel: handleCancel,
5273
- onDropItem: handleDropItem,
5274
- onGrabItem: handleGrabItem,
5275
- onAddComponent: handleAddComponent,
5276
- dynamicComponentsByCategory
5277
- }
5278
- )
5279
- },
5280
- field.__temp_key__
5281
- )) })
5282
- ] }),
5283
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(
5284
- AddComponentButton,
5313
+ const level = useComponent("RepeatableComponent", (state) => state.level);
5314
+ if (value.length === 0) {
5315
+ return /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleClick });
5316
+ }
5317
+ return /* @__PURE__ */ jsxs(Box, { hasRadius: true, children: [
5318
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: ariaDescriptionId, children: formatMessage({
5319
+ id: getTranslation("dnd.instructions"),
5320
+ defaultMessage: `Press spacebar to grab and re-order`
5321
+ }) }),
5322
+ /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
5323
+ /* @__PURE__ */ jsxs(
5324
+ AccordionRoot,
5285
5325
  {
5286
- hasError,
5287
- isDisabled: disabled,
5288
- isOpen: addComponentIsOpen,
5289
- onClick: handleClickOpenPicker,
5290
- children: renderButtonLabel()
5326
+ $error: error,
5327
+ value: collapseToOpen,
5328
+ onValueChange: handleValueChange,
5329
+ "aria-describedby": ariaDescriptionId,
5330
+ children: [
5331
+ value.map(({ __temp_key__: key, id }, index) => {
5332
+ const nameWithIndex = `${name2}.${index}`;
5333
+ return /* @__PURE__ */ jsx(
5334
+ ComponentProvider,
5335
+ {
5336
+ id,
5337
+ uid: attribute.component,
5338
+ level: level + 1,
5339
+ type: "repeatable",
5340
+ children: /* @__PURE__ */ jsx(
5341
+ Component,
5342
+ {
5343
+ disabled,
5344
+ name: nameWithIndex,
5345
+ attribute,
5346
+ index,
5347
+ mainField,
5348
+ onMoveItem: handleMoveComponentField,
5349
+ onDeleteComponent: () => {
5350
+ removeFieldRow(name2, index);
5351
+ toggleCollapses();
5352
+ },
5353
+ toggleCollapses,
5354
+ onCancel: handleCancel,
5355
+ onDropItem: handleDropItem,
5356
+ onGrabItem: handleGrabItem,
5357
+ __temp_key__: key,
5358
+ children: layout.map((row, index2) => {
5359
+ return /* @__PURE__ */ jsx(ResponsiveGridRoot, { gap: 4, children: row.map(({ size, ...field }) => {
5360
+ const completeFieldName = `${nameWithIndex}.${field.name}`;
5361
+ const translatedLabel = formatMessage({
5362
+ id: `content-manager.components.${attribute.component}.${field.name}`,
5363
+ defaultMessage: field.label
5364
+ });
5365
+ return /* @__PURE__ */ jsx(
5366
+ ResponsiveGridItem,
5367
+ {
5368
+ col: size,
5369
+ s: 12,
5370
+ xs: 12,
5371
+ direction: "column",
5372
+ alignItems: "stretch",
5373
+ children: children({
5374
+ ...field,
5375
+ label: translatedLabel,
5376
+ name: completeFieldName
5377
+ })
5378
+ },
5379
+ completeFieldName
5380
+ );
5381
+ }) }, index2);
5382
+ })
5383
+ }
5384
+ )
5385
+ },
5386
+ key
5387
+ );
5388
+ }),
5389
+ /* @__PURE__ */ jsx(TextButtonCustom, { disabled, onClick: handleClick, startIcon: /* @__PURE__ */ jsx(Plus, {}), children: formatMessage({
5390
+ id: getTranslation("containers.EditView.add.new-entry"),
5391
+ defaultMessage: "Add an entry"
5392
+ }) })
5393
+ ]
5291
5394
  }
5292
- ) }),
5293
- /* @__PURE__ */ jsx(
5294
- ComponentPicker,
5395
+ )
5396
+ ] });
5397
+ };
5398
+ const AccordionRoot = styled(Accordion.Root)`
5399
+ border: 1px solid
5400
+ ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
5401
+ `;
5402
+ const TextButtonCustom = styled(TextButton)`
5403
+ width: 100%;
5404
+ display: flex;
5405
+ justify-content: center;
5406
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
5407
+ padding-inline: ${(props) => props.theme.spaces[6]};
5408
+ padding-block: ${(props) => props.theme.spaces[3]};
5409
+
5410
+ &:not([disabled]) {
5411
+ cursor: pointer;
5412
+
5413
+ &:hover {
5414
+ background-color: ${(props) => props.theme.colors.primary100};
5415
+ }
5416
+ }
5417
+
5418
+ span {
5419
+ font-weight: 600;
5420
+ font-size: 1.4rem;
5421
+ line-height: 2.4rem;
5422
+ }
5423
+
5424
+ @media (prefers-reduced-motion: no-preference) {
5425
+ transition: background-color 120ms ${(props) => props.theme.motion.easings.easeOutQuad};
5426
+ }
5427
+ `;
5428
+ const Component = ({
5429
+ disabled,
5430
+ index,
5431
+ name: name2,
5432
+ mainField = {
5433
+ name: "id",
5434
+ type: "integer"
5435
+ },
5436
+ children,
5437
+ onDeleteComponent,
5438
+ toggleCollapses,
5439
+ __temp_key__,
5440
+ ...dragProps
5441
+ }) => {
5442
+ const { formatMessage } = useIntl();
5443
+ const displayValue = useForm("RepeatableComponent", (state) => {
5444
+ return getIn(state.values, [...name2.split("."), mainField.name]);
5445
+ });
5446
+ const accordionRef = React.useRef(null);
5447
+ const componentKey = name2.split(".").slice(0, -1).join(".");
5448
+ const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(!disabled, {
5449
+ type: `${ItemTypes.COMPONENT}_${componentKey}`,
5450
+ index,
5451
+ item: {
5452
+ index,
5453
+ displayedValue: displayValue
5454
+ },
5455
+ onStart() {
5456
+ toggleCollapses();
5457
+ },
5458
+ ...dragProps
5459
+ });
5460
+ React.useEffect(() => {
5461
+ dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
5462
+ }, [dragPreviewRef, index]);
5463
+ const composedAccordionRefs = useComposedRefs(accordionRef, dragRef);
5464
+ const composedBoxRefs = useComposedRefs(
5465
+ boxRef,
5466
+ dropRef
5467
+ );
5468
+ return /* @__PURE__ */ jsx(Fragment, { children: isDragging ? /* @__PURE__ */ jsx(Preview, {}) : /* @__PURE__ */ jsxs(Accordion.Item, { ref: composedBoxRefs, value: __temp_key__, children: [
5469
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
5470
+ /* @__PURE__ */ jsx(Accordion.Trigger, { children: displayValue }),
5471
+ /* @__PURE__ */ jsxs(Accordion.Actions, { children: [
5472
+ /* @__PURE__ */ jsx(
5473
+ IconButton,
5474
+ {
5475
+ variant: "ghost",
5476
+ onClick: onDeleteComponent,
5477
+ label: formatMessage({
5478
+ id: getTranslation("containers.Edit.delete"),
5479
+ defaultMessage: "Delete"
5480
+ }),
5481
+ children: /* @__PURE__ */ jsx(Trash, {})
5482
+ }
5483
+ ),
5484
+ /* @__PURE__ */ jsx(
5485
+ IconButton,
5486
+ {
5487
+ ref: composedAccordionRefs,
5488
+ variant: "ghost",
5489
+ onClick: (e) => e.stopPropagation(),
5490
+ "data-handler-id": handlerId,
5491
+ label: formatMessage({
5492
+ id: getTranslation("components.DragHandle-label"),
5493
+ defaultMessage: "Drag"
5494
+ }),
5495
+ onKeyDown: handleKeyDown,
5496
+ children: /* @__PURE__ */ jsx(Drag, {})
5497
+ }
5498
+ )
5499
+ ] })
5500
+ ] }),
5501
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(
5502
+ Flex,
5295
5503
  {
5296
- dynamicComponentsByCategory,
5297
- isOpen: addComponentIsOpen,
5298
- onClickAddComponent: handleAddComponent
5504
+ direction: "column",
5505
+ alignItems: "stretch",
5506
+ background: "neutral100",
5507
+ padding: 6,
5508
+ gap: 6,
5509
+ children
5299
5510
  }
5300
- )
5511
+ ) })
5301
5512
  ] }) });
5302
5513
  };
5514
+ const Preview = () => {
5515
+ return /* @__PURE__ */ jsx(StyledSpan, { tag: "span", padding: 6, background: "primary100" });
5516
+ };
5517
+ const StyledSpan = styled(Box)`
5518
+ display: block;
5519
+ outline: 1px dashed ${({ theme }) => theme.colors.primary500};
5520
+ outline-offset: -1px;
5521
+ `;
5522
+ const ComponentInput = ({
5523
+ label,
5524
+ required,
5525
+ name: name2,
5526
+ attribute,
5527
+ disabled,
5528
+ labelAction,
5529
+ ...props
5530
+ }) => {
5531
+ const { formatMessage } = useIntl();
5532
+ const field = useField(name2);
5533
+ const showResetComponent = !attribute.repeatable && field.value && !disabled;
5534
+ const { components } = useDoc();
5535
+ const handleInitialisationClick = () => {
5536
+ const schema = components[attribute.component];
5537
+ const form = createDefaultForm(schema, components);
5538
+ const data = transformDocument(schema, components)(form);
5539
+ field.onChange(name2, data);
5540
+ };
5541
+ return /* @__PURE__ */ jsxs(Field.Root, { error: field.error, required, children: [
5542
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
5543
+ /* @__PURE__ */ jsxs(Field.Label, { action: labelAction, children: [
5544
+ label,
5545
+ attribute.repeatable && /* @__PURE__ */ jsxs(Fragment, { children: [
5546
+ " (",
5547
+ Array.isArray(field.value) ? field.value.length : 0,
5548
+ ")"
5549
+ ] })
5550
+ ] }),
5551
+ showResetComponent && /* @__PURE__ */ jsx(
5552
+ IconButton,
5553
+ {
5554
+ label: formatMessage({
5555
+ id: getTranslation("components.reset-entry"),
5556
+ defaultMessage: "Reset Entry"
5557
+ }),
5558
+ variant: "ghost",
5559
+ onClick: () => {
5560
+ field.onChange(name2, null);
5561
+ },
5562
+ children: /* @__PURE__ */ jsx(Trash, {})
5563
+ }
5564
+ )
5565
+ ] }),
5566
+ !attribute.repeatable && !field.value && /* @__PURE__ */ jsx(Initializer, { disabled, name: name2, onClick: handleInitialisationClick }),
5567
+ !attribute.repeatable && field.value ? /* @__PURE__ */ jsx(NonRepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }) : null,
5568
+ attribute.repeatable && /* @__PURE__ */ jsx(RepeatableComponent, { attribute, name: name2, disabled, ...props, children: props.children }),
5569
+ /* @__PURE__ */ jsx(Field.Error, {})
5570
+ ] });
5571
+ };
5572
+ const MemoizedComponentInput = React.memo(ComponentInput);
5303
5573
  export {
5304
- BlocksInput as B,
5305
- ComponentInput as C,
5306
5574
  DynamicZone as D,
5307
- InputRenderer as I,
5575
+ FormLayout as F,
5576
+ MemoizedUIDInput as M,
5308
5577
  NotAllowedInput as N,
5309
- UIDInput as U,
5310
- Wysiwyg as W,
5311
5578
  useDynamicZone as a,
5312
5579
  useFieldHint as b,
5313
- createDefaultForm as c,
5314
- prepareTempKeys as p,
5315
- removeFieldsThatDontExistOnSchema as r,
5316
- transformDocument as t,
5580
+ MemoizedWysiwyg as c,
5581
+ MemoizedComponentInput as d,
5582
+ MemoizedBlocksInput as e,
5317
5583
  useLazyComponents as u
5318
5584
  };
5319
- //# sourceMappingURL=Field-kVFO4ZKB.mjs.map
5585
+ //# sourceMappingURL=Input-ww3KFYZr.mjs.map