@strapi/content-manager 5.15.0 → 5.15.1

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.
@@ -2,16 +2,17 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
+ var core = require('@dnd-kit/core');
6
+ var sortable = require('@dnd-kit/sortable');
7
+ var utilities = require('@dnd-kit/utilities');
5
8
  var strapiAdmin = require('@strapi/admin/strapi-admin');
6
9
  var designSystem = require('@strapi/design-system');
7
10
  var Icons = require('@strapi/icons');
8
11
  var fractionalIndexing = require('fractional-indexing');
9
- var reactDndHtml5Backend = require('react-dnd-html5-backend');
12
+ var immer = require('immer');
10
13
  var reactIntl = require('react-intl');
11
14
  var reactRouterDom = require('react-router-dom');
12
15
  var styledComponents = require('styled-components');
13
- var dragAndDrop = require('../../constants/dragAndDrop.js');
14
- var useDragAndDrop = require('../../hooks/useDragAndDrop.js');
15
16
  var translations = require('../../utils/translations.js');
16
17
  var ComponentIcon = require('../ComponentIcon.js');
17
18
  var EditFieldForm = require('./EditFieldForm.js');
@@ -35,6 +36,46 @@ function _interopNamespaceDefault(e) {
35
36
 
36
37
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
37
38
 
39
+ const GRID_COLUMNS = 12;
40
+ /* -------------------------------------------------------------------------------------------------
41
+ * Drag and Drop
42
+ * -----------------------------------------------------------------------------------------------*/ const DroppableContainer = ({ id, children })=>{
43
+ const droppable = core.useDroppable({
44
+ id
45
+ });
46
+ return children(droppable);
47
+ };
48
+ const SortableItem = ({ id, children })=>{
49
+ const { attributes, setNodeRef, transform, transition } = sortable.useSortable({
50
+ id
51
+ });
52
+ const style = {
53
+ transform: utilities.CSS.Transform.toString(transform),
54
+ transition,
55
+ height: '100%'
56
+ };
57
+ return /*#__PURE__*/ jsxRuntime.jsx("div", {
58
+ ref: setNodeRef,
59
+ style: style,
60
+ ...attributes,
61
+ children: children
62
+ });
63
+ };
64
+ /**
65
+ * Compute uids and formName for drag and drop items for the incoming layout
66
+ */ const createDragAndDropContainersFromLayout = (layout)=>{
67
+ return layout.map((row, containerIndex)=>({
68
+ ...row,
69
+ // Use unique ids for drag and drop items
70
+ dndId: `container-${containerIndex}`,
71
+ children: row.children.map((child, childIndex)=>({
72
+ ...child,
73
+ dndId: `container-${containerIndex}-child-${childIndex}`,
74
+ // The formName must be recomputed each time an item is moved
75
+ formName: `layout.${containerIndex}.children.${childIndex}`
76
+ }))
77
+ }));
78
+ };
38
79
  const Fields = ({ attributes, fieldSizes, components, metadatas = {} })=>{
39
80
  const { formatMessage } = reactIntl.useIntl();
40
81
  const layout = strapiAdmin.useForm('Fields', (state)=>state.values.layout ?? []);
@@ -50,7 +91,7 @@ const Fields = ({ attributes, fieldSizes, components, metadatas = {} })=>{
50
91
  const [name, { visible, ...field }] = current;
51
92
  if (!existingFields.includes(name) && visible === true) {
52
93
  const type = attributes[name]?.type;
53
- const size = type ? fieldSizes[type] : 12;
94
+ const size = type ? fieldSizes[type] : GRID_COLUMNS;
54
95
  acc.push({
55
96
  ...field,
56
97
  label: field.label ?? name,
@@ -60,53 +101,57 @@ const Fields = ({ attributes, fieldSizes, components, metadatas = {} })=>{
60
101
  }
61
102
  return acc;
62
103
  }, []);
63
- const handleMoveField = ([newRowIndex, newFieldIndex], [currentRowIndex, currentFieldIndex])=>{
64
- /**
65
- * Because this view has the constraint that the sum of field sizes cannot be greater
66
- * than 12, we don't use the form's method to move field rows, instead, we calculate
67
- * the new layout and set the entire form.
68
- */ const newLayout = structuredClone(layout);
69
- /**
70
- * Remove field from the current layout space using splice so we have the item
71
- */ const [field] = newLayout[currentRowIndex].children.splice(currentFieldIndex, 1);
72
- if (!field || field.name === TEMP_FIELD_NAME) {
73
- return;
74
- }
75
- const newRow = newLayout[newRowIndex].children;
76
- const [newFieldKey] = generateNKeysBetween(newRow, 1, currentFieldIndex, newFieldIndex);
77
- /**
78
- * Next we inject the field into it's new row at it's specified index, we then remove the spaces
79
- * if they exist and recalculate into potentially two arrays ONLY if the sizing is now over 12,
80
- * the row and the rest of the row that couldn't fit.
81
- *
82
- * for example, if i have a row of `[{size: 4}, {size: 6}]` and i add `{size: 8}` a index 0,
83
- * the new array will look like `[{size: 8}, {size: 4}, {size: 6}]` which breaks the limit of 12,
84
- * so instead we make two arrays for the new rows `[[{size: 8}, {size: 4}], [{size: 6}]]` which we
85
- * then inject at the original row point with spacers included.
86
- */ newRow.splice(newFieldIndex, 0, {
87
- ...field,
88
- __temp_key__: newFieldKey
89
- });
90
- if (newLayout[newRowIndex].children.reduce((acc, curr)=>acc + curr.size, 0) > 12) {
91
- const recalculatedRows = chunkArray(newLayout[newRowIndex].children.filter((field)=>field.name !== TEMP_FIELD_NAME));
92
- const rowKeys = generateNKeysBetween(newLayout, recalculatedRows.length, currentRowIndex, newRowIndex);
93
- newLayout.splice(newRowIndex, 1, ...recalculatedRows.map((row, index)=>({
94
- __temp_key__: rowKeys[index],
95
- children: row
96
- })));
104
+ const handleRemoveField = (rowIndex, fieldIndex)=>()=>{
105
+ if (layout[rowIndex].children.length === 1) {
106
+ removeFieldRow(`layout`, rowIndex);
107
+ } else {
108
+ onChange(`layout.${rowIndex}.children`, [
109
+ ...layout[rowIndex].children.slice(0, fieldIndex),
110
+ ...layout[rowIndex].children.slice(fieldIndex + 1)
111
+ ]);
112
+ }
113
+ };
114
+ const handleAddField = (field)=>()=>{
115
+ addFieldRow('layout', {
116
+ children: [
117
+ field
118
+ ]
119
+ });
120
+ };
121
+ const [containers, setContainers] = React__namespace.useState(()=>createDragAndDropContainersFromLayout(layout));
122
+ const [activeDragItem, setActiveDragItem] = React__namespace.useState(null);
123
+ /**
124
+ * Finds either the parent container id or the child id within a container
125
+ */ function findContainer(id, containersAsDictionary) {
126
+ // If the id is a key, then it is the parent container
127
+ if (id in containersAsDictionary) {
128
+ return id;
97
129
  }
98
- /**
99
- * Now we remove our spacers from the rows so we can understand what dead rows exist:
100
- * - if there's only spacers left
101
- * - there's nothing in the row, e.g. a size 12 field left it.
102
- * These rows are then filtered out.
103
- * After that, we recalculate the spacers for the rows that need them.
104
- */ const newLayoutWithSpacers = newLayout.map((row)=>({
130
+ // Otherwise, it is a child inside a container
131
+ return Object.keys(containersAsDictionary).find((key)=>containersAsDictionary[key].children.find((child)=>child.dndId === id));
132
+ }
133
+ /**
134
+ * Gets an item from a container based on its id
135
+ */ const getItemFromContainer = (id, container)=>{
136
+ return container.children.find((item)=>id === item.dndId);
137
+ };
138
+ /**
139
+ * Gets the containers as dictionary for quick lookup
140
+ */ const getContainersAsDictionary = ()=>{
141
+ return Object.fromEntries(containers.map((container)=>[
142
+ container.dndId,
143
+ container
144
+ ]));
145
+ };
146
+ /**
147
+ * Recomputes the empty space in the grid
148
+ */ const createContainersWithSpacers = (layout)=>{
149
+ return layout.map((row)=>({
105
150
  ...row,
106
151
  children: row.children.filter((field)=>field.name !== TEMP_FIELD_NAME)
107
152
  })).filter((row)=>row.children.length > 0).map((row)=>{
108
153
  const totalSpaceTaken = row.children.reduce((acc, curr)=>acc + curr.size, 0);
109
- if (totalSpaceTaken < 12) {
154
+ if (totalSpaceTaken < GRID_COLUMNS) {
110
155
  const [spacerKey] = fractionalIndexing.generateNKeysBetween(row.children.at(-1)?.__temp_key__, undefined, 1);
111
156
  return {
112
157
  ...row,
@@ -114,7 +159,7 @@ const Fields = ({ attributes, fieldSizes, components, metadatas = {} })=>{
114
159
  ...row.children,
115
160
  {
116
161
  name: TEMP_FIELD_NAME,
117
- size: 12 - totalSpaceTaken,
162
+ size: GRID_COLUMNS - totalSpaceTaken,
118
163
  __temp_key__: spacerKey
119
164
  }
120
165
  ]
@@ -122,182 +167,233 @@ const Fields = ({ attributes, fieldSizes, components, metadatas = {} })=>{
122
167
  }
123
168
  return row;
124
169
  });
125
- onChange('layout', newLayoutWithSpacers);
126
170
  };
127
- const handleRemoveField = (rowIndex, fieldIndex)=>()=>{
128
- if (layout[rowIndex].children.length === 1) {
129
- removeFieldRow(`layout`, rowIndex);
130
- } else {
131
- onChange(`layout.${rowIndex}.children`, [
132
- ...layout[rowIndex].children.slice(0, fieldIndex),
133
- ...layout[rowIndex].children.slice(fieldIndex + 1)
134
- ]);
171
+ /**
172
+ * When layout changes (e.g. when a field size is changed or the containers are reordered)
173
+ * we need to update the ids and form names
174
+ */ React__namespace.useEffect(()=>{
175
+ const containers = createDragAndDropContainersFromLayout(layout);
176
+ setContainers(containers);
177
+ }, [
178
+ layout,
179
+ setContainers
180
+ ]);
181
+ return /*#__PURE__*/ jsxRuntime.jsx(core.DndContext, {
182
+ onDragStart: (event)=>{
183
+ const containersAsDictionary = getContainersAsDictionary();
184
+ const activeContainer = findContainer(event.active.id, containersAsDictionary);
185
+ if (!activeContainer) return;
186
+ const activeItem = getItemFromContainer(event.active.id, containersAsDictionary[activeContainer]);
187
+ if (activeItem) {
188
+ setActiveDragItem(activeItem);
135
189
  }
136
- };
137
- const handleAddField = (field)=>()=>{
138
- addFieldRow('layout', {
139
- children: [
140
- field
141
- ]
190
+ },
191
+ onDragOver: ({ active, over })=>{
192
+ const containersAsDictionary = getContainersAsDictionary();
193
+ const activeContainer = findContainer(active.id, containersAsDictionary);
194
+ const overContainer = findContainer(over?.id ?? '', containersAsDictionary);
195
+ const activeContainerIndex = containers.findIndex((container)=>container.dndId === activeContainer);
196
+ const overContainerIndex = containers.findIndex((container)=>container.dndId === overContainer);
197
+ if (!activeContainer || !overContainer) {
198
+ return;
199
+ }
200
+ const draggedItem = getItemFromContainer(active.id, containersAsDictionary[activeContainer]);
201
+ const overItem = getItemFromContainer(over?.id ?? '', containersAsDictionary[overContainer]);
202
+ const overIndex = containersAsDictionary[overContainer].children.findIndex((item)=>item.dndId === over?.id);
203
+ if (!draggedItem) return;
204
+ // Handle a full width field being dragged
205
+ if (draggedItem?.size === GRID_COLUMNS) {
206
+ // Swap the items in the containers
207
+ const update = immer.produce(containers, (draft)=>{
208
+ draft[activeContainerIndex].children = containers[overContainerIndex].children;
209
+ draft[overContainerIndex].children = containers[activeContainerIndex].children;
210
+ });
211
+ setContainers(update);
212
+ return;
213
+ }
214
+ /**
215
+ * Handle an item being dragged from one container to another,
216
+ * the item is removed from its current container, and then added to its new container
217
+ * An item can only be added in a container if there is enough space.
218
+ */ const update = immer.produce(containers, (draft)=>{
219
+ draft[activeContainerIndex].children = draft[activeContainerIndex].children.filter((item)=>item.dndId !== active.id);
220
+ const spaceTaken = draft[overContainerIndex].children.reduce((acc, curr)=>{
221
+ if (curr.name === TEMP_FIELD_NAME) {
222
+ return acc;
223
+ }
224
+ return acc + curr.size;
225
+ }, 0);
226
+ // Check the sizes of the children, if there is no room, exit
227
+ if (spaceTaken + draggedItem.size > GRID_COLUMNS) {
228
+ // Leave the item where it started
229
+ draft[activeContainerIndex].children = containers[activeContainerIndex].children;
230
+ return;
231
+ }
232
+ if (overItem?.name === TEMP_FIELD_NAME) {
233
+ // We are over an invisible spacer, replace it with the dragged item
234
+ draft[overContainerIndex].children.splice(overIndex, 1, draggedItem);
235
+ return;
236
+ }
237
+ // There is room for the item in the container, drop it
238
+ draft[overContainerIndex].children.splice(overIndex, 0, draggedItem);
142
239
  });
143
- };
144
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
145
- paddingTop: 6,
146
- direction: "column",
147
- alignItems: "stretch",
148
- gap: 4,
149
- children: [
150
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
151
- alignItems: "flex-start",
152
- direction: "column",
153
- justifyContent: "space-between",
154
- children: [
155
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
156
- fontWeight: "bold",
157
- children: formatMessage({
158
- id: translations.getTranslation('containers.list.displayedFields'),
159
- defaultMessage: 'Displayed fields'
160
- })
161
- }),
162
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
163
- variant: "pi",
164
- textColor: "neutral600",
165
- children: formatMessage({
166
- id: 'containers.SettingPage.editSettings.description',
167
- defaultMessage: 'Drag & drop the fields to build the layout'
168
- })
169
- })
170
- ]
171
- }),
172
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
173
- padding: 4,
174
- hasRadius: true,
175
- borderStyle: "dashed",
176
- borderWidth: "1px",
177
- borderColor: "neutral300",
178
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
240
+ setContainers(update);
241
+ },
242
+ onDragEnd: (event)=>{
243
+ const { active, over } = event;
244
+ const { id } = active;
245
+ const overId = over?.id;
246
+ const containersAsDictionary = getContainersAsDictionary();
247
+ const activeContainer = findContainer(id, containersAsDictionary);
248
+ const overContainer = findContainer(overId, containersAsDictionary);
249
+ if (!activeContainer || !overContainer) {
250
+ return;
251
+ }
252
+ const activeIndex = containersAsDictionary[activeContainer].children.findIndex((children)=>children.dndId === id);
253
+ const overIndex = containersAsDictionary[overContainer].children.findIndex((children)=>children.dndId === overId);
254
+ const movedContainerItems = immer.produce(containersAsDictionary, (draft)=>{
255
+ if (activeIndex !== overIndex && activeContainer === overContainer) {
256
+ // Move items around inside their own container
257
+ draft[activeContainer].children = sortable.arrayMove(draft[activeContainer].children, activeIndex, overIndex);
258
+ }
259
+ });
260
+ // Remove properties the server does not expect before updating the form
261
+ const updatedContainers = Object.values(movedContainerItems);
262
+ const updatedContainersWithSpacers = createContainersWithSpacers(updatedContainers);
263
+ const updatedLayout = updatedContainersWithSpacers.map(({ dndId: _dndId, children, ...container })=>({
264
+ ...container,
265
+ children: children.map(({ dndId: _dndId, formName: _formName, ...child })=>child)
266
+ }));
267
+ // Update the layout
268
+ onChange('layout', updatedLayout);
269
+ setActiveDragItem(null);
270
+ },
271
+ children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
272
+ paddingTop: 6,
273
+ direction: "column",
274
+ alignItems: "stretch",
275
+ gap: 4,
276
+ children: [
277
+ /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
278
+ alignItems: "flex-start",
179
279
  direction: "column",
180
- alignItems: "stretch",
181
- gap: 2,
280
+ justifyContent: "space-between",
182
281
  children: [
183
- layout.map((row, rowIndex)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
184
- gap: 2,
185
- children: row.children.map(({ size, ...field }, fieldIndex)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
186
- col: size,
187
- direction: "column",
188
- alignItems: "stretch",
189
- children: /*#__PURE__*/ jsxRuntime.jsx(Field, {
190
- attribute: attributes[field.name],
191
- components: components,
192
- index: [
193
- rowIndex,
194
- fieldIndex
195
- ],
196
- name: `layout.${rowIndex}.children.${fieldIndex}`,
197
- onMoveField: handleMoveField,
198
- onRemoveField: handleRemoveField(rowIndex, fieldIndex)
199
- })
200
- }, field.name))
201
- }, row.__temp_key__)),
202
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Menu.Root, {
203
- children: [
204
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Trigger, {
205
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(Icons.Plus, {}),
206
- endIcon: null,
207
- disabled: remainingFields.length === 0,
208
- fullWidth: true,
209
- variant: "secondary",
210
- children: formatMessage({
211
- id: translations.getTranslation('containers.SettingPage.add.field'),
212
- defaultMessage: 'Insert another field'
213
- })
214
- }),
215
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Content, {
216
- children: remainingFields.map((field)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Item, {
217
- onSelect: handleAddField(field),
218
- children: field.label
219
- }, field.name))
220
- })
221
- ]
282
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
283
+ fontWeight: "bold",
284
+ children: formatMessage({
285
+ id: translations.getTranslation('containers.list.displayedFields'),
286
+ defaultMessage: 'Displayed fields'
287
+ })
288
+ }),
289
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
290
+ variant: "pi",
291
+ textColor: "neutral600",
292
+ children: formatMessage({
293
+ id: 'containers.SettingPage.editSettings.description',
294
+ defaultMessage: 'Drag & drop the fields to build the layout'
295
+ })
222
296
  })
223
297
  ]
298
+ }),
299
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
300
+ padding: 4,
301
+ hasRadius: true,
302
+ borderStyle: "dashed",
303
+ borderWidth: "1px",
304
+ borderColor: "neutral300",
305
+ children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
306
+ direction: "column",
307
+ alignItems: "stretch",
308
+ gap: 2,
309
+ children: [
310
+ containers.map((container, containerIndex)=>/*#__PURE__*/ jsxRuntime.jsx(sortable.SortableContext, {
311
+ id: container.dndId,
312
+ items: container.children.map((child)=>({
313
+ id: child.dndId
314
+ })),
315
+ children: /*#__PURE__*/ jsxRuntime.jsx(DroppableContainer, {
316
+ id: container.dndId,
317
+ children: ({ setNodeRef })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
318
+ ref: setNodeRef,
319
+ gap: 2,
320
+ children: container.children.map((child, childIndex)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
321
+ col: child.size,
322
+ direction: "column",
323
+ alignItems: "stretch",
324
+ children: /*#__PURE__*/ jsxRuntime.jsx(SortableItem, {
325
+ id: child.dndId,
326
+ children: /*#__PURE__*/ jsxRuntime.jsx(Field, {
327
+ attribute: attributes[child.name],
328
+ components: components,
329
+ name: child.formName,
330
+ onRemoveField: handleRemoveField(containerIndex, childIndex),
331
+ dndId: child.dndId
332
+ })
333
+ })
334
+ }, child.dndId))
335
+ }, container.dndId)
336
+ })
337
+ }, container.dndId)),
338
+ /*#__PURE__*/ jsxRuntime.jsx(core.DragOverlay, {
339
+ children: activeDragItem ? /*#__PURE__*/ jsxRuntime.jsx(Field, {
340
+ attribute: attributes[activeDragItem.name],
341
+ components: components,
342
+ name: activeDragItem.formName,
343
+ dndId: activeDragItem.dndId
344
+ }) : null
345
+ }),
346
+ /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Menu.Root, {
347
+ children: [
348
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Trigger, {
349
+ startIcon: /*#__PURE__*/ jsxRuntime.jsx(Icons.Plus, {}),
350
+ endIcon: null,
351
+ disabled: remainingFields.length === 0,
352
+ fullWidth: true,
353
+ variant: "secondary",
354
+ children: formatMessage({
355
+ id: translations.getTranslation('containers.SettingPage.add.field'),
356
+ defaultMessage: 'Insert another field'
357
+ })
358
+ }),
359
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Content, {
360
+ children: remainingFields.map((field)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Menu.Item, {
361
+ onSelect: handleAddField(field),
362
+ children: field.label
363
+ }, field.name))
364
+ })
365
+ ]
366
+ })
367
+ ]
368
+ })
224
369
  })
