@measured/puck 0.11.0-canary.b28404f → 0.11.0-canary.c8c02fd
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.
- 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
|
|