@measured/puck 0.11.3 → 0.12.0-canary.01939fc

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # puck
1
+ # Puck
2
2
 
3
3
  The self-hosted, drag and drop editor for React.
4
4
 
@@ -17,25 +17,30 @@ The self-hosted, drag and drop editor for React.
17
17
  </a>
18
18
  </p>
19
19
 
20
- ## Features
20
+ ## Demo
21
21
 
22
- - 🖱️ **Drag and drop**: Visual editing for your existing React component library
23
- - 🌐 **Integrations**: Load your content from a 3rd party headless CMS
24
- - ✍️ **Inline editing**: Author content directly via puck for convenience
25
- - ⭐️ **No vendor lock-in**: Self-host or integrate with your existing application
22
+ Visit https://demo.puckeditor.com/edit to try the demo.
26
23
 
27
- [See demo](https://puck-editor-demo.vercel.app/edit)
24
+ ## Documentation
28
25
 
29
- ## Example
26
+ Visit https://puckeditor.com to view the full documentation.
27
+
28
+ ## Quick start
29
+
30
+ Install the package:
31
+
32
+ ```sh
33
+ npm i @measured/puck --save # or npx create-puck-app my-app
34
+ ```
30
35
 
31
36
  Render the editor:
32
37
 
33
38
  ```jsx
34
39
  // Editor.jsx
35
40
  import { Puck } from "@measured/puck";
36
- import "@measured/puck/dist/index.css";
41
+ import "@measured/puck/puck.css";
37
42
 
38
- // Create puck component config
43
+ // Create Puck component config
39
44
  const config = {
40
45
  components: {
41
46
  HeadingBlock: {
@@ -71,465 +76,24 @@ Render the page:
71
76
  ```jsx
72
77
  // Page.jsx
73
78
  import { Render } from "@measured/puck";
74
- import "@measured/puck/dist/index.css";
79
+ import "@measured/puck/puck.css";
75
80
 
76
81
  export function Page() {
77
82
  return <Render config={config} data={data} />;
78
83
  }
79
84
  ```
80
85
 
81
- ## Installation
82
-
83
- Install the package
84
-
85
- ```
86
- npm i @measured/puck --save
87
- ```
86
+ ## Recipes
88
87
 
89
- Or generate a puck application using a recipe
88
+ Use `create-puck-app` to quickly spin up a a pre-configured app based on our provided [recipes](https://github.com/measuredco/puck/tree/main/recipes):
90
89
 
91
90
  ```sh
92
91
  npx create-puck-app my-app
93
92
  ```
94
93
 
95
- ## Recipes
96
-
97
- Puck is a React component that can be easily integrated into your existing application. We also provide helpful recipes for common use cases:
98
-
99
- - [**next**](https://github.com/measuredco/puck/tree/main/recipes/next): Next.js app example
100
-
101
- ## Plugins
102
-
103
- Puck can be configured to work with plugins. Plugins can extend the functionality to support novel functionality.
104
-
105
- ### Official plugins
106
-
107
- - [`heading-analyzer`](https://github.com/measuredco/puck/tree/main/packages/plugin-heading-analyzer): Analyze the heading outline of your page and be warned when you're not respecting WCAG 2 accessibility standards.
108
-
109
- ### Developing a plugin
110
-
111
- The plugin API follows a React paradigm. Each plugin passed to the Puck editor can provide three functions:
112
-
113
- - `renderRoot` (`Component`): Render the root node of the preview content
114
- - `renderRootFields` (`Component`): Render the root fields
115
- - `renderFields` (`Component`): Render the fields for the currently selected component
116
- - `renderComponentList` (`Component`): Render the component list
117
-
118
- Each render function receives three props:
119
-
120
- - **children** (`ReactNode`): The normal contents of the root or field. You must render this if provided.
121
- - **state** (`AppState`): The current application state, including data and UI state
122
- - **dispatch** (`(action: PuckAction) => void`): The Puck dispatcher, used for making data changes or updating the UI. See the [action definitions](https://github.com/measuredco/puck/blob/main/packages/core/reducer/actions.tsx) for a full reference of available mutations.
123
-
124
- #### Example
125
-
126
- Here's an example plugin that creates a button to toggle the left side-bar:
127
-
128
- ```jsx
129
- const myPlugin = {
130
- renderRootFields: ({ children, dispatch, state }) => (
131
- <div>
132
- {children}
133
-
134
- <button
135
- onClick={() => {
136
- dispatch({
137
- type: "setUi",
138
- ui: { leftSideBarVisible: !state.ui.leftSideBarVisible },
139
- });
140
- }}
141
- >
142
- Toggle side-bar
143
- </button>
144
- </div>
145
- ),
146
- };
147
- ```
148
-
149
- ## Custom fields
150
-
151
- Puck supports custom fields using the `custom` field type and `render` method.
152
-
153
- In this example, we optionally add the `<FieldLabel>` component to add a label:
154
-
155
- ```tsx
156
- import { FieldLabel } from "@measured/puck";
157
-
158
- export const MyComponent: ComponentConfig = {
159
- fields: {
160
- myField: {
161
- type: "custom",
162
- render: ({ field, name, onChange, value }) => {
163
- return (
164
- <FieldLabel label={field.label || name}>
165
- <input
166
- placeholder="Enter text..."
167
- type="text"
168
- name={name}
169
- defaultValue={value}
170
- onChange={(e) => onChange(e.currentTarget.value)}
171
- ></input>
172
- </FieldLabel>
173
- );
174
- },
175
- },
176
- },
177
- };
178
- ```
179
-
180
- ## DropZones
181
-
182
- Puck supports creating complex layouts (like multi-column layouts) using the `<DropZone>` component.
183
-
184
- ### Example
185
-
186
- In this example, we use the `<DropZone>` component to render two nested DropZones within another component:
187
-
188
- ```tsx
189
- import { DropZone } from "@measured/puck";
190
-
191
- export const MyComponent: ComponentConfig = {
192
- render: () => {
193
- return (
194
- <div>
195
- <DropZone zone="first-drop-zone">
196
- <DropZone zone="second-drop-zone">
197
- </div>
198
- )
199
- }
200
- };
201
- ```
202
-
203
- ### Custom root entry points
204
-
205
- You can also do this at the root of your component. This is useful if you have a fixed layout and only want to make certain parts of your page customisable:
206
-
207
- ```tsx
208
- import { DropZone, Config } from "@measured/puck";
209
-
210
- export const config: Config = {
211
- root: {
212
- render: ({ children }) => {
213
- return (
214
- <div>
215
- {/* children renders the default zone. This can be omitted if necessary. */}
216
- {children}
217
-
218
- <div>
219
- <DropZone zone="other-drop-zone">
220
- </div>
221
- </div>
222
- )
223
- }
224
- }
225
- };
226
- ```
227
-
228
- ### The Rules of DropZones
229
-
230
- The current DropZone implementation has certain rules and limitations:
231
-
232
- 1. You can drag from the component list on the LHS into any DropZone
233
- 2. You can drag components between DropZones, so long as those DropZones share a parent (also known as _area_)
234
- 3. You can't drag between DropZones that don't share a parent (or _area_)
235
- 4. Your mouse must be directly over a DropZone for a collision to be detected
236
-
237
- ## External fields
238
-
239
- External fields 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 query data from a third party API:
244
-
245
- ```tsx
246
- const config = {
247
- components: {
248
- HeadingBlock: {
249
- fields: {
250
- myData: {
251
- type: "external",
252
- fetchList: async () => {
253
- const response = await fetch("https://www.example.com/api");
254
-
255
- return {
256
- text: response.json().text,
257
- };
258
- },
259
- },
260
- },
261
- render: ({ myData }) => {
262
- return <h1>{myData.text}</h1>;
263
- },
264
- },
265
- },
266
- };
267
- ```
268
-
269
- When the user interacts with this external field, 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`.
270
-
271
- ## Dynamic prop resolution
272
-
273
- Dynamic prop resolution allows developers to resolve props for components without saving the data to the Puck data model.
274
-
275
- ### resolveData()
276
-
277
- `resolveData` is defined in the component config, and allows the developer to make asynchronous calls to change the [ComponentData](#componentdata) after they've been set by Puck. Receives [ComponentData](#componentdata) and returns [ComponentData](#componentdata).
278
-
279
- #### Examples
280
-
281
- ##### Basic example
282
-
283
- In this example, we remap the `text` prop to the `title` prop and mark the `title` field as read-only.
284
-
285
- ```tsx
286
- const config = {
287
- components: {
288
- HeadingBlock: {
289
- fields: {
290
- text: {
291
- type: "text",
292
- },
293
- title: {
294
- type: "text",
295
- },
296
- },
297
- resolveData: async (props) => {
298
- return {
299
- props: {
300
- title: props.text,
301
- },
302
- readOnly: {
303
- title: true,
304
- },
305
- };
306
- },
307
- render: ({ title }) => {
308
- return <h1>{title}</h1>;
309
- },
310
- },
311
- },
312
- };
313
- ```
314
-
315
- ##### Combining with external fields
316
-
317
- A more advanced pattern is to combine the `resolveData` method with `external` fields to dynamically fetch data when rendering the component.
318
-
319
- ```tsx
320
- const config = {
321
- components: {
322
- HeadingBlock: {
323
- fields: {
324
- myData: {
325
- type: "external",
326
- placeholder: "Select from example.com",
327
- fetchList: async () => {
328
- const response = await fetch("https://www.example.com/api");
329
-
330
- return {
331
- id: response.json().id,
332
- };
333
- },
334
- },
335
- title: {
336
- type: "text",
337
- },
338
- },
339
- resolveData: async (props) => {
340
- if (!myData.id) {
341
- return { props, readOnly: { title: false } };
342
- }
343
-
344
- const latestData = await fetch(
345
- `https://www.example.com/api/${myData.id}`
346
- );
347
-
348
- return {
349
- props: {
350
- title: latestData.json().text,
351
- },
352
- readOnly: {
353
- title: true,
354
- },
355
- };
356
- },
357
- render: ({ title }) => {
358
- return <h1>{title}</h1>;
359
- },
360
- },
361
- },
362
- };
363
- ```
364
-
365
- ### resolveAllData()
366
-
367
- `resolveAllData` is a utility function exported by Puck to enable the developer to run all their `resolveData` methods before rendering the component with `<Render>`.
368
-
369
- If your `resolveData` methods rely on any external APIs, you should run this before rendering your page.
370
-
371
- ```tsx
372
- import { resolveAllData } from "@measured/puck";
373
-
374
- const resolvedData = resolveAllData(data, config);
375
- ```
376
-
377
- ## Reference
378
-
379
- ### `<Puck>`
380
-
381
- The `<Puck>` component renders the Puck editor.
382
-
383
- - **config** (`Config`): Puck component configuration
384
- - **data** (`Data`): Initial data to render
385
- - **onChange** (`(Data) => void` [optional]): Callback that triggers when the user makes a change
386
- - **onPublish** (`(Data) => void` [optional]): Callback that triggers when the user hits the "Publish" button
387
- - **renderComponentList** (`Component` [optional]): Render function for wrapping the component list
388
- - **renderHeader** (`Component` [optional]): Render function for overriding the Puck header component
389
- - **renderHeaderActions** (`Component` [optional]): Render function for overriding the Puck header actions. Use a fragment.
390
- - **headerTitle** (`string` [optional]): Set the title shown in the header title
391
- - **headerPath** (`string` [optional]): Set a path to show after the header title
392
- - **plugins** (`Plugin[]` [optional]): Array of plugins that can be used to enhance Puck
393
-
394
- ### `<Render>`
395
-
396
- The `<Render>` component renders user-facing UI using Puck data.
397
-
398
- - **config** (`Config`): Puck component configuration
399
- - **data** (`Data`): Data to render
400
-
401
- ### `<DropZone>`
402
-
403
- The `<DropZone>` component allows you to create advanced layouts, like multi-columns.
404
-
405
- - **zone** (`string`): Identifier for the zone of your component, unique to the parent component
406
- - **style** (`CSSProperties`): Custom inline styles
407
-
408
- ### `Config`
409
-
410
- The `Config` object describes which components Puck should render, how they should render and which inputs are available to them.
411
-
412
- - **root** (`object`)
413
- - **fields** (`object`):
414
- - **title** (`Field`): Title of the content, typically used for the page title.
415
- - **[fieldName]** (`Field`): User defined fields, used to describe the input data stored in the `root` key.
416
- - **render** (`Component`): Render a React component at the root of your component tree. Useful for defining context providers.
417
- - **resolveData** (`async (data: ComponentData) => ComponentData` [optional]): Function to dynamically change props before rendering the root.
418
- - **components** (`object`): Definitions for each of the components you want to show in the visual editor
419
- - **[componentName]** (`object`)
420
- - **fields** (`Field`): The Field objects describing the input data stored against this component.
421
- - **render** (`Component`): Render function for your React component. Receives props as defined in fields.
422
- - **defaultProps** (`object` [optional]): Default props to pass to your component. Will show in fields.
423
- - **resolveData** (`async (data: ComponentData) => ComponentData` [optional]): Function to dynamically change props before rendering the component.
424
- - **categories** (`object`): Component categories for rendering in the side bar or restricting in DropZones
425
- - **[categoryName]** (`object`)
426
- - **components** (`sting[]`, [optional]): Array containing the names of components in this category
427
- - **title** (`sting`, [optional]): Title of the category
428
- - **visible** (`boolean`, [optional]): Whether or not the category should be visible in the side bar
429
- - **defaultExpanded** (`boolean`, [optional]): Whether or not the category should be expanded in the side bar by default
430
-
431
- ### `Field`
432
-
433
- A `Field` represents a user input field shown in the Puck interface.
434
-
435
- ### All Fields
436
-
437
- - **label** (`text` [optional]): A label for the input. Will use the key if not provided.
438
-
439
- ### Text Fields
440
-
441
- - **type** (`"text"`)
442
-
443
- ### Textarea Fields
444
-
445
- - **type** (`"textarea"`)
446
-
447
- ### Number Fields
448
-
449
- - **type** (`"number"`)
450
-
451
- ### Select Fields
452
-
453
- - **type** (`"select"`)
454
- - **options** (`object[]`): array of items to render
455
- - **label** (`string`)
456
- - **value** (`string` | `number` | `boolean`)
457
-
458
- ### Radio Fields
459
-
460
- - **type** (`"radio"`)
461
- - **options** (`object[]`): array of items to render
462
- - **label** (`string`)
463
- - **value** (`string` | `number` | `boolean`)
464
-
465
- ### Array Fields
466
-
467
- - **type** (`"array"`)
468
- - **arrayFields** (`object`): Object describing sub-fields for each item
469
- - **[fieldName]** (`Field`): The Field objects describing the input data for each item
470
- - **getItemSummary** (`(object, number) => string` [optional]): Function to get the label of each item
471
- - **defaultItemProps** (`object` [optional]): Default props to pass to each new item added, when using a `array` field type
472
-
473
- ### External Fields
474
-
475
- External fields can be used to load content from an external content repository, like Strapi.js.
476
-
477
- - **type** (`"external"`)
478
- - **placeholder** (`string`): A placeholder for the external field button
479
- - **fetchList** (`() => object`): Fetch content from a third-party API and return an array
480
- - **mapProp** (`(selectedItem: object) => object`): Map the selected item into another shape
481
-
482
- ### Custom Fields
483
-
484
- - **type** (`"custom"`)
485
- - **render** (`Component`): Render a custom field. Receives the props:
486
- - **field** (`Field`): Field configuration
487
- - **name** (`string`): Name of the field
488
- - **value** (`any`): Value for the field
489
- - **onChange** (`(value: any) => void`): Callback to change the value
490
- - **readOnly** (`boolean` | `undefined`): Whether or not the field should be in readOnly mode
491
-
492
- ### `AppState`
493
-
494
- The `AppState` object stores the puck application state.
495
-
496
- - **data** (`Data`): The page data currently being rendered
497
- - **ui** (`object`):
498
- - **leftSideBarVisible** (boolean): Whether or not the left side bar is visible
499
- - **itemSelector** (object): An object describing which item is selected
500
- - **arrayState** (object): An object describing the internal state of array items
501
- - **componentList** (object): An object describing the component list. Similar shape to `Config.categories`.
502
- - **components** (`sting[]`, [optional]): Array containing the names of components in this category
503
- - **title** (`sting`, [optional]): Title of the category
504
- - **visible** (`boolean`, [optional]): Whether or not the category is visible in the side bar
505
- - **expanded** (`boolean`, [optional]): Whether or not the category is expanded in the side bar
506
-
507
- ### `Data`
508
-
509
- The `Data` object stores the puck page data.
510
-
511
- - **root** (`ComponentData`): The component data for the root of your configuration.
512
- - **props** (object): Extends `ComponentData.props`, with some additional props
513
- - **title** (`string`, [optional]): Title of the content, typically used for the page title
514
- - **content** (`ComponentData[]`): Component data for the main content
515
- - **zones** (`object`, [optional]): Component data for all DropZones
516
- **[zoneCompound]** (`ComponentData[]`): Component data for a specific DropZone `zone` within a component instance
517
-
518
- ### `ComponentData`
519
-
520
- - **type** (`string`): Component name
521
- - **props** (`object`):
522
- - **[prop]** (`any`): User defined data from component fields
523
- - **readOnly** (`object`): Object describing which fields on the component are currently read-only. Can use dot-notation for arrays, like `array[1].text` or `array[*].text`.
524
- - **[prop]** (`boolean`): boolean describing whether or not the prop field is read-only
525
-
526
- ### `Plugin`
527
-
528
- Plugins that can be used to enhance Puck.
94
+ Available recipes include:
529
95
 
530
- - **renderRoot** (`Component`): Render the root node of the preview content
531
- - **renderRootFields** (`Component`): Render the root fields
532
- - **renderFields** (`Component`): Render the fields for the currently selected component
96
+ - [**next**](https://github.com/measuredco/puck/tree/main/recipes/next): Next.js 13 app example, using App Router and static page generation
533
97
 
534
98
  ## Hire the Puck team
535
99
 
@@ -0,0 +1,196 @@
1
+ import { CSSProperties, ReactElement, ReactNode } from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ type ItemSelector = {
5
+ index: number;
6
+ zone?: string;
7
+ };
8
+
9
+ type DropZoneProps = {
10
+ zone: string;
11
+ style?: CSSProperties;
12
+ };
13
+ declare function DropZone(props: DropZoneProps): react_jsx_runtime.JSX.Element;
14
+
15
+ type WithPuckProps<Props> = Props & {
16
+ id: string;
17
+ };
18
+ type BaseField = {
19
+ label?: string;
20
+ };
21
+ type TextField = BaseField & {
22
+ type: "text" | "number" | "textarea";
23
+ };
24
+ type SelectField = BaseField & {
25
+ type: "select" | "radio";
26
+ options: {
27
+ label: string;
28
+ value: string | number | boolean;
29
+ }[];
30
+ };
31
+ type ArrayField<Props extends {
32
+ [key: string]: any;
33
+ } = {
34
+ [key: string]: any;
35
+ }> = BaseField & {
36
+ type: "array";
37
+ arrayFields: {
38
+ [SubPropName in keyof Props[0]]: Field<Props[0][SubPropName]>;
39
+ };
40
+ defaultItemProps?: Props[0];
41
+ getItemSummary?: (item: Props[0], index?: number) => string;
42
+ };
43
+ type Adaptor<AdaptorParams = {}, TableShape extends Record<string, any> = {}, PropShape = TableShape> = {
44
+ name: string;
45
+ fetchList: (adaptorParams?: AdaptorParams) => Promise<TableShape[] | null>;
46
+ mapProp?: (value: TableShape) => PropShape;
47
+ };
48
+ type ExternalFieldWithAdaptor<Props extends {
49
+ [key: string]: any;
50
+ } = {
51
+ [key: string]: any;
52
+ }> = BaseField & {
53
+ type: "external";
54
+ placeholder?: string;
55
+ adaptor: Adaptor<any, any, Props>;
56
+ adaptorParams?: object;
57
+ getItemSummary: (item: Props, index?: number) => string;
58
+ };
59
+ type ExternalField<Props extends {
60
+ [key: string]: any;
61
+ } = {
62
+ [key: string]: any;
63
+ }> = BaseField & {
64
+ type: "external";
65
+ placeholder?: string;
66
+ fetchList: () => Promise<any[] | null>;
67
+ mapProp?: (value: any) => Props;
68
+ getItemSummary: (item: Props, index?: number) => string;
69
+ };
70
+ type CustomField<Props extends {
71
+ [key: string]: any;
72
+ } = {
73
+ [key: string]: any;
74
+ }> = BaseField & {
75
+ type: "custom";
76
+ render: (props: {
77
+ field: CustomField;
78
+ name: string;
79
+ value: any;
80
+ onChange: (value: Props) => void;
81
+ readOnly?: boolean;
82
+ }) => ReactElement;
83
+ };
84
+ type Field<Props extends {
85
+ [key: string]: any;
86
+ } = {
87
+ [key: string]: any;
88
+ }> = TextField | SelectField | ArrayField<Props> | ExternalField<Props> | ExternalFieldWithAdaptor<Props> | CustomField;
89
+ type DefaultRootProps = {
90
+ title?: string;
91
+ [key: string]: any;
92
+ };
93
+ type DefaultComponentProps = {
94
+ [key: string]: any;
95
+ editMode?: boolean;
96
+ };
97
+ type Fields<ComponentProps extends DefaultComponentProps = DefaultComponentProps> = {
98
+ [PropName in keyof Omit<Required<ComponentProps>, "children" | "editMode">]: Field<ComponentProps[PropName]>;
99
+ };
100
+ type Content<Props extends {
101
+ [key: string]: any;
102
+ } = {
103
+ [key: string]: any;
104
+ }> = ComponentData<Props>[];
105
+ type PuckComponent<Props extends DefaultComponentProps = DefaultComponentProps> = (props: WithPuckProps<Props & {
106
+ puck: PuckContext;
107
+ }>) => JSX.Element;
108
+ type PuckContext = {
109
+ renderDropZone: typeof DropZone;
110
+ };
111
+ type ComponentConfig<ComponentProps extends DefaultComponentProps = DefaultComponentProps, DefaultProps = ComponentProps, DataShape = ComponentData<ComponentProps>> = {
112
+ render: PuckComponent<ComponentProps>;
113
+ defaultProps?: DefaultProps;
114
+ fields?: Fields<ComponentProps>;
115
+ resolveData?: (data: DataShape, params: {
116
+ changed: Partial<Record<keyof ComponentProps, boolean>>;
117
+ }) => Promise<Partial<ComponentDataWithOptionalProps<ComponentProps>>> | Partial<ComponentDataWithOptionalProps<ComponentProps>>;
118
+ };
119
+ type Category<ComponentName> = {
120
+ components?: ComponentName[];
121
+ title?: string;
122
+ visible?: boolean;
123
+ defaultExpanded?: boolean;
124
+ };
125
+ type Config<Props extends {
126
+ [key: string]: any;
127
+ } = {
128
+ [key: string]: any;
129
+ }, RootProps extends DefaultRootProps = DefaultRootProps, CategoryName extends string = string> = {
130
+ categories?: Record<CategoryName, Category<keyof Props>> & {
131
+ other?: Category<Props>;
132
+ };
133
+ components: {
134
+ [ComponentName in keyof Props]: Omit<ComponentConfig<Props[ComponentName], Props[ComponentName]>, "type">;
135
+ };
136
+ root?: Partial<ComponentConfig<RootProps & {
137
+ children: ReactNode;
138
+ }, Partial<RootProps & {
139
+ children: ReactNode;
140
+ }>, RootDataWithProps<RootProps>>>;
141
+ };
142
+ type BaseData<Props extends {
143
+ [key: string]: any;
144
+ } = {
145
+ [key: string]: any;
146
+ }> = {
147
+ readOnly?: Partial<Record<keyof Props, boolean>>;
148
+ };
149
+ type ComponentData<Props extends DefaultComponentProps = DefaultComponentProps> = {
150
+ type: keyof Props;
151
+ props: WithPuckProps<Props>;
152
+ } & BaseData<Props>;
153
+ type RootDataWithProps<Props extends DefaultRootProps = DefaultRootProps> = {
154
+ props: Props;
155
+ };
156
+ type RootDataWithoutProps<Props extends DefaultRootProps = DefaultRootProps> = Props;
157
+ type RootData<Props extends DefaultRootProps = DefaultRootProps> = BaseData<Props> & Partial<RootDataWithProps<Props>> & Partial<RootDataWithoutProps<Props>>;
158
+ type ComponentDataWithOptionalProps<Props extends {
159
+ [key: string]: any;
160
+ } = {
161
+ [key: string]: any;
162
+ }> = Omit<ComponentData, "props"> & {
163
+ props: Partial<WithPuckProps<Props>>;
164
+ };
165
+ type MappedItem = ComponentData;
166
+ type Data<Props extends DefaultComponentProps = DefaultComponentProps, RootProps extends DefaultRootProps = DefaultRootProps> = {
167
+ root: RootData<RootProps>;
168
+ content: Content<WithPuckProps<Props>>;
169
+ zones?: Record<string, Content<WithPuckProps<Props>>>;
170
+ };
171
+ type ItemWithId = {
172
+ _arrayId: string;
173
+ _originalIndex: number;
174
+ data: any;
175
+ };
176
+ type ArrayState = {
177
+ items: ItemWithId[];
178
+ openId: string;
179
+ };
180
+ type UiState = {
181
+ leftSideBarVisible: boolean;
182
+ itemSelector: ItemSelector | null;
183
+ arrayState: Record<string, ArrayState | undefined>;
184
+ componentList: Record<string, {
185
+ components?: string[];
186
+ title?: string;
187
+ visible?: boolean;
188
+ expanded?: boolean;
189
+ }>;
190
+ };
191
+ type AppState = {
192
+ data: Data;
193
+ ui: UiState;
194
+ };
195
+
196
+ export { AppState as A, BaseField as B, Config as C, Data as D, ExternalFieldWithAdaptor as E, Field as F, ItemSelector as I, MappedItem as M, PuckComponent as P, RootDataWithProps as R, SelectField as S, TextField as T, UiState as U, DefaultRootProps as a, RootData as b, ArrayField as c, Adaptor as d, ExternalField as e, CustomField as f, DefaultComponentProps as g, Fields as h, Content as i, PuckContext as j, ComponentConfig as k, BaseData as l, ComponentData as m, RootDataWithoutProps as n, ItemWithId as o, ArrayState as p, DropZone as q };