225
- })
226
- ]
370
+ ]
371
+ })
227
372
  });
228
373
  };
229
- /**
230
- * @internal
231
- * @description Small abstraction to solve within an array of fields where you can
232
- * add a field to the beginning or start, move back and forth what it's index range
233
- * should be when calculating it's new temp key
234
- */ const generateNKeysBetween = (field, count, currInd, newInd)=>{
235
- const startKey = currInd > newInd ? field[newInd - 1]?.__temp_key__ : field[newInd]?.__temp_key__;
236
- const endKey = currInd > newInd ? field[newInd]?.__temp_key__ : field[newInd + 1]?.__temp_key__;
237
- return fractionalIndexing.generateNKeysBetween(startKey, endKey, count);
238
- };
239
- /**
240
- * @internal
241
- * @description chunks a row of layouts by the max size we allow, 12. It does not add the
242
- * spacers again, that should be added separately.
243
- */ const chunkArray = (array)=>{
244
- const result = [];
245
- let temp = [];
246
- array.reduce((acc, field)=>{
247
- if (acc + field.size > 12) {
248
- result.push(temp);
249
- temp = [
250
- field
251
- ];
252
- return field.size;
253
- } else {
254
- temp.push(field);
255
- return acc + field.size;
256
- }
257
- }, 0);
258
- if (temp.length > 0) {
259
- result.push(temp);
260
- }
261
- return result;
262
- };
263
374
  const TEMP_FIELD_NAME = '_TEMP_';
