@strapi/content-type-builder 5.53.0 → 5.55.0

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 (208) hide show
  1. package/dist/admin/components/AIChat/hooks/useAIFetch.js +6 -2
  2. package/dist/admin/components/AIChat/hooks/useAIFetch.js.map +1 -1
  3. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs +7 -3
  4. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js +20 -0
  6. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js.map +1 -0
  7. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs +18 -0
  8. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs.map +1 -0
  9. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js +83 -59
  10. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js.map +1 -1
  11. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs +86 -62
  12. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs.map +1 -1
  13. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js +112 -0
  14. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js.map +1 -0
  15. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs +110 -0
  16. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs.map +1 -0
  17. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js +159 -0
  18. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js.map +1 -0
  19. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs +157 -0
  20. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs.map +1 -0
  21. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js +311 -0
  22. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js.map +1 -0
  23. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs +309 -0
  24. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs.map +1 -0
  25. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js +379 -0
  26. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js.map +1 -0
  27. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs +376 -0
  28. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs.map +1 -0
  29. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js +172 -0
  30. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js.map +1 -0
  31. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs +166 -0
  32. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs.map +1 -0
  33. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js +62 -0
  34. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js.map +1 -0
  35. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs +60 -0
  36. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs.map +1 -0
  37. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js +145 -0
  38. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js.map +1 -0
  39. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs +143 -0
  40. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs.map +1 -0
  41. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js +176 -0
  42. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js.map +1 -0
  43. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs +169 -0
  44. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs.map +1 -0
  45. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js +277 -0
  46. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js.map +1 -0
  47. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs +273 -0
  48. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs.map +1 -0
  49. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js +62 -0
  50. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js.map +1 -0
  51. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs +58 -0
  52. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs.map +1 -0
  53. package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
  54. package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
  55. package/dist/admin/components/DataManager/DataManagerProvider.js +70 -8
  56. package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
  57. package/dist/admin/components/DataManager/DataManagerProvider.mjs +70 -8
  58. package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
  59. package/dist/admin/components/DataManager/reducer.js +411 -33
  60. package/dist/admin/components/DataManager/reducer.js.map +1 -1
  61. package/dist/admin/components/DataManager/reducer.mjs +411 -33
  62. package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
  63. package/dist/admin/components/DataManager/utils/cleanData.js +11 -2
  64. package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
  65. package/dist/admin/components/DataManager/utils/cleanData.mjs +11 -2
  66. package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
  67. package/dist/admin/components/DataManager/utils/contentStructure.js +150 -0
  68. package/dist/admin/components/DataManager/utils/contentStructure.js.map +1 -0
  69. package/dist/admin/components/DataManager/utils/contentStructure.mjs +133 -0
  70. package/dist/admin/components/DataManager/utils/contentStructure.mjs.map +1 -0
  71. package/dist/admin/components/FolderSelect.js +200 -0
  72. package/dist/admin/components/FolderSelect.js.map +1 -0
  73. package/dist/admin/components/FolderSelect.mjs +198 -0
  74. package/dist/admin/components/FolderSelect.mjs.map +1 -0
  75. package/dist/admin/components/FormModal/FormModal.js +23 -2
  76. package/dist/admin/components/FormModal/FormModal.js.map +1 -1
  77. package/dist/admin/components/FormModal/FormModal.mjs +23 -2
  78. package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
  79. package/dist/admin/components/FormModal/contentType/contentTypeForm.js +15 -18
  80. package/dist/admin/components/FormModal/contentType/contentTypeForm.js.map +1 -1
  81. package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs +15 -18
  82. package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs.map +1 -1
  83. package/dist/admin/components/FormModal/reducer.js +6 -0
  84. package/dist/admin/components/FormModal/reducer.js.map +1 -1
  85. package/dist/admin/components/FormModal/reducer.mjs +6 -0
  86. package/dist/admin/components/FormModal/reducer.mjs.map +1 -1
  87. package/dist/admin/pages/App/index.js +2 -5
  88. package/dist/admin/pages/App/index.js.map +1 -1
  89. package/dist/admin/pages/App/index.mjs +2 -5
  90. package/dist/admin/pages/App/index.mjs.map +1 -1
  91. package/dist/admin/src/components/AIChat/hooks/usePrefetchAIToken.d.ts +1 -0
  92. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.d.ts +16 -0
  93. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.d.ts +12 -0
  94. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.d.ts +14 -0
  95. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.d.ts +38 -0
  96. package/dist/admin/src/components/ContentTypeBuilderNav/{useContentTypeBuilderMenu.d.ts → hooks/useContentTypeBuilderMenu.d.ts} +17 -7
  97. package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useFolderActions.d.ts +42 -0
  98. package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useSortableTree.d.ts +53 -0
  99. package/dist/admin/src/components/ContentTypeBuilderNav/lib/buildFolderTree.d.ts +42 -0
  100. package/dist/admin/src/components/ContentTypeBuilderNav/lib/dropProjection.d.ts +58 -0
  101. package/dist/admin/src/components/ContentTypeBuilderNav/lib/flatModel.d.ts +18 -0
  102. package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +41 -0
  103. package/dist/admin/src/components/DataManager/reducer.d.ts +105 -1
  104. package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +5 -1
  105. package/dist/admin/src/components/DataManager/utils/contentStructure.d.ts +68 -0
  106. package/dist/admin/src/components/FolderSelect.d.ts +18 -0
  107. package/dist/admin/src/components/FormModal/contentType/contentTypeForm.d.ts +0 -21
  108. package/dist/admin/src/components/FormModal/forms/forms.d.ts +0 -10
  109. package/dist/admin/src/components/FormModal/reducer.d.ts +7 -0
  110. package/dist/admin/src/utils/folderTelemetry.d.ts +5 -0
  111. package/dist/admin/translations/en.json.js +23 -0
  112. package/dist/admin/translations/en.json.js.map +1 -1
  113. package/dist/admin/translations/en.json.mjs +23 -0
  114. package/dist/admin/translations/en.json.mjs.map +1 -1
  115. package/dist/admin/utils/folderTelemetry.js +19 -0
  116. package/dist/admin/utils/folderTelemetry.js.map +1 -0
  117. package/dist/admin/utils/folderTelemetry.mjs +16 -0
  118. package/dist/admin/utils/folderTelemetry.mjs.map +1 -0
  119. package/dist/server/controllers/schema.js +1 -1
  120. package/dist/server/controllers/schema.js.map +1 -1
  121. package/dist/server/controllers/schema.mjs +1 -1
  122. package/dist/server/controllers/schema.mjs.map +1 -1
  123. package/dist/server/controllers/validation/common.js +3 -0
  124. package/dist/server/controllers/validation/common.js.map +1 -1
  125. package/dist/server/controllers/validation/common.mjs +3 -1
  126. package/dist/server/controllers/validation/common.mjs.map +1 -1
  127. package/dist/server/controllers/validation/content-structure.js +177 -0
  128. package/dist/server/controllers/validation/content-structure.js.map +1 -0
  129. package/dist/server/controllers/validation/content-structure.mjs +173 -0
  130. package/dist/server/controllers/validation/content-structure.mjs.map +1 -0
  131. package/dist/server/controllers/validation/schema.js +3 -1
  132. package/dist/server/controllers/validation/schema.js.map +1 -1
  133. package/dist/server/controllers/validation/schema.mjs +3 -1
  134. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  135. package/dist/server/register.js +1 -1
  136. package/dist/server/register.js.map +1 -1
  137. package/dist/server/register.mjs +1 -1
  138. package/dist/server/register.mjs.map +1 -1
  139. package/dist/server/routes/content-api.js +4 -4
  140. package/dist/server/routes/content-api.js.map +1 -1
  141. package/dist/server/routes/content-api.mjs +4 -4
  142. package/dist/server/routes/content-api.mjs.map +1 -1
  143. package/dist/server/services/api-handler.js +37 -4
  144. package/dist/server/services/api-handler.js.map +1 -1
  145. package/dist/server/services/api-handler.mjs +36 -5
  146. package/dist/server/services/api-handler.mjs.map +1 -1
  147. package/dist/server/services/content-structure.js +174 -0
  148. package/dist/server/services/content-structure.js.map +1 -0
  149. package/dist/server/services/content-structure.mjs +172 -0
  150. package/dist/server/services/content-structure.mjs.map +1 -0
  151. package/dist/server/services/content-types.js +196 -44
  152. package/dist/server/services/content-types.js.map +1 -1
  153. package/dist/server/services/content-types.mjs +195 -45
  154. package/dist/server/services/content-types.mjs.map +1 -1
  155. package/dist/server/services/index.js +3 -1
  156. package/dist/server/services/index.js.map +1 -1
  157. package/dist/server/services/index.mjs +3 -1
  158. package/dist/server/services/index.mjs.map +1 -1
  159. package/dist/server/services/schema-builder/index.js +4 -2
  160. package/dist/server/services/schema-builder/index.js.map +1 -1
  161. package/dist/server/services/schema-builder/index.mjs +4 -2
  162. package/dist/server/services/schema-builder/index.mjs.map +1 -1
  163. package/dist/server/services/schema-builder/schema-handler.js +19 -17
  164. package/dist/server/services/schema-builder/schema-handler.js.map +1 -1
  165. package/dist/server/services/schema-builder/schema-handler.mjs +19 -17
  166. package/dist/server/services/schema-builder/schema-handler.mjs.map +1 -1
  167. package/dist/server/services/schema-mutation.js +46 -0
  168. package/dist/server/services/schema-mutation.js.map +1 -0
  169. package/dist/server/services/schema-mutation.mjs +43 -0
  170. package/dist/server/services/schema-mutation.mjs.map +1 -0
  171. package/dist/server/services/schema.js +134 -79
  172. package/dist/server/services/schema.js.map +1 -1
  173. package/dist/server/services/schema.mjs +135 -80
  174. package/dist/server/services/schema.mjs.map +1 -1
  175. package/dist/server/src/controllers/schema.d.ts.map +1 -1
  176. package/dist/server/src/controllers/validation/common.d.ts +1 -0
  177. package/dist/server/src/controllers/validation/common.d.ts.map +1 -1
  178. package/dist/server/src/controllers/validation/content-structure.d.ts +56 -0
  179. package/dist/server/src/controllers/validation/content-structure.d.ts.map +1 -0
  180. package/dist/server/src/controllers/validation/schema.d.ts +35 -0
  181. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  182. package/dist/server/src/index.d.ts +3 -0
  183. package/dist/server/src/index.d.ts.map +1 -1
  184. package/dist/server/src/routes/content-api.d.ts.map +1 -1
  185. package/dist/server/src/services/api-handler.d.ts +13 -1
  186. package/dist/server/src/services/api-handler.d.ts.map +1 -1
  187. package/dist/server/src/services/content-structure.d.ts +37 -0
  188. package/dist/server/src/services/content-structure.d.ts.map +1 -0
  189. package/dist/server/src/services/content-types.d.ts +4 -0
  190. package/dist/server/src/services/content-types.d.ts.map +1 -1
  191. package/dist/server/src/services/index.d.ts +4 -0
  192. package/dist/server/src/services/index.d.ts.map +1 -1
  193. package/dist/server/src/services/schema-builder/index.d.ts +3 -1
  194. package/dist/server/src/services/schema-builder/index.d.ts.map +1 -1
  195. package/dist/server/src/services/schema-builder/schema-handler.d.ts.map +1 -1
  196. package/dist/server/src/services/schema-mutation.d.ts +26 -0
  197. package/dist/server/src/services/schema-mutation.d.ts.map +1 -0
  198. package/dist/server/src/services/schema.d.ts +1 -0
  199. package/dist/server/src/services/schema.d.ts.map +1 -1
  200. package/dist/server/src/utils/index.d.ts +2 -0
  201. package/dist/server/src/utils/index.d.ts.map +1 -1
  202. package/dist/server/utils/index.js.map +1 -1
  203. package/dist/server/utils/index.mjs.map +1 -1
  204. package/package.json +8 -8
  205. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js +0 -157
  206. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js.map +0 -1
  207. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs +0 -151
  208. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs.map +0 -1
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var designSystem = require('@strapi/design-system');
6
+ var Icons = require('@strapi/icons');
7
+ var reactIntl = require('react-intl');
8
+ var styledComponents = require('styled-components');
9
+ var getTrad = require('../../../../utils/getTrad.js');
10
+
11
+ const Row = styledComponents.styled(designSystem.Flex)`
12
+ padding-right: ${({ theme })=>theme.spaces[3]};
13
+
14
+ padding-block: ${({ theme })=>theme.spaces[1]};
15
+
16
+ padding-left: ${({ theme, $depth })=>`calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]})`};
17
+
18
+ gap: ${({ theme })=>theme.spaces[2]};
19
+ `;
20
+ const NameInput = styledComponents.styled.input`
21
+ flex: 1;
22
+
23
+ min-width: 0;
24
+ padding: 4px 8px;
25
+
26
+ background: ${({ theme })=>theme.colors.neutral0};
27
+ border: 1px solid
28
+ ${({ $hasError, theme })=>$hasError ? theme.colors.danger600 : theme.colors.primary600};
29
+ border-radius: ${({ theme })=>theme.borderRadius};
30
+
31
+ font-weight: ${({ theme })=>theme.fontWeights.semiBold};
32
+ color: ${({ theme })=>theme.colors.neutral800};
33
+ font-size: ${({ theme })=>theme.fontSizes[1]};
34
+
35
+ &:focus {
36
+ outline: none;
37
+ }
38
+ `;
39
+ const ErrorBox = styledComponents.styled(designSystem.Box)`
40
+ padding-left: ${({ theme, $depth })=>`calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]} + ${theme.spaces[4]} + ${theme.spaces[2]})`};
41
+ `;
42
+ const FolderNameField = ({ defaultValue, onSubmit, onCancel, validate, depth })=>{
43
+ const { formatMessage } = reactIntl.useIntl();
44
+ const errorId = React.useId();
45
+ const [error, setError] = React.useState(undefined);
46
+ const [value, setValue] = React.useState(defaultValue);
47
+ const inputRef = React.useRef(null);
48
+ const settledRef = React.useRef(false); // Guards against Enter and the subsequent blur both firing.
49
+ React.useEffect(()=>{
50
+ inputRef.current?.select();
51
+ inputRef.current?.focus();
52
+ }, []);
53
+ const handleChange = (next)=>{
54
+ setValue(next);
55
+ const trimmed = next.trim();
56
+ setError(trimmed.length > 0 ? validate?.(trimmed) : undefined);
57
+ };
58
+ const commitFromEnter = ()=>{
59
+ if (settledRef.current) {
60
+ return;
61
+ }
62
+ const trimmed = value.trim();
63
+ if (trimmed.length === 0) {
64
+ settledRef.current = true;
65
+ onCancel();
66
+ return;
67
+ }
68
+ const validationError = validate?.(trimmed);
69
+ if (validationError) {
70
+ setError(validationError);
71
+ inputRef.current?.focus();
72
+ return;
73
+ }
74
+ settledRef.current = true;
75
+ onSubmit(trimmed);
76
+ };
77
+ const commitFromBlur = ()=>{
78
+ if (settledRef.current) {
79
+ return;
80
+ }
81
+ settledRef.current = true;
82
+ const trimmed = value.trim();
83
+ // On blur, an empty or invalid name cancels the edit rather than trapping focus.
84
+ if (trimmed.length === 0 || validate?.(trimmed)) {
85
+ onCancel();
86
+ return;
87
+ }
88
+ onSubmit(trimmed);
89
+ };
90
+ const cancel = ()=>{
91
+ if (settledRef.current) {
92
+ return;
93
+ }
94
+ settledRef.current = true;
95
+ onCancel();
96
+ };
97
+ const onNameInputChange = (event)=>{
98
+ handleChange(event.target.value);
99
+ };
100
+ const onNameInputKeyDown = (event)=>{
101
+ if (event.key === 'Enter') {
102
+ event.preventDefault();
103
+ commitFromEnter();
104
+ }
105
+ if (event.key === 'Escape') {
106
+ event.preventDefault();
107
+ cancel();
108
+ }
109
+ };
110
+ return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
111
+ children: [
112
+ /*#__PURE__*/ jsxRuntime.jsxs(Row, {
113
+ $depth: depth,
114
+ alignItems: "center",
115
+ children: [
116
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
117
+ tag: "span",
118
+ width: "16px",
119
+ flex: "0 0 auto",
120
+ "aria-hidden": true,
121
+ children: /*#__PURE__*/ jsxRuntime.jsx(Icons.ChevronDown, {
122
+ fill: "neutral500",
123
+ style: {
124
+ transform: 'rotate(-90deg)'
125
+ }
126
+ })
127
+ }),
128
+ /*#__PURE__*/ jsxRuntime.jsx(NameInput, {
129
+ ref: inputRef,
130
+ value: value,
131
+ "aria-describedby": error ? errorId : undefined,
132
+ "aria-invalid": Boolean(error),
133
+ "aria-label": formatMessage({
134
+ id: getTrad.getTrad('nav.folder.name-label'),
135
+ defaultMessage: 'Folder name'
136
+ }),
137
+ onKeyDown: onNameInputKeyDown,
138
+ onChange: onNameInputChange,
139
+ onBlur: commitFromBlur,
140
+ $hasError: Boolean(error)
141
+ })
142
+ ]
143
+ }),
144
+ error && /*#__PURE__*/ jsxRuntime.jsx(ErrorBox, {
145
+ $depth: depth,
146
+ paddingTop: 1,
147
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
148
+ id: errorId,
149
+ variant: "pi",
150
+ textColor: "danger600",
151
+ children: error
152
+ })
153
+ })
154
+ ]
155
+ });
156
+ };
157
+
158
+ exports.FolderNameField = FolderNameField;
159
+ //# sourceMappingURL=FolderNameField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FolderNameField.js","sources":["../../../../../../admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.tsx"],"sourcesContent":["import { useEffect, useId, useRef, useState } from 'react';\n\nimport { Box, Flex, Typography } from '@strapi/design-system';\nimport { ChevronDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTrad } from '../../../../utils/getTrad';\n\nconst Row = styled(Flex)<{ $depth: number }>`\n padding-right: ${({ theme }) => theme.spaces[3]};\n\n padding-block: ${({ theme }) => theme.spaces[1]};\n\n padding-left: ${({ theme, $depth }) =>\n `calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]})`};\n\n gap: ${({ theme }) => theme.spaces[2]};\n`;\n\nconst NameInput = styled.input<{ $hasError: boolean }>`\n flex: 1;\n\n min-width: 0;\n padding: 4px 8px;\n\n background: ${({ theme }) => theme.colors.neutral0};\n border: 1px solid\n ${({ $hasError, theme }) => ($hasError ? theme.colors.danger600 : theme.colors.primary600)};\n border-radius: ${({ theme }) => theme.borderRadius};\n\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n color: ${({ theme }) => theme.colors.neutral800};\n font-size: ${({ theme }) => theme.fontSizes[1]};\n\n &:focus {\n outline: none;\n }\n`;\n\nconst ErrorBox = styled(Box)<{ $depth: number }>`\n padding-left: ${({ theme, $depth }) =>\n `calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]} + ${theme.spaces[4]} + ${theme.spaces[2]})`};\n`;\n\ninterface FolderNameFieldProps {\n defaultValue: string;\n depth: number;\n\n /**\n * Function to validate a draft entry. Return an error message to block acceptance, or `undefined` if the draft is acceptable.\n */\n validate?: (name: string) => string | undefined;\n\n onSubmit: (name: string) => void;\n onCancel: () => void;\n}\n\nexport const FolderNameField = ({\n defaultValue,\n onSubmit,\n onCancel,\n validate,\n depth,\n}: FolderNameFieldProps) => {\n const { formatMessage } = useIntl();\n const errorId = useId();\n\n const [error, setError] = useState<string | undefined>(undefined);\n const [value, setValue] = useState(defaultValue);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const settledRef = useRef(false); // Guards against Enter and the subsequent blur both firing.\n\n useEffect(() => {\n inputRef.current?.select();\n inputRef.current?.focus();\n }, []);\n\n const handleChange = (next: string) => {\n setValue(next);\n\n const trimmed = next.trim();\n setError(trimmed.length > 0 ? validate?.(trimmed) : undefined);\n };\n\n const commitFromEnter = () => {\n if (settledRef.current) {\n return;\n }\n\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n settledRef.current = true;\n\n onCancel();\n return;\n }\n\n const validationError = validate?.(trimmed);\n\n if (validationError) {\n setError(validationError);\n inputRef.current?.focus();\n\n return;\n }\n\n settledRef.current = true;\n onSubmit(trimmed);\n };\n\n const commitFromBlur = () => {\n if (settledRef.current) {\n return;\n }\n\n settledRef.current = true;\n const trimmed = value.trim();\n\n // On blur, an empty or invalid name cancels the edit rather than trapping focus.\n if (trimmed.length === 0 || validate?.(trimmed)) {\n onCancel();\n return;\n }\n\n onSubmit(trimmed);\n };\n\n const cancel = () => {\n if (settledRef.current) {\n return;\n }\n\n settledRef.current = true;\n onCancel();\n };\n\n const onNameInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(event.target.value);\n };\n\n const onNameInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commitFromEnter();\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n cancel();\n }\n };\n\n return (\n <Box>\n <Row $depth={depth} alignItems=\"center\">\n <Box tag=\"span\" width=\"16px\" flex=\"0 0 auto\" aria-hidden>\n <ChevronDown fill=\"neutral500\" style={{ transform: 'rotate(-90deg)' }} />\n </Box>\n <NameInput\n ref={inputRef}\n value={value}\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={formatMessage({\n id: getTrad('nav.folder.name-label'),\n defaultMessage: 'Folder name',\n })}\n onKeyDown={onNameInputKeyDown}\n onChange={onNameInputChange}\n onBlur={commitFromBlur}\n $hasError={Boolean(error)}\n />\n </Row>\n {error && (\n <ErrorBox $depth={depth} paddingTop={1}>\n <Typography id={errorId} variant=\"pi\" textColor=\"danger600\">\n {error}\n </Typography>\n </ErrorBox>\n )}\n </Box>\n );\n};\n"],"names":["Row","styled","Flex","theme","spaces","$depth","NameInput","input","colors","neutral0","$hasError","danger600","primary600","borderRadius","fontWeights","semiBold","neutral800","fontSizes","ErrorBox","Box","FolderNameField","defaultValue","onSubmit","onCancel","validate","depth","formatMessage","useIntl","errorId","useId","error","setError","useState","undefined","value","setValue","inputRef","useRef","settledRef","useEffect","current","select","focus","handleChange","next","trimmed","trim","length","commitFromEnter","validationError","commitFromBlur","cancel","onNameInputChange","event","target","onNameInputKeyDown","key","preventDefault","_jsxs","alignItems","_jsx","tag","width","flex","aria-hidden","ChevronDown","fill","style","transform","ref","aria-describedby","aria-invalid","Boolean","aria-label","id","getTrad","defaultMessage","onKeyDown","onChange","onBlur","paddingTop","Typography","variant","textColor"],"mappings":";;;;;;;;;;AASA,MAAMA,GAAAA,GAAMC,uBAAAA,CAAOC,iBAAAA,CAAyB;iBAC3B,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;iBAEjC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;gBAElC,EAAE,CAAC,EAAED,KAAK,EAAEE,MAAM,EAAE,GAChC,CAAC,KAAK,EAAEA,MAAAA,CAAO,GAAG,EAAEF,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,GAAG,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,CAAC,CAAC;;OAEzD,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AACxC,CAAC;AAED,MAAME,SAAAA,GAAYL,uBAAAA,CAAOM,KAA6B;;;;;;cAMxC,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMK,MAAM,CAACC,QAAQ,CAAC;;AAEjD,IAAA,EAAE,CAAC,EAAEC,SAAS,EAAEP,KAAK,EAAE,GAAMO,SAAAA,GAAYP,KAAAA,CAAMK,MAAM,CAACG,SAAS,GAAGR,MAAMK,MAAM,CAACI,UAAU,CAAE;AAC9E,iBAAA,EAAE,CAAC,EAAET,KAAK,EAAE,GAAKA,KAAAA,CAAMU,YAAY,CAAC;;eAEtC,EAAE,CAAC,EAAEV,KAAK,EAAE,GAAKA,KAAAA,CAAMW,WAAW,CAACC,QAAQ,CAAC;SAClD,EAAE,CAAC,EAAEZ,KAAK,EAAE,GAAKA,KAAAA,CAAMK,MAAM,CAACQ,UAAU,CAAC;aACrC,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAAA,CAAMc,SAAS,CAAC,CAAA,CAAE,CAAC;;;;;AAKjD,CAAC;AAED,MAAMC,QAAAA,GAAWjB,uBAAAA,CAAOkB,gBAAAA,CAAwB;AAChC,gBAAA,EAAE,CAAC,EAAEhB,KAAK,EAAEE,MAAM,EAAE,GAChC,CAAC,KAAK,EAAEA,MAAAA,CAAO,GAAG,EAAEF,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,GAAG,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,GAAG,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,GAAG,EAAED,MAAMC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1G,CAAC;AAeM,MAAMgB,eAAAA,GAAkB,CAAC,EAC9BC,YAAY,EACZC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACgB,GAAA;IACrB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,OAAAA,GAAUC,WAAAA,EAAAA;AAEhB,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGC,cAAAA,CAA6BC,SAAAA,CAAAA;AACvD,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGH,cAAAA,CAASX,YAAAA,CAAAA;AAEnC,IAAA,MAAMe,WAAWC,YAAAA,CAAyB,IAAA,CAAA;IAC1C,MAAMC,UAAAA,GAAaD,YAAAA,CAAO,KAAA,CAAA,CAAA;IAE1BE,eAAAA,CAAU,IAAA;AACRH,QAAAA,QAAAA,CAASI,OAAO,EAAEC,MAAAA,EAAAA;AAClBL,QAAAA,QAAAA,CAASI,OAAO,EAAEE,KAAAA,EAAAA;AACpB,IAAA,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAMC,eAAe,CAACC,IAAAA,GAAAA;QACpBT,QAAAA,CAASS,IAAAA,CAAAA;QAET,MAAMC,OAAAA,GAAUD,KAAKE,IAAI,EAAA;AACzBf,QAAAA,QAAAA,CAASc,OAAAA,CAAQE,MAAM,GAAG,CAAA,GAAIvB,WAAWqB,OAAAA,CAAAA,GAAWZ,SAAAA,CAAAA;AACtD,IAAA,CAAA;AAEA,IAAA,MAAMe,eAAAA,GAAkB,IAAA;QACtB,IAAIV,UAAAA,CAAWE,OAAO,EAAE;AACtB,YAAA;AACF,QAAA;QAEA,MAAMK,OAAAA,GAAUX,MAAMY,IAAI,EAAA;QAE1B,IAAID,OAAAA,CAAQE,MAAM,KAAK,CAAA,EAAG;AACxBT,YAAAA,UAAAA,CAAWE,OAAO,GAAG,IAAA;AAErBjB,YAAAA,QAAAA,EAAAA;AACA,YAAA;AACF,QAAA;AAEA,QAAA,MAAM0B,kBAAkBzB,QAAAA,GAAWqB,OAAAA,CAAAA;AAEnC,QAAA,IAAII,eAAAA,EAAiB;YACnBlB,QAAAA,CAASkB,eAAAA,CAAAA;AACTb,YAAAA,QAAAA,CAASI,OAAO,EAAEE,KAAAA,EAAAA;AAElB,YAAA;AACF,QAAA;AAEAJ,QAAAA,UAAAA,CAAWE,OAAO,GAAG,IAAA;QACrBlB,QAAAA,CAASuB,OAAAA,CAAAA;AACX,IAAA,CAAA;AAEA,IAAA,MAAMK,cAAAA,GAAiB,IAAA;QACrB,IAAIZ,UAAAA,CAAWE,OAAO,EAAE;AACtB,YAAA;AACF,QAAA;AAEAF,QAAAA,UAAAA,CAAWE,OAAO,GAAG,IAAA;QACrB,MAAMK,OAAAA,GAAUX,MAAMY,IAAI,EAAA;;AAG1B,QAAA,IAAID,OAAAA,CAAQE,MAAM,KAAK,CAAA,IAAKvB,WAAWqB,OAAAA,CAAAA,EAAU;AAC/CtB,YAAAA,QAAAA,EAAAA;AACA,YAAA;AACF,QAAA;QAEAD,QAAAA,CAASuB,OAAAA,CAAAA;AACX,IAAA,CAAA;AAEA,IAAA,MAAMM,MAAAA,GAAS,IAAA;QACb,IAAIb,UAAAA,CAAWE,OAAO,EAAE;AACtB,YAAA;AACF,QAAA;AAEAF,QAAAA,UAAAA,CAAWE,OAAO,GAAG,IAAA;AACrBjB,QAAAA,QAAAA,EAAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM6B,oBAAoB,CAACC,KAAAA,GAAAA;QACzBV,YAAAA,CAAaU,KAAAA,CAAMC,MAAM,CAACpB,KAAK,CAAA;AACjC,IAAA,CAAA;AAEA,IAAA,MAAMqB,qBAAqB,CAACF,KAAAA,GAAAA;QAC1B,IAAIA,KAAAA,CAAMG,GAAG,KAAK,OAAA,EAAS;AACzBH,YAAAA,KAAAA,CAAMI,cAAc,EAAA;AACpBT,YAAAA,eAAAA,EAAAA;AACF,QAAA;QAEA,IAAIK,KAAAA,CAAMG,GAAG,KAAK,QAAA,EAAU;AAC1BH,YAAAA,KAAAA,CAAMI,cAAc,EAAA;AACpBN,YAAAA,MAAAA,EAAAA;AACF,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACEO,eAAA,CAACvC,gBAAAA,EAAAA;;0BACCuC,eAAA,CAAC1D,GAAAA,EAAAA;gBAAIK,MAAAA,EAAQoB,KAAAA;gBAAOkC,UAAAA,EAAW,QAAA;;kCAC7BC,cAAA,CAACzC,gBAAAA,EAAAA;wBAAI0C,GAAAA,EAAI,MAAA;wBAAOC,KAAAA,EAAM,MAAA;wBAAOC,IAAAA,EAAK,UAAA;wBAAWC,aAAW,EAAA,IAAA;AACtD,wBAAA,QAAA,gBAAAJ,cAAA,CAACK,iBAAAA,EAAAA;4BAAYC,IAAAA,EAAK,YAAA;4BAAaC,KAAAA,EAAO;gCAAEC,SAAAA,EAAW;AAAiB;;;kCAEtER,cAAA,CAACtD,SAAAA,EAAAA;wBACC+D,GAAAA,EAAKjC,QAAAA;wBACLF,KAAAA,EAAOA,KAAAA;AACPoC,wBAAAA,kBAAAA,EAAkBxC,QAAQF,OAAAA,GAAUK,SAAAA;AACpCsC,wBAAAA,cAAAA,EAAcC,OAAAA,CAAQ1C,KAAAA,CAAAA;AACtB2C,wBAAAA,YAAAA,EAAY/C,aAAAA,CAAc;AACxBgD,4BAAAA,EAAAA,EAAIC,eAAAA,CAAQ,uBAAA,CAAA;4BACZC,cAAAA,EAAgB;AAClB,yBAAA,CAAA;wBACAC,SAAAA,EAAWtB,kBAAAA;wBACXuB,QAAAA,EAAU1B,iBAAAA;wBACV2B,MAAAA,EAAQ7B,cAAAA;AACRxC,wBAAAA,SAAAA,EAAW8D,OAAAA,CAAQ1C,KAAAA;;;;AAGtBA,YAAAA,KAAAA,kBACC8B,cAAA,CAAC1C,QAAAA,EAAAA;gBAASb,MAAAA,EAAQoB,KAAAA;gBAAOuD,UAAAA,EAAY,CAAA;AACnC,gBAAA,QAAA,gBAAApB,cAAA,CAACqB,uBAAAA,EAAAA;oBAAWP,EAAAA,EAAI9C,OAAAA;oBAASsD,OAAAA,EAAQ,IAAA;oBAAKC,SAAAA,EAAU,WAAA;AAC7CrD,oBAAAA,QAAAA,EAAAA;;;;;AAMb;;;;"}
@@ -0,0 +1,157 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useId, useState, useRef, useEffect } from 'react';
3
+ import { Box, Typography, Flex } from '@strapi/design-system';
4
+ import { ChevronDown } from '@strapi/icons';
5
+ import { useIntl } from 'react-intl';
6
+ import { styled } from 'styled-components';
7
+ import { getTrad } from '../../../../utils/getTrad.mjs';
8
+
9
+ const Row = styled(Flex)`
10
+ padding-right: ${({ theme })=>theme.spaces[3]};
11
+
12
+ padding-block: ${({ theme })=>theme.spaces[1]};
13
+
14
+ padding-left: ${({ theme, $depth })=>`calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]})`};
15
+
16
+ gap: ${({ theme })=>theme.spaces[2]};
17
+ `;
18
+ const NameInput = styled.input`
19
+ flex: 1;
20
+
21
+ min-width: 0;
22
+ padding: 4px 8px;
23
+
24
+ background: ${({ theme })=>theme.colors.neutral0};
25
+ border: 1px solid
26
+ ${({ $hasError, theme })=>$hasError ? theme.colors.danger600 : theme.colors.primary600};
27
+ border-radius: ${({ theme })=>theme.borderRadius};
28
+
29
+ font-weight: ${({ theme })=>theme.fontWeights.semiBold};
30
+ color: ${({ theme })=>theme.colors.neutral800};
31
+ font-size: ${({ theme })=>theme.fontSizes[1]};
32
+
33
+ &:focus {
34
+ outline: none;
35
+ }
36
+ `;
37
+ const ErrorBox = styled(Box)`
38
+ padding-left: ${({ theme, $depth })=>`calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]} + ${theme.spaces[4]} + ${theme.spaces[2]})`};
39
+ `;
40
+ const FolderNameField = ({ defaultValue, onSubmit, onCancel, validate, depth })=>{
41
+ const { formatMessage } = useIntl();
42
+ const errorId = useId();
43
+ const [error, setError] = useState(undefined);
44
+ const [value, setValue] = useState(defaultValue);
45
+ const inputRef = useRef(null);
46
+ const settledRef = useRef(false); // Guards against Enter and the subsequent blur both firing.
47
+ useEffect(()=>{
48
+ inputRef.current?.select();
49
+ inputRef.current?.focus();
50
+ }, []);
51
+ const handleChange = (next)=>{
52
+ setValue(next);
53
+ const trimmed = next.trim();
54
+ setError(trimmed.length > 0 ? validate?.(trimmed) : undefined);
55
+ };
56
+ const commitFromEnter = ()=>{
57
+ if (settledRef.current) {
58
+ return;
59
+ }
60
+ const trimmed = value.trim();
61
+ if (trimmed.length === 0) {
62
+ settledRef.current = true;
63
+ onCancel();
64
+ return;
65
+ }
66
+ const validationError = validate?.(trimmed);
67
+ if (validationError) {
68
+ setError(validationError);
69
+ inputRef.current?.focus();
70
+ return;
71
+ }
72
+ settledRef.current = true;
73
+ onSubmit(trimmed);
74
+ };
75
+ const commitFromBlur = ()=>{
76
+ if (settledRef.current) {
77
+ return;
78
+ }
79
+ settledRef.current = true;
80
+ const trimmed = value.trim();
81
+ // On blur, an empty or invalid name cancels the edit rather than trapping focus.
82
+ if (trimmed.length === 0 || validate?.(trimmed)) {
83
+ onCancel();
84
+ return;
85
+ }
86
+ onSubmit(trimmed);
87
+ };
88
+ const cancel = ()=>{
89
+ if (settledRef.current) {
90
+ return;
91
+ }
92
+ settledRef.current = true;
93
+ onCancel();
94
+ };
95
+ const onNameInputChange = (event)=>{
96
+ handleChange(event.target.value);
97
+ };
98
+ const onNameInputKeyDown = (event)=>{
99
+ if (event.key === 'Enter') {
100
+ event.preventDefault();
101
+ commitFromEnter();
102
+ }
103
+ if (event.key === 'Escape') {
104
+ event.preventDefault();
105
+ cancel();
106
+ }
107
+ };
108
+ return /*#__PURE__*/ jsxs(Box, {
109
+ children: [
110
+ /*#__PURE__*/ jsxs(Row, {
111
+ $depth: depth,
112
+ alignItems: "center",
113
+ children: [
114
+ /*#__PURE__*/ jsx(Box, {
115
+ tag: "span",
116
+ width: "16px",
117
+ flex: "0 0 auto",
118
+ "aria-hidden": true,
119
+ children: /*#__PURE__*/ jsx(ChevronDown, {
120
+ fill: "neutral500",
121
+ style: {
122
+ transform: 'rotate(-90deg)'
123
+ }
124
+ })
125
+ }),
126
+ /*#__PURE__*/ jsx(NameInput, {
127
+ ref: inputRef,
128
+ value: value,
129
+ "aria-describedby": error ? errorId : undefined,
130
+ "aria-invalid": Boolean(error),
131
+ "aria-label": formatMessage({
132
+ id: getTrad('nav.folder.name-label'),
133
+ defaultMessage: 'Folder name'
134
+ }),
135
+ onKeyDown: onNameInputKeyDown,
136
+ onChange: onNameInputChange,
137
+ onBlur: commitFromBlur,
138
+ $hasError: Boolean(error)
139
+ })
140
+ ]
141
+ }),
142
+ error && /*#__PURE__*/ jsx(ErrorBox, {
143
+ $depth: depth,
144
+ paddingTop: 1,
145
+ children: /*#__PURE__*/ jsx(Typography, {
146
+ id: errorId,
147
+ variant: "pi",
148
+ textColor: "danger600",
149
+ children: error
150
+ })
151
+ })
152
+ ]
153
+ });
154
+ };
155
+
156
+ export { FolderNameField };
157
+ //# sourceMappingURL=FolderNameField.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FolderNameField.mjs","sources":["../../../../../../admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.tsx"],"sourcesContent":["import { useEffect, useId, useRef, useState } from 'react';\n\nimport { Box, Flex, Typography } from '@strapi/design-system';\nimport { ChevronDown } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTrad } from '../../../../utils/getTrad';\n\nconst Row = styled(Flex)<{ $depth: number }>`\n padding-right: ${({ theme }) => theme.spaces[3]};\n\n padding-block: ${({ theme }) => theme.spaces[1]};\n\n padding-left: ${({ theme, $depth }) =>\n `calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]})`};\n\n gap: ${({ theme }) => theme.spaces[2]};\n`;\n\nconst NameInput = styled.input<{ $hasError: boolean }>`\n flex: 1;\n\n min-width: 0;\n padding: 4px 8px;\n\n background: ${({ theme }) => theme.colors.neutral0};\n border: 1px solid\n ${({ $hasError, theme }) => ($hasError ? theme.colors.danger600 : theme.colors.primary600)};\n border-radius: ${({ theme }) => theme.borderRadius};\n\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n color: ${({ theme }) => theme.colors.neutral800};\n font-size: ${({ theme }) => theme.fontSizes[1]};\n\n &:focus {\n outline: none;\n }\n`;\n\nconst ErrorBox = styled(Box)<{ $depth: number }>`\n padding-left: ${({ theme, $depth }) =>\n `calc(${$depth} * ${theme.spaces[6]} + ${theme.spaces[3]} + ${theme.spaces[4]} + ${theme.spaces[2]})`};\n`;\n\ninterface FolderNameFieldProps {\n defaultValue: string;\n depth: number;\n\n /**\n * Function to validate a draft entry. Return an error message to block acceptance, or `undefined` if the draft is acceptable.\n */\n validate?: (name: string) => string | undefined;\n\n onSubmit: (name: string) => void;\n onCancel: () => void;\n}\n\nexport const FolderNameField = ({\n defaultValue,\n onSubmit,\n onCancel,\n validate,\n depth,\n}: FolderNameFieldProps) => {\n const { formatMessage } = useIntl();\n const errorId = useId();\n\n const [error, setError] = useState<string | undefined>(undefined);\n const [value, setValue] = useState(defaultValue);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const settledRef = useRef(false); // Guards against Enter and the subsequent blur both firing.\n\n useEffect(() => {\n inputRef.current?.select();\n inputRef.current?.focus();\n }, []);\n\n const handleChange = (next: string) => {\n setValue(next);\n\n const trimmed = next.trim();\n setError(trimmed.length > 0 ? validate?.(trimmed) : undefined);\n };\n\n const commitFromEnter = () => {\n if (settledRef.current) {\n return;\n }\n\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n settledRef.current = true;\n\n onCancel();\n return;\n }\n\n const validationError = validate?.(trimmed);\n\n if (validationError) {\n setError(validationError);\n inputRef.current?.focus();\n\n return;\n }\n\n settledRef.current = true;\n onSubmit(trimmed);\n };\n\n const commitFromBlur = () => {\n if (settledRef.current) {\n return;\n }\n\n settledRef.current = true;\n const trimmed = value.trim();\n\n // On blur, an empty or invalid name cancels the edit rather than trapping focus.\n if (trimmed.length === 0 || validate?.(trimmed)) {\n onCancel();\n return;\n }\n\n onSubmit(trimmed);\n };\n\n const cancel = () => {\n if (settledRef.current) {\n return;\n }\n\n settledRef.current = true;\n onCancel();\n };\n\n const onNameInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(event.target.value);\n };\n\n const onNameInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commitFromEnter();\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n cancel();\n }\n };\n\n return (\n <Box>\n <Row $depth={depth} alignItems=\"center\">\n <Box tag=\"span\" width=\"16px\" flex=\"0 0 auto\" aria-hidden>\n <ChevronDown fill=\"neutral500\" style={{ transform: 'rotate(-90deg)' }} />\n </Box>\n <NameInput\n ref={inputRef}\n value={value}\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={formatMessage({\n id: getTrad('nav.folder.name-label'),\n defaultMessage: 'Folder name',\n })}\n onKeyDown={onNameInputKeyDown}\n onChange={onNameInputChange}\n onBlur={commitFromBlur}\n $hasError={Boolean(error)}\n />\n </Row>\n {error && (\n <ErrorBox $depth={depth} paddingTop={1}>\n <Typography id={errorId} variant=\"pi\" textColor=\"danger600\">\n {error}\n </Typography>\n </ErrorBox>\n )}\n </Box>\n );\n};\n"],"names":["Row","styled","Flex","theme","spaces","$depth","NameInput","input","colors","neutral0","$hasError","danger600","primary600","borderRadius","fontWeights","semiBold","neutral800","fontSizes","ErrorBox","Box","FolderNameField","defaultValue","onSubmit","onCancel","validate","depth","formatMessage","useIntl","errorId","useId","error","setError","useState","undefined","value","setValue","inputRef","useRef","settledRef","useEffect","current","select","focus","handleChange","next","trimmed","trim","length","commitFromEnter","validationError","commitFromBlur","cancel","onNameInputChange","event","target","onNameInputKeyDown","key","preventDefault","_jsxs","alignItems","_jsx","tag","width","flex","aria-hidden","ChevronDown","fill","style","transform","ref","aria-describedby","aria-invalid","Boolean","aria-label","id","getTrad","defaultMessage","onKeyDown","onChange","onBlur","paddingTop","Typography","variant","textColor"],"mappings":"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"}
@@ -0,0 +1,311 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var core = require('@dnd-kit/core');
6
+ var sortable = require('@dnd-kit/sortable');
7
+ var strapiAdmin = require('@strapi/admin/strapi-admin');
8
+ var designSystem = require('@strapi/design-system');
9
+ var Icons = require('@strapi/icons');
10
+ var reactIntl = require('react-intl');
11
+ var getTrad = require('../../../../utils/getTrad.js');
12
+ var useDataManager = require('../../../DataManager/useDataManager.js');
13
+ var contentStructure = require('../../../DataManager/utils/contentStructure.js');
14
+ var useFolderActions = require('../../hooks/useFolderActions.js');
15
+ var useSortableTree = require('../../hooks/useSortableTree.js');
16
+ var buildFolderTree = require('../../lib/buildFolderTree.js');
17
+ var flatModel = require('../../lib/flatModel.js');
18
+ var DeleteFolderDialog = require('./DeleteFolderDialog.js');
19
+ var FolderNameField = require('./FolderNameField.js');
20
+ var SortableTreeRow = require('./SortableTreeRow.js');
21
+
22
+ const countContentTypes = (nodes)=>{
23
+ return nodes.reduce((total, node)=>{
24
+ if (node.type === 'folder') {
25
+ return total + countContentTypes(node.children);
26
+ }
27
+ return total + 1;
28
+ }, 0);
29
+ };
30
+ const EMPTY_COLLAPSED = new Set(); // Empty set to uncollapse all items while searching
31
+ const FolderNavSection = ({ onCreateContentType, createTypeLabel, searchValue, sectionId, section, title, links })=>{
32
+ const { contentStructure: contentStructure$1, contentTypes, isInDevelopmentMode } = useDataManager.useDataManager();
33
+ const { formatMessage, locale } = reactIntl.useIntl();
34
+ const actions = useFolderActions.useFolderActions();
35
+ const [collapsed, setCollapsed] = React.useState(new Set());
36
+ const [editingId, setEditingId] = React.useState(null);
37
+ const [isDrafting, setIsDrafting] = React.useState(false);
38
+ const [deleteTarget, setDeleteTarget] = React.useState(null);
39
+ const { contains } = designSystem.useFilter(locale, {
40
+ sensitivity: 'base'
41
+ });
42
+ const formatter = designSystem.useCollator(locale, {
43
+ sensitivity: 'base'
44
+ });
45
+ const sectionData = contentStructure$1.sections[section];
46
+ const searchActive = searchValue.trim().length > 0;
47
+ const canEdit = Boolean(isInDevelopmentMode);
48
+ const deletableContentTypeUids = React.useMemo(()=>{
49
+ return new Set(Object.values(contentTypes).filter((contentType)=>contentType.uid.startsWith('api::') && !contentType.plugin).map((contentType)=>contentType.uid));
50
+ }, [
51
+ contentTypes
52
+ ]);
53
+ const tree = React.useMemo(()=>{
54
+ return buildFolderTree.buildSectionTree(sectionData, links, (a, b)=>formatter.compare(a, b));
55
+ }, [
56
+ sectionData,
57
+ links,
58
+ formatter
59
+ ]);
60
+ const effectiveCollapsed = searchActive ? EMPTY_COLLAPSED : collapsed;
61
+ const visibleTree = React.useMemo(()=>{
62
+ return searchActive ? buildFolderTree.filterTree(tree, (text)=>contains(text, searchValue)) : tree;
63
+ }, [
64
+ searchActive,
65
+ tree,
66
+ contains,
67
+ searchValue
68
+ ]);
69
+ const flatItems = React.useMemo(()=>{
70
+ return flatModel.flattenSortableTree(visibleTree, effectiveCollapsed);
71
+ }, [
72
+ visibleTree,
73
+ effectiveCollapsed
74
+ ]);
75
+ // This hook supplies the CTB contentStructure dnd engine.
76
+ const dnd = useSortableTree.useSortableTree({
77
+ disabled: !canEdit || searchActive,
78
+ collapsed: effectiveCollapsed,
79
+ items: flatItems,
80
+ canDrop: (activeNode, target)=>{
81
+ if (activeNode.type !== 'folder') {
82
+ return true;
83
+ }
84
+ const parentId = target.kind === 'nest' ? target.folderId : target.parentId;
85
+ if (contentStructure.isFolderNameTakenBySibling(sectionData.groups, parentId, activeNode.name, activeNode.id)) {
86
+ return false;
87
+ }
88
+ return true;
89
+ },
90
+ onDrop: (activeNode, target)=>{
91
+ const parentId = target.kind === 'nest' ? target.folderId : target.parentId;
92
+ const index = target.kind === 'nest' ? 0 : target.index;
93
+ if (activeNode.type === 'folder') {
94
+ actions.moveFolder({
95
+ newParentId: parentId,
96
+ id: activeNode.id,
97
+ section,
98
+ index
99
+ });
100
+ return;
101
+ }
102
+ actions.assignContentTypeToFolder({
103
+ targetGroupId: parentId,
104
+ uid: activeNode.uid,
105
+ section,
106
+ index
107
+ });
108
+ },
109
+ onExpandFolder: (folderId)=>setCollapsed((prev)=>{
110
+ const next = new Set(prev);
111
+ next.delete(folderId);
112
+ return next;
113
+ })
114
+ });
115
+ const confirmDelete = ()=>{
116
+ if (!deleteTarget) {
117
+ return;
118
+ }
119
+ if (deleteTarget.mode === 'withContent') {
120
+ actions.deleteFolderAndContent({
121
+ contentTypeUids: buildFolderTree.collectSubtreeContentTypeUids(sectionData, deleteTarget.node.id).filter((uid)=>deletableContentTypeUids.has(uid)),
122
+ id: deleteTarget.node.id,
123
+ section
124
+ });
125
+ } else {
126
+ if (contentStructure.getDeleteFolderOnlySiblingNameCollisions(sectionData.groups, deleteTarget.node.id).length > 0) {
127
+ return;
128
+ }
129
+ actions.deleteFolderOnly({
130
+ section,
131
+ id: deleteTarget.node.id
132
+ });
133
+ }
134
+ setDeleteTarget(null);
135
+ };
136
+ const validateFolderName = ({ excludeId, parentId, name })=>{
137
+ const folderNameTaken = contentStructure.isFolderNameTakenBySibling(sectionData.groups, parentId, name, excludeId);
138
+ if (folderNameTaken) {
139
+ return formatMessage({
140
+ defaultMessage: 'A folder with this name already exists in this location',
141
+ id: getTrad.getTrad('nav.folder.name.duplicate')
142
+ });
143
+ }
144
+ return undefined;
145
+ };
146
+ const handlers = {
147
+ dropTargetId: dnd.dropTargetId,
148
+ dropLine: dnd.dropLine,
149
+ validateFolderName,
150
+ editingId,
151
+ section,
152
+ canEdit,
153
+ isCollapsed: (id)=>{
154
+ return effectiveCollapsed.has(id);
155
+ },
156
+ // Search forces the tree open; a collapse toggle then can't take effect, so don't present one.
157
+ canToggle: !searchActive,
158
+ onToggle: (id)=>{
159
+ setCollapsed((prev)=>{
160
+ const next = new Set(prev);
161
+ if (next.has(id)) {
162
+ next.delete(id);
163
+ } else {
164
+ next.add(id);
165
+ }
166
+ return next;
167
+ });
168
+ },
169
+ // Deferred past the closing menu's focus restoration so the inline input isn't blurred (and consequently auto-committed) the instant it mounts.
170
+ onBeginRename: (id)=>{
171
+ setTimeout(()=>{
172
+ setIsDrafting(false);
173
+ setEditingId(id);
174
+ }, 0);
175
+ },
176
+ onSubmitRename: (id, name)=>{
177
+ actions.renameFolder({
178
+ section,
179
+ id,
180
+ name
181
+ });
182
+ setEditingId(null);
183
+ },
184
+ onCancelRename: ()=>{
185
+ setEditingId(null);
186
+ },
187
+ onDeleteFolder: (node)=>{
188
+ setDeleteTarget({
189
+ node,
190
+ mode: 'only'
191
+ });
192
+ },
193
+ onDeleteFolderAndContent: (node)=>{
194
+ setDeleteTarget({
195
+ node,
196
+ mode: 'withContent'
197
+ });
198
+ }
199
+ };
200
+ const sectionLink = {
201
+ label: createTypeLabel,
202
+ // The "New folder" option mounts the folder name input input and focuses it. Without this flag enabled, closing the menu would restore focus to the menu icon trigger.
203
+ suppressFocusCaptureOnMenuClose: true,
204
+ menu: [
205
+ {
206
+ label: createTypeLabel,
207
+ onSelect: onCreateContentType,
208
+ startIcon: /*#__PURE__*/ jsxRuntime.jsx(Icons.File, {})
209
+ },
210
+ {
211
+ label: formatMessage({
212
+ id: getTrad.getTrad('nav.action.new-folder'),
213
+ defaultMessage: 'New folder'
214
+ }),
215
+ onSelect: ()=>{
216
+ setEditingId(null);
217
+ setTimeout(()=>setIsDrafting(true), 0);
218
+ },
219
+ startIcon: /*#__PURE__*/ jsxRuntime.jsx(Icons.Folder, {})
220
+ }
221
+ ]
222
+ };
223
+ const rows = // No extra horizontal padding here — the rows sit directly in the section's
224
+ // list so their left edge lines up with the components SubSections.
225
+ /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
226
+ children: [
227
+ canEdit && isDrafting && /*#__PURE__*/ jsxRuntime.jsx(FolderNameField.FolderNameField, {
228
+ depth: 0,
229
+ defaultValue: formatMessage({
230
+ id: getTrad.getTrad('nav.folder.default-name'),
231
+ defaultMessage: 'New folder'
232
+ }),
233
+ validate: (name)=>{
234
+ return validateFolderName({
235
+ name,
236
+ parentId: null
237
+ });
238
+ },
239
+ onSubmit: (name)=>{
240
+ actions.createFolder({
241
+ section,
242
+ name,
243
+ parentId: null
244
+ });
245
+ setIsDrafting(false);
246
+ },
247
+ onCancel: ()=>{
248
+ setIsDrafting(false);
249
+ }
250
+ }),
251
+ /*#__PURE__*/ jsxRuntime.jsxs(core.DndContext, {
252
+ collisionDetection: dnd.collisionDetection,
253
+ onDragCancel: dnd.onDragCancel,
254
+ onDragStart: dnd.onDragStart,
255
+ onDragMove: dnd.onDragMove,
256
+ onDragEnd: dnd.onDragEnd,
257
+ sensors: dnd.sensors,
258
+ children: [
259
+ /*#__PURE__*/ jsxRuntime.jsx(sortable.SortableContext, {
260
+ items: dnd.renderedItems.map((item)=>item.id),
261
+ strategy: dnd.sortingStrategy,
262
+ children: dnd.renderedItems.map((item)=>{
263
+ return /*#__PURE__*/ jsxRuntime.jsx(SortableTreeRow.SortableTreeRow, {
264
+ item: item,
265
+ handlers: handlers
266
+ }, item.id);
267
+ })
268
+ }),
269
+ /*#__PURE__*/ jsxRuntime.jsx(core.DragOverlay, {
270
+ dropAnimation: null,
271
+ children: dnd.activeItem ? /*#__PURE__*/ jsxRuntime.jsx(SortableTreeRow.RowOverlay, {
272
+ item: dnd.activeItem
273
+ }) : null
274
+ })
275
+ ]
276
+ })
277
+ ]
278
+ }, "section-rows");
279
+ return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
280
+ children: [
281
+ /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Section, {
282
+ badgeLabel: countContentTypes(visibleTree).toString(),
283
+ link: canEdit ? sectionLink : undefined,
284
+ sectionId: sectionId,
285
+ label: title,
286
+ children: [
287
+ rows
288
+ ]
289
+ }),
290
+ deleteTarget && /*#__PURE__*/ jsxRuntime.jsx(DeleteFolderDialog.DeleteFolderDialog, {
291
+ counts: {
292
+ ...buildFolderTree.countSubtree(sectionData, deleteTarget.node.id, deletableContentTypeUids),
293
+ preservedContentTypes: buildFolderTree.collectSubtreeContentTypeUids(sectionData, deleteTarget.node.id).filter((uid)=>!deletableContentTypeUids.has(uid)).length
294
+ },
295
+ conflictingFolderNames: deleteTarget.mode === 'only' ? contentStructure.getDeleteFolderOnlySiblingNameCollisions(sectionData.groups, deleteTarget.node.id) : [],
296
+ folderName: deleteTarget.node.name,
297
+ onConfirm: confirmDelete,
298
+ mode: deleteTarget.mode,
299
+ open: true,
300
+ onOpenChange: (open)=>{
301
+ if (!open) {
302
+ setDeleteTarget(null);
303
+ }
304
+ }
305
+ })
306
+ ]
307
+ });
308
+ };
309
+
310
+ exports.FolderNavSection = FolderNavSection;
311
+ //# sourceMappingURL=FolderNavSection.js.map