@measured/puck 0.11.0-canary.b28404f → 0.11.0-canary.c8c02fd
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +17 -215
- package/dist/index.d.ts +24 -75
- package/dist/index.js +59 -85
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# puck
|
2
2
|
|
3
|
-
The self-hosted, drag and drop editor for React.
|
4
|
-
|
5
3
|
<p align="left">
|
6
4
|
<a aria-label="Measured logo" href="https://measured.co">
|
7
5
|
<img src="https://img.shields.io/badge/MADE%20BY%20Measured-000000.svg?style=for-the-badge&labelColor=000">
|
@@ -17,7 +15,7 @@ The self-hosted, drag and drop editor for React.
|
|
17
15
|
</a>
|
18
16
|
</p>
|
19
17
|
|
20
|
-
|
18
|
+
The self-hosted, drag and drop editor for React.
|
21
19
|
|
22
20
|
- 🖱️ **Drag and drop**: Visual editing for your existing React component library
|
23
21
|
- 🌐 **Integrations**: Load your content from a 3rd party headless CMS
|
@@ -234,163 +232,6 @@ The current DropZone implementation has certain rules and limitations:
|
|
234
232
|
3. You can't drag between DropZones that don't share a parent (or _area_)
|
235
233
|
4. Your mouse must be directly over a DropZone for a collision to be detected
|
236
234
|
|
237
|
-
## Adaptors
|
238
|
-
|
239
|
-
Adaptors can be used to import data from a third-party API, such as a headless CMS.
|
240
|
-
|
241
|
-
### Example
|
242
|
-
|
243
|
-
The `external` field type enables us to use an adaptor to query data from a third party API:
|
244
|
-
|
245
|
-
```tsx
|
246
|
-
const myAdaptor = {
|
247
|
-
name: "My adaptor",
|
248
|
-
fetchList: async () => {
|
249
|
-
const response = await fetch("https://www.example.com/api");
|
250
|
-
|
251
|
-
return {
|
252
|
-
text: response.json().text,
|
253
|
-
};
|
254
|
-
},
|
255
|
-
};
|
256
|
-
|
257
|
-
const config = {
|
258
|
-
components: {
|
259
|
-
HeadingBlock: {
|
260
|
-
fields: {
|
261
|
-
myData: {
|
262
|
-
type: "external",
|
263
|
-
adaptor: myAdaptor,
|
264
|
-
},
|
265
|
-
},
|
266
|
-
render: ({ myData }) => {
|
267
|
-
return <h1>{myData.text}</h1>;
|
268
|
-
},
|
269
|
-
},
|
270
|
-
},
|
271
|
-
};
|
272
|
-
```
|
273
|
-
|
274
|
-
When the user interacts with this adaptor, they'll be presented with a list of items to choose from. Once they select an item, the value will be mapped onto the prop. In this case, `myData`.
|
275
|
-
|
276
|
-
## Dynamic prop resolution
|
277
|
-
|
278
|
-
Dynamic prop resolution allows developers to resolve props for components without saving the data to the Puck data model.
|
279
|
-
|
280
|
-
### resolveProps()
|
281
|
-
|
282
|
-
`resolveProps` is defined in the component config, and allows the developer to make asynchronous calls to change the props after they've been set by Puck.
|
283
|
-
|
284
|
-
#### Args
|
285
|
-
|
286
|
-
- **props** (`object`): the current props for your component stored in the Puck data
|
287
|
-
|
288
|
-
#### Response
|
289
|
-
|
290
|
-
- **props** (`object`): the resolved props for your component. Will not be stored in the Puck data
|
291
|
-
- **readOnly** (`object`): an object describing which fields on the component are currently read-only
|
292
|
-
- **[prop]** (`boolean`): boolean describing whether or not the prop field is read-only
|
293
|
-
|
294
|
-
#### Examples
|
295
|
-
|
296
|
-
##### Basic example
|
297
|
-
|
298
|
-
In this example, we remap the `text` prop to the `title` prop and mark the `title` field as read-only.
|
299
|
-
|
300
|
-
```tsx
|
301
|
-
const config = {
|
302
|
-
components: {
|
303
|
-
HeadingBlock: {
|
304
|
-
fields: {
|
305
|
-
text: {
|
306
|
-
type: "text",
|
307
|
-
},
|
308
|
-
title: {
|
309
|
-
type: "text",
|
310
|
-
},
|
311
|
-
},
|
312
|
-
resolveProps: async (props) => {
|
313
|
-
return {
|
314
|
-
props: {
|
315
|
-
title: props.text,
|
316
|
-
},
|
317
|
-
readOnly: {
|
318
|
-
title: true,
|
319
|
-
},
|
320
|
-
};
|
321
|
-
},
|
322
|
-
render: ({ title }) => {
|
323
|
-
return <h1>{title}</h1>;
|
324
|
-
},
|
325
|
-
},
|
326
|
-
},
|
327
|
-
};
|
328
|
-
```
|
329
|
-
|
330
|
-
##### Combining with adaptors
|
331
|
-
|
332
|
-
A more advanced pattern is to combine the `resolveProps` method with the adaptors to dynamically fetch data when rendering the component.
|
333
|
-
|
334
|
-
```tsx
|
335
|
-
const myAdaptor = {
|
336
|
-
name: "My adaptor",
|
337
|
-
fetchList: async () => {
|
338
|
-
const response = await fetch("https://www.example.com/api");
|
339
|
-
|
340
|
-
return {
|
341
|
-
id: response.json().id,
|
342
|
-
};
|
343
|
-
},
|
344
|
-
};
|
345
|
-
|
346
|
-
const config = {
|
347
|
-
components: {
|
348
|
-
HeadingBlock: {
|
349
|
-
fields: {
|
350
|
-
myData: {
|
351
|
-
type: "external",
|
352
|
-
adaptor: myAdaptor,
|
353
|
-
},
|
354
|
-
title: {
|
355
|
-
type: "text",
|
356
|
-
},
|
357
|
-
},
|
358
|
-
resolveProps: async (props) => {
|
359
|
-
if (!myData.id) {
|
360
|
-
return { props, readOnly: { title: false } };
|
361
|
-
}
|
362
|
-
|
363
|
-
const latestData = await fetch(
|
364
|
-
`https://www.example.com/api/${myData.id}`
|
365
|
-
);
|
366
|
-
|
367
|
-
return {
|
368
|
-
props: {
|
369
|
-
title: latestData.json().text,
|
370
|
-
},
|
371
|
-
readOnly: {
|
372
|
-
title: true,
|
373
|
-
},
|
374
|
-
};
|
375
|
-
},
|
376
|
-
render: ({ title }) => {
|
377
|
-
return <h1>{title}</h1>;
|
378
|
-
},
|
379
|
-
},
|
380
|
-
},
|
381
|
-
};
|
382
|
-
```
|
383
|
-
|
384
|
-
### resolveData()
|
385
|
-
|
386
|
-
`resolveData` is a utility function exported by Puck to enable the developer to resolve their custom props before rendering their component with `<Render>`. This is ideally done on the server. If you're using `resolveProps`, you _must_ use `resolveData` before rendering.
|
387
|
-
|
388
|
-
```tsx
|
389
|
-
import { resolveData } from "@measured/puck";
|
390
|
-
|
391
|
-
const resolvedData = resolveData(data, config);
|
392
|
-
```
|
393
|
-
|
394
235
|
## Reference
|
395
236
|
|
396
237
|
### `<Puck>`
|
@@ -436,13 +277,6 @@ The `Config` object describes which components Puck should render, how they shou
|
|
436
277
|
- **fields** (`Field`): The Field objects describing the input data stored against this component.
|
437
278
|
- **render** (`Component`): Render function for your React component. Receives props as defined in fields.
|
438
279
|
- **defaultProps** (`object` [optional]): Default props to pass to your component. Will show in fields.
|
439
|
-
- **resolveProps** (`async (props: object) => object` [optional]): Function to dynamically change props before rendering the component.
|
440
|
-
- Args
|
441
|
-
- **props** (`object`): the current props for your component stored in the Puck data
|
442
|
-
- Response
|
443
|
-
- **props** (`object`): the resolved props for your component. Will not be stored in the Puck data
|
444
|
-
- **readOnly** (`object`): an object describing which fields on the component are currently read-only
|
445
|
-
- **[prop]** (`boolean`): boolean describing whether or not the prop field is read-only
|
446
280
|
- **categories** (`object`): Component categories for rendering in the side bar or restricting in DropZones
|
447
281
|
- **[categoryName]** (`object`)
|
448
282
|
- **components** (`sting[]`, [optional]): Array containing the names of components in this category
|
@@ -454,58 +288,17 @@ The `Config` object describes which components Puck should render, how they shou
|
|
454
288
|
|
455
289
|
A `Field` represents a user input field shown in the Puck interface.
|
456
290
|
|
457
|
-
|
458
|
-
|
291
|
+
- **type** (`text` | `textarea` | `number` | `select` | `radio` | `external` | `array` | `custom`): The input type to render
|
459
292
|
- **label** (`text` [optional]): A label for the input. Will use the key if not provided.
|
460
|
-
|
461
|
-
### Text Fields
|
462
|
-
|
463
|
-
- **type** (`"text"`)
|
464
|
-
|
465
|
-
### Textarea Fields
|
466
|
-
|
467
|
-
- **type** (`"textarea"`)
|
468
|
-
|
469
|
-
### Number Fields
|
470
|
-
|
471
|
-
- **type** (`"number"`)
|
472
|
-
|
473
|
-
### Select Fields
|
474
|
-
|
475
|
-
- **type** (`"select"`)
|
476
|
-
- **options** (`object[]`): array of items to render
|
477
|
-
- **label** (`string`)
|
478
|
-
- **value** (`string` | `number` | `boolean`)
|
479
|
-
|
480
|
-
### Radio Fields
|
481
|
-
|
482
|
-
- **type** (`"radio"`)
|
483
|
-
- **options** (`object[]`): array of items to render
|
484
|
-
- **label** (`string`)
|
485
|
-
- **value** (`string` | `number` | `boolean`)
|
486
|
-
|
487
|
-
### Array Fields
|
488
|
-
|
489
|
-
- **type** (`"array"`)
|
490
|
-
- **arrayFields** (`object`): Object describing sub-fields for each item
|
293
|
+
- **arrayFields** (`object`): Object describing sub-fields for items in an `array` input
|
491
294
|
- **[fieldName]** (`Field`): The Field objects describing the input data for each item
|
492
|
-
|
295
|
+
- **getItemSummary** (`(object, number) => string` [optional]): Function to get the name of each item when using the `array` or `external` field types
|
493
296
|
- **defaultItemProps** (`object` [optional]): Default props to pass to each new item added, when using a `array` field type
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
- **type** (`"external"`)
|
500
|
-
- **adaptor** (`Adaptor`): Content adaptor responsible for fetching data to show in the table
|
501
|
-
- **name** (`string`): The human-readable name of the adaptor
|
502
|
-
- **fetchList** (`(adaptorParams: object) => object`): Fetch content from a third-party API and return an array
|
503
|
-
- **mapProp** (`(selectedItem: object) => object`): Map the selected item into another shape
|
297
|
+
- **options** (`object[]`): array of items to render for select or radio inputs
|
298
|
+
- **label** (`string`)
|
299
|
+
- **value** (`string` | `number` | `boolean`)
|
300
|
+
- **adaptor** (`Adaptor`): Content adaptor if using the `external` input type
|
504
301
|
- **adaptorParams** (`object`): Paramaters passed to the adaptor
|
505
|
-
|
506
|
-
### Custom Fields
|
507
|
-
|
508
|
-
- **type** (`"custom"`)
|
509
302
|
- **render** (`Component`): Render a custom field. Receives the props:
|
510
303
|
- **field** (`Field`): Field configuration
|
511
304
|
- **name** (`string`): Name of the field
|
@@ -540,6 +333,15 @@ The `Data` object stores the puck page data.
|
|
540
333
|
- **props** (object):
|
541
334
|
- **[prop]** (string): User defined data from component fields
|
542
335
|
|
336
|
+
### `Adaptor`
|
337
|
+
|
338
|
+
An `Adaptor` can be used to load content from an external content repository, like Strapi.js.
|
339
|
+
|
340
|
+
- **name** (`string`): The human-readable name of the adaptor
|
341
|
+
- **fetchList** (`(adaptorParams: object) => object`): Fetch a list of content and return an array
|
342
|
+
|
343
|
+
> NB Using an adaptor on the reserved field name `_data` will spread the resulting data over your object, and lock the overridden fields.
|
344
|
+
|
543
345
|
### `Plugin`
|
544
346
|
|
545
347
|
Plugins that can be used to enhance Puck.
|
package/dist/index.d.ts
CHANGED
@@ -8,71 +8,39 @@ type ItemSelector = {
|
|
8
8
|
zone?: string;
|
9
9
|
};
|
10
10
|
|
11
|
-
type Adaptor<AdaptorParams = {}
|
11
|
+
type Adaptor<AdaptorParams = {}> = {
|
12
12
|
name: string;
|
13
|
-
fetchList: (adaptorParams?: AdaptorParams) => Promise<
|
14
|
-
mapProp?: (value: TableShape) => PropShape;
|
13
|
+
fetchList: (adaptorParams?: AdaptorParams) => Promise<Record<string, any>[] | null>;
|
15
14
|
};
|
16
|
-
type
|
15
|
+
type WithId<T> = T & {
|
17
16
|
id: string;
|
18
|
-
_meta?: {
|
19
|
-
readOnly: Partial<Record<keyof Props, boolean>>;
|
20
|
-
};
|
21
|
-
};
|
22
|
-
type BaseField = {
|
23
|
-
label?: string;
|
24
|
-
};
|
25
|
-
type TextField = BaseField & {
|
26
|
-
type: "text" | "number" | "textarea";
|
27
|
-
};
|
28
|
-
type SelectField = BaseField & {
|
29
|
-
type: "select" | "radio";
|
30
|
-
options: {
|
31
|
-
label: string;
|
32
|
-
value: string | number | boolean;
|
33
|
-
}[];
|
34
|
-
};
|
35
|
-
type ArrayField<Props extends {
|
36
|
-
[key: string]: any;
|
37
|
-
} = {
|
38
|
-
[key: string]: any;
|
39
|
-
}> = BaseField & {
|
40
|
-
type: "array";
|
41
|
-
arrayFields: {
|
42
|
-
[SubPropName in keyof Props[0]]: Field<Props[0][SubPropName]>;
|
43
|
-
};
|
44
|
-
defaultItemProps?: Props[0];
|
45
|
-
getItemSummary?: (item: Props[0], index?: number) => string;
|
46
17
|
};
|
47
|
-
type
|
18
|
+
type Field<Props extends {
|
48
19
|
[key: string]: any;
|
49
20
|
} = {
|
50
21
|
[key: string]: any;
|
51
|
-
}> =
|
52
|
-
type: "external";
|
53
|
-
|
22
|
+
}> = {
|
23
|
+
type: "text" | "textarea" | "number" | "select" | "array" | "external" | "radio" | "custom";
|
24
|
+
label?: string;
|
25
|
+
adaptor?: Adaptor;
|
54
26
|
adaptorParams?: object;
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
type: "custom";
|
63
|
-
render: (props: {
|
64
|
-
field: CustomField;
|
27
|
+
arrayFields?: {
|
28
|
+
[SubPropName in keyof Props]: Field<Props[SubPropName][0]>;
|
29
|
+
};
|
30
|
+
getItemSummary?: (item: Props, index?: number) => string;
|
31
|
+
defaultItemProps?: Props;
|
32
|
+
render?: (props: {
|
33
|
+
field: Field;
|
65
34
|
name: string;
|
66
35
|
value: any;
|
67
|
-
onChange: (value:
|
36
|
+
onChange: (value: any) => void;
|
68
37
|
readOnly?: boolean;
|
69
38
|
}) => ReactElement;
|
39
|
+
options?: {
|
40
|
+
label: string;
|
41
|
+
value: string | number | boolean;
|
42
|
+
}[];
|
70
43
|
};
|
71
|
-
type Field<Props extends {
|
72
|
-
[key: string]: any;
|
73
|
-
} = {
|
74
|
-
[key: string]: any;
|
75
|
-
}> = TextField | SelectField | ArrayField<Props> | ExternalField<Props> | CustomField;
|
76
44
|
type DefaultRootProps = {
|
77
45
|
children: ReactNode;
|
78
46
|
title: string;
|
@@ -84,7 +52,7 @@ type DefaultComponentProps = {
|
|
84
52
|
editMode?: boolean;
|
85
53
|
};
|
86
54
|
type Fields<ComponentProps extends DefaultComponentProps = DefaultComponentProps> = {
|
87
|
-
[PropName in keyof Omit<Required<ComponentProps>, "children" | "editMode">]: Field<ComponentProps[PropName]>;
|
55
|
+
[PropName in keyof Omit<Required<ComponentProps>, "children" | "editMode">]: Field<ComponentProps[PropName][0]>;
|
88
56
|
};
|
89
57
|
type Content<Props extends {
|
90
58
|
[key: string]: any;
|
@@ -92,13 +60,9 @@ type Content<Props extends {
|
|
92
60
|
[key: string]: any;
|
93
61
|
}> = MappedItem<Props>[];
|
94
62
|
type ComponentConfig<ComponentProps extends DefaultComponentProps = DefaultComponentProps, DefaultProps = ComponentProps> = {
|
95
|
-
render: (props:
|
63
|
+
render: (props: WithId<ComponentProps>) => ReactElement;
|
96
64
|
defaultProps?: DefaultProps;
|
97
65
|
fields?: Fields<ComponentProps>;
|
98
|
-
resolveProps?: (props: WithPuckProps<ComponentProps>) => Promise<{
|
99
|
-
props: WithPuckProps<ComponentProps>;
|
100
|
-
readOnly?: Partial<Record<keyof ComponentProps, boolean>>;
|
101
|
-
}>;
|
102
66
|
};
|
103
67
|
type Category<ComponentName> = {
|
104
68
|
components?: ComponentName[];
|
@@ -129,7 +93,7 @@ type MappedItem<Props extends {
|
|
129
93
|
[key: string]: any;
|
130
94
|
}> = {
|
131
95
|
type: keyof Props;
|
132
|
-
props:
|
96
|
+
props: WithId<{
|
133
97
|
[key: string]: any;
|
134
98
|
}>;
|
135
99
|
};
|
@@ -252,7 +216,6 @@ type PathData = Record<string, {
|
|
252
216
|
type DropZoneContext = {
|
253
217
|
data: Data;
|
254
218
|
config: Config;
|
255
|
-
dynamicProps?: Record<string, any>;
|
256
219
|
itemSelector?: ItemSelector | null;
|
257
220
|
setItemSelector?: (newIndex: ItemSelector | null) => void;
|
258
221
|
dispatch?: (action: PuckAction) => void;
|
@@ -346,24 +309,10 @@ declare function Render({ config, data }: {
|
|
346
309
|
data: Data;
|
347
310
|
}): react_jsx_runtime.JSX.Element;
|
348
311
|
|
349
|
-
declare const resolveData: (data: Data, config: Config) => Promise<{
|
350
|
-
content: {
|
351
|
-
props: any;
|
352
|
-
type: string | number;
|
353
|
-
}[];
|
354
|
-
zones: Record<string, MappedItem<{
|
355
|
-
[key: string]: any;
|
356
|
-
}>[]>;
|
357
|
-
root: {
|
358
|
-
[key: string]: any;
|
359
|
-
title: string;
|
360
|
-
};
|
361
|
-
}>;
|
362
|
-
|
363
312
|
declare const FieldLabel: ({ children, icon, label, }: {
|
364
313
|
children?: ReactNode;
|
365
314
|
icon?: ReactNode;
|
366
315
|
label: string;
|
367
316
|
}) => react_jsx_runtime.JSX.Element;
|
368
317
|
|
369
|
-
export { Adaptor, AppState,
|
318
|
+
export { Adaptor, AppState, ArrayState, Button, ComponentConfig, Config, Content, Data, DefaultComponentProps, DefaultRootProps, DropZone, DropZoneProvider, Field, FieldLabel, Fields, IconButton, ItemWithId, MappedItem, Puck, Render, UiState, dropZoneContext };
|
package/dist/index.js
CHANGED
@@ -1109,8 +1109,7 @@ __export(core_exports, {
|
|
1109
1109
|
IconButton: () => IconButton,
|
1110
1110
|
Puck: () => Puck,
|
1111
1111
|
Render: () => Render,
|
1112
|
-
dropZoneContext: () => dropZoneContext
|
1113
|
-
resolveData: () => resolveData
|
1112
|
+
dropZoneContext: () => dropZoneContext
|
1114
1113
|
});
|
1115
1114
|
module.exports = __toCommonJS(core_exports);
|
1116
1115
|
init_react_import();
|
@@ -2664,13 +2663,11 @@ var setupZone = (data, zoneKey) => {
|
|
2664
2663
|
};
|
2665
2664
|
|
2666
2665
|
// lib/get-item.ts
|
2667
|
-
var getItem = (selector, data
|
2666
|
+
var getItem = (selector, data) => {
|
2668
2667
|
if (!selector.zone || selector.zone === rootDroppableId) {
|
2669
|
-
|
2670
|
-
return __spreadProps(__spreadValues({}, item2), { props: dynamicProps[item2.props.id] || item2.props });
|
2668
|
+
return data.content[selector.index];
|
2671
2669
|
}
|
2672
|
-
|
2673
|
-
return __spreadProps(__spreadValues({}, item), { props: dynamicProps[item.props.id] || item.props });
|
2670
|
+
return setupZone(data, selector.zone).zones[selector.zone][selector.index];
|
2674
2671
|
};
|
2675
2672
|
|
2676
2673
|
// lib/index.ts
|
@@ -2678,6 +2675,14 @@ init_react_import();
|
|
2678
2675
|
|
2679
2676
|
// lib/filter.ts
|
2680
2677
|
init_react_import();
|
2678
|
+
var filter = (obj, validKeys) => {
|
2679
|
+
return validKeys.reduce((acc, item) => {
|
2680
|
+
if (typeof obj[item] !== "undefined") {
|
2681
|
+
return __spreadProps(__spreadValues({}, acc), { [item]: obj[item] });
|
2682
|
+
}
|
2683
|
+
return acc;
|
2684
|
+
}, {});
|
2685
|
+
};
|
2681
2686
|
|
2682
2687
|
// lib/reorder.ts
|
2683
2688
|
init_react_import();
|
@@ -2828,7 +2833,6 @@ function DropZoneEdit({ zone, style }) {
|
|
2828
2833
|
const {
|
2829
2834
|
// These all need setting via context
|
2830
2835
|
data,
|
2831
|
-
dynamicProps = {},
|
2832
2836
|
dispatch = () => null,
|
2833
2837
|
config,
|
2834
2838
|
itemSelector,
|
@@ -2930,7 +2934,7 @@ function DropZoneEdit({ zone, style }) {
|
|
2930
2934
|
content.map((item, i) => {
|
2931
2935
|
var _a2;
|
2932
2936
|
const componentId = item.props.id;
|
2933
|
-
const defaultedProps = __spreadProps(__spreadValues(__spreadValues({}, (_a2 = config.components[item.type]) == null ? void 0 : _a2.defaultProps),
|
2937
|
+
const defaultedProps = __spreadProps(__spreadValues(__spreadValues({}, (_a2 = config.components[item.type]) == null ? void 0 : _a2.defaultProps), item.props), {
|
2934
2938
|
editMode: true
|
2935
2939
|
});
|
2936
2940
|
const isSelected = (selectedItem == null ? void 0 : selectedItem.props.id) === componentId || false;
|
@@ -3320,7 +3324,7 @@ var ArrayField = ({
|
|
3320
3324
|
});
|
3321
3325
|
setArrayState({ items: newItems });
|
3322
3326
|
}, [value]);
|
3323
|
-
if (
|
3327
|
+
if (!field.arrayFields) {
|
3324
3328
|
return null;
|
3325
3329
|
}
|
3326
3330
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: getClassNameInput(), children: [
|
@@ -3519,7 +3523,6 @@ var ExternalInput = ({
|
|
3519
3523
|
onChange,
|
3520
3524
|
value = null
|
3521
3525
|
}) => {
|
3522
|
-
const { mapProp = (val) => val } = field.adaptor || {};
|
3523
3526
|
const [data, setData] = (0, import_react27.useState)([]);
|
3524
3527
|
const [isOpen, setOpen] = (0, import_react27.useState)(false);
|
3525
3528
|
const [selectedData, setSelectedData] = (0, import_react27.useState)(value);
|
@@ -3597,9 +3600,9 @@ var ExternalInput = ({
|
|
3597
3600
|
{
|
3598
3601
|
style: { whiteSpace: "nowrap" },
|
3599
3602
|
onClick: (e) => {
|
3600
|
-
onChange(
|
3603
|
+
onChange(item);
|
3601
3604
|
setOpen(false);
|
3602
|
-
setSelectedData(
|
3605
|
+
setSelectedData(item);
|
3603
3606
|
},
|
3604
3607
|
children: keys.map((key) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { children: item[key] }, key))
|
3605
3608
|
},
|
@@ -3621,18 +3624,16 @@ var getClassName9 = get_class_name_factory_default("Input", styles_module_defaul
|
|
3621
3624
|
var ExternalField = ({
|
3622
3625
|
field,
|
3623
3626
|
onChange,
|
3627
|
+
readOnly,
|
3624
3628
|
value,
|
3625
3629
|
name,
|
3626
3630
|
label
|
3627
3631
|
}) => {
|
3628
|
-
if (
|
3632
|
+
if (!field.adaptor) {
|
3629
3633
|
return null;
|
3630
3634
|
}
|
3631
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: getClassName9(), children: [
|
3632
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.
|
3633
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: getClassName9("labelIcon"), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(link_default, { size: 16 }) }),
|
3634
|
-
label || name
|
3635
|
-
] }),
|
3635
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: getClassName9(""), children: [
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: getClassName9("label"), children: name === "_data" ? "External content" : label || name }),
|
3636
3637
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ExternalInput, { field, onChange, value })
|
3637
3638
|
] });
|
3638
3639
|
};
|
@@ -3648,7 +3649,7 @@ var RadioField = ({
|
|
3648
3649
|
value,
|
3649
3650
|
name
|
3650
3651
|
}) => {
|
3651
|
-
if (
|
3652
|
+
if (!field.options) {
|
3652
3653
|
return null;
|
3653
3654
|
}
|
3654
3655
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: getClassName10(), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: getClassName10("radioGroup"), children: [
|
@@ -3698,7 +3699,7 @@ var SelectField = ({
|
|
3698
3699
|
value,
|
3699
3700
|
name
|
3700
3701
|
}) => {
|
3701
|
-
if (
|
3702
|
+
if (!field.options) {
|
3702
3703
|
return null;
|
3703
3704
|
}
|
3704
3705
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: getClassName11(), children: [
|
@@ -4745,26 +4746,6 @@ var useComponentList = (config, ui) => {
|
|
4745
4746
|
return componentList;
|
4746
4747
|
};
|
4747
4748
|
|
4748
|
-
// lib/resolve-all-props.ts
|
4749
|
-
init_react_import();
|
4750
|
-
var resolveAllProps = (content, config) => __async(void 0, null, function* () {
|
4751
|
-
return yield Promise.all(
|
4752
|
-
content.map((item) => __async(void 0, null, function* () {
|
4753
|
-
const configForItem = config.components[item.type];
|
4754
|
-
if (configForItem.resolveProps) {
|
4755
|
-
const { props: resolvedProps, readOnly = {} } = yield configForItem.resolveProps(item.props);
|
4756
|
-
const { _meta: { readOnly: existingReadOnly = {} } = {} } = item.props || {};
|
4757
|
-
return __spreadProps(__spreadValues({}, item), {
|
4758
|
-
props: __spreadProps(__spreadValues({}, resolvedProps), {
|
4759
|
-
_meta: { readOnly: __spreadValues(__spreadValues({}, existingReadOnly), readOnly) }
|
4760
|
-
})
|
4761
|
-
});
|
4762
|
-
}
|
4763
|
-
return item;
|
4764
|
-
}))
|
4765
|
-
);
|
4766
|
-
});
|
4767
|
-
|
4768
4749
|
// components/Puck/index.tsx
|
4769
4750
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
4770
4751
|
var defaultPageFields = {
|
@@ -4795,7 +4776,6 @@ function Puck({
|
|
4795
4776
|
headerPath
|
4796
4777
|
}) {
|
4797
4778
|
var _a, _b;
|
4798
|
-
const [dynamicProps, setDynamicProps] = (0, import_react34.useState)({});
|
4799
4779
|
const [reducer] = (0, import_react34.useState)(() => createReducer({ config }));
|
4800
4780
|
const initialAppState = __spreadProps(__spreadValues({}, defaultAppState), {
|
4801
4781
|
data: initialData,
|
@@ -4821,21 +4801,6 @@ function Puck({
|
|
4821
4801
|
flushZones(initialAppState)
|
4822
4802
|
);
|
4823
4803
|
const { data, ui } = appState;
|
4824
|
-
(0, import_react34.useEffect)(() => {
|
4825
|
-
const flatContent = Object.keys(data.zones || {}).reduce(
|
4826
|
-
(acc, zone) => [...acc, ...data.zones[zone]],
|
4827
|
-
data.content
|
4828
|
-
);
|
4829
|
-
resolveAllProps(flatContent, config).then((dynamicContent) => {
|
4830
|
-
const newDynamicProps = dynamicContent.reduce(
|
4831
|
-
(acc, item) => {
|
4832
|
-
return __spreadProps(__spreadValues({}, acc), { [item.props.id]: item.props });
|
4833
|
-
},
|
4834
|
-
{}
|
4835
|
-
);
|
4836
|
-
setDynamicProps(newDynamicProps);
|
4837
|
-
});
|
4838
|
-
}, [data]);
|
4839
4804
|
const { canForward, canRewind, rewind, forward } = usePuckHistory({
|
4840
4805
|
appState,
|
4841
4806
|
dispatch
|
@@ -4850,7 +4815,7 @@ function Puck({
|
|
4850
4815
|
},
|
4851
4816
|
[]
|
4852
4817
|
);
|
4853
|
-
const selectedItem = itemSelector ? getItem(itemSelector, data
|
4818
|
+
const selectedItem = itemSelector ? getItem(itemSelector, data) : null;
|
4854
4819
|
const Page = (0, import_react34.useCallback)(
|
4855
4820
|
(pageProps) => {
|
4856
4821
|
var _a2, _b2;
|
@@ -4979,7 +4944,6 @@ function Puck({
|
|
4979
4944
|
value: {
|
4980
4945
|
data,
|
4981
4946
|
itemSelector,
|
4982
|
-
dynamicProps,
|
4983
4947
|
setItemSelector,
|
4984
4948
|
config,
|
4985
4949
|
dispatch,
|
@@ -5260,18 +5224,42 @@ function Puck({
|
|
5260
5224
|
showBreadcrumbs: true,
|
5261
5225
|
title: selectedItem ? selectedItem.type : "Page",
|
5262
5226
|
children: Object.keys(fields).map((fieldName) => {
|
5227
|
+
var _a2, _b2, _c, _d;
|
5263
5228
|
const field = fields[fieldName];
|
5264
5229
|
const onChange2 = (value) => {
|
5265
5230
|
let currentProps;
|
5231
|
+
let newProps;
|
5266
5232
|
if (selectedItem) {
|
5267
5233
|
currentProps = selectedItem.props;
|
5268
5234
|
} else {
|
5269
5235
|
currentProps = data.root;
|
5270
5236
|
}
|
5271
|
-
|
5272
|
-
|
5273
|
-
|
5274
|
-
|
5237
|
+
if (fieldName === "_data") {
|
5238
|
+
if (!value) {
|
5239
|
+
const _a3 = currentProps._meta || {}, { locked } = _a3, _meta = __objRest(_a3, ["locked"]);
|
5240
|
+
newProps = __spreadProps(__spreadValues({}, currentProps), {
|
5241
|
+
_data: void 0,
|
5242
|
+
_meta
|
5243
|
+
});
|
5244
|
+
} else {
|
5245
|
+
const changedFields = filter(
|
5246
|
+
// filter out anything not supported by this component
|
5247
|
+
value,
|
5248
|
+
Object.keys(fields)
|
5249
|
+
);
|
5250
|
+
newProps = __spreadProps(__spreadValues(__spreadValues({}, currentProps), changedFields), {
|
5251
|
+
_data: value,
|
5252
|
+
// TODO perf - this is duplicative and will make payload larger
|
5253
|
+
_meta: {
|
5254
|
+
locked: Object.keys(changedFields)
|
5255
|
+
}
|
5256
|
+
});
|
5257
|
+
}
|
5258
|
+
} else {
|
5259
|
+
newProps = __spreadProps(__spreadValues({}, currentProps), {
|
5260
|
+
[fieldName]: value
|
5261
|
+
});
|
5262
|
+
}
|
5275
5263
|
if (itemSelector) {
|
5276
5264
|
dispatch({
|
5277
5265
|
type: "replace",
|
@@ -5287,28 +5275,31 @@ function Puck({
|
|
5287
5275
|
}
|
5288
5276
|
};
|
5289
5277
|
if (selectedItem && itemSelector) {
|
5290
|
-
const { readOnly = {} } = selectedItem.props._meta || {};
|
5291
5278
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
5292
5279
|
InputOrGroup,
|
5293
5280
|
{
|
5294
5281
|
field,
|
5295
5282
|
name: fieldName,
|
5296
5283
|
label: field.label,
|
5297
|
-
readOnly:
|
5284
|
+
readOnly: ((_b2 = (_a2 = getItem(
|
5285
|
+
itemSelector,
|
5286
|
+
data
|
5287
|
+
).props._meta) == null ? void 0 : _a2.locked) == null ? void 0 : _b2.indexOf(fieldName)) > -1,
|
5298
5288
|
value: selectedItem.props[fieldName],
|
5299
5289
|
onChange: onChange2
|
5300
5290
|
},
|
5301
5291
|
`${selectedItem.props.id}_${fieldName}`
|
5302
5292
|
);
|
5303
5293
|
} else {
|
5304
|
-
const { readOnly = {} } = data.root._meta || {};
|
5305
5294
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
5306
5295
|
InputOrGroup,
|
5307
5296
|
{
|
5308
5297
|
field,
|
5309
5298
|
name: fieldName,
|
5310
5299
|
label: field.label,
|
5311
|
-
readOnly:
|
5300
|
+
readOnly: ((_d = (_c = data.root._meta) == null ? void 0 : _c.locked) == null ? void 0 : _d.indexOf(
|
5301
|
+
fieldName
|
5302
|
+
)) > -1,
|
5312
5303
|
value: data.root[fieldName],
|
5313
5304
|
onChange: onChange2
|
5314
5305
|
},
|
@@ -5339,22 +5330,6 @@ function Render({ config, data }) {
|
|
5339
5330
|
}
|
5340
5331
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DropZoneProvider, { value: { data, config, mode: "render" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DropZone, { zone: rootDroppableId }) });
|
5341
5332
|
}
|
5342
|
-
|
5343
|
-
// lib/resolve-data.ts
|
5344
|
-
init_react_import();
|
5345
|
-
var resolveData = (data, config) => __async(void 0, null, function* () {
|
5346
|
-
const { zones = {} } = data;
|
5347
|
-
const zoneKeys = Object.keys(zones);
|
5348
|
-
const resolvedZones = {};
|
5349
|
-
for (let i = 0; i < zoneKeys.length; i++) {
|
5350
|
-
const zoneKey = zoneKeys[i];
|
5351
|
-
resolvedZones[zoneKey] = yield resolveAllProps(zones[zoneKey], config);
|
5352
|
-
}
|
5353
|
-
return __spreadProps(__spreadValues({}, data), {
|
5354
|
-
content: yield resolveAllProps(data.content, config),
|
5355
|
-
zones: resolvedZones
|
5356
|
-
});
|
5357
|
-
});
|
5358
5333
|
// Annotate the CommonJS export names for ESM import in node:
|
5359
5334
|
0 && (module.exports = {
|
5360
5335
|
Button,
|
@@ -5364,8 +5339,7 @@ var resolveData = (data, config) => __async(void 0, null, function* () {
|
|
5364
5339
|
IconButton,
|
5365
5340
|
Puck,
|
5366
5341
|
Render,
|
5367
|
-
dropZoneContext
|
5368
|
-
resolveData
|
5342
|
+
dropZoneContext
|
5369
5343
|
});
|
5370
5344
|
/*! Bundled license information:
|
5371
5345
|
|