264
375
  /**
265
376
  * Displays a field in the layout with drag options, also
266
377
  * opens a modal to edit the details of said field.
267
- */ const Field = ({ attribute, components, name, index, onMoveField, onRemoveField })=>{
378
+ */ const Field = ({ attribute, components, name, onRemoveField, dndId })=>{
268
379
  const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
269
380
  const { formatMessage } = reactIntl.useIntl();
270
381
  const { value } = strapiAdmin.useField(name);
271
- const [{ isDragging }, objectRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(true, {
272
- dropSensitivity: 'immediate',
273
- type: dragAndDrop.ItemTypes.EDIT_FIELD,
274
- item: {
275
- index,
276
- label: value?.label,
277
- name
278
- },
279
- index,
280
- onMoveItem: onMoveField
382
+ const { listeners, setActivatorNodeRef } = sortable.useSortable({
383
+ id: dndId
281
384
  });
282
- React__namespace.useEffect(()=>{
283
- dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), {
284
- captureDraggingState: false
285
- });
286
- }, [
287
- dragPreviewRef
288
- ]);
289
- const composedRefs = designSystem.useComposedRefs(dragRef, objectRef);
290
385
  const handleRemoveField = (e)=>{
291
386
  e.preventDefault();
292
387
  e.stopPropagation();
293
- onRemoveField(e);
388
+ if (onRemoveField) {
389
+ onRemoveField?.(e);
390
+ }
294
391
  };
295
392
  const onEditFieldMeta = (e)=>{
296
393
  e.preventDefault();
297
394
  e.stopPropagation();
298
395
  setIsModalOpen(true);
299
396
  };
300
- const tempRefs = designSystem.useComposedRefs(dropRef, objectRef);
301
397
  if (!value) {
302
398
  return null;
303
399
  }
@@ -307,10 +403,12 @@ const TEMP_FIELD_NAME = '_TEMP_';
307
403
  height: "100%",
308
404
  style: {
309
405
  opacity: 0
310
- },
311
- ref: tempRefs
406
+ }
312
407
  });
313
408
  }
409
+ if (!attribute) {
410
+ return null;
411
+ }
314
412
  return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Root, {
315
413
  open: isModalOpen,
316
414
  onOpenChange: setIsModalOpen,
@@ -319,10 +417,6 @@ const TEMP_FIELD_NAME = '_TEMP_';
319
417
  borderColor: "neutral150",
320
418
  background: "neutral100",
321
419
  hasRadius: true,
322
- style: {
323
- opacity: isDragging ? 0.5 : 1
324
- },
325
- ref: dropRef,
326
420
  gap: 3,
327
421
  cursor: "pointer",
328
422
  onClick: ()=>{
@@ -330,6 +424,7 @@ const TEMP_FIELD_NAME = '_TEMP_';
330
424
  },
331
425
  children: [
332
426
  /*#__PURE__*/ jsxRuntime.jsx(DragButton, {
427
+ ref: setActivatorNodeRef,
333
428
  tag: "span",
334
429
  withTooltip: false,
335
430
  label: formatMessage({
@@ -338,8 +433,7 @@ const TEMP_FIELD_NAME = '_TEMP_';
338
433
  }, {
339
434
  item: value.label
340
435
  }),
341
- onClick: (e)=>e.stopPropagation(),
342
- ref: composedRefs,
436
+ ...listeners,
343
437
  children: /*#__PURE__*/ jsxRuntime.jsx(Icons.Drag, {})
344
438
  }),
345
439
  /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
@@ -446,6 +540,7 @@ const TEMP_FIELD_NAME = '_TEMP_';
446
540
  alignItems: "flex-start",
447
541
  gap: 2,
448
542
  width: "100%",
543
+ wrap: "wrap",
449
544
  children: attribute?.components.map((uid)=>/*#__PURE__*/ jsxRuntime.jsxs(ComponentLink, {
450
545
  // used to stop the edit form from appearing when we click here.
451
546
  onClick: (e)=>e.stopPropagation(),
@@ -530,5 +625,6 @@ const ComponentLink = styledComponents.styled(reactRouterDom.NavLink)`
530
625
  `;
531
626
 
532
627
  exports.Fields = Fields;
628
+ exports.SortableItem = SortableItem;
533
629
  exports.TEMP_FIELD_NAME = TEMP_FIELD_NAME;
534
630
  //# sourceMappingURL=Fields.js.map