@measured/puck 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # puck
2
+
3
+ The self-hosted, drag and drop editor for React.
4
+
5
+ - 🖱️ **Drag and drop**: Visual editing for your existing React component library
6
+ - 🌐 **Integrations**: Load your content from a 3rd party headless CMS
7
+ - ✍️ **Inline editing**: Author content directly via puck for convenience
8
+ - ⭐️ **No vendor lock-in**: Self-host or integrate with your existing application
9
+
10
+ ![puck](https://github.com/measuredco/puck/assets/985961/10257000-ece7-4728-9e71-6204d2f1540e)
11
+
12
+ [See demo](https://puck-demo-six.vercel.app/custom/edit)
13
+
14
+ ## Example
15
+
16
+ ```jsx
17
+ import { Puck } from "puck";
18
+
19
+ // Create puck component config
20
+ const config = {
21
+ HeadingBlock: {
22
+ fields: {
23
+ children: {
24
+ type: "text",
25
+ },
26
+ },
27
+ render: ({ children }) => {
28
+ return <h1>{children}</h1>;
29
+ },
30
+ },
31
+ };
32
+
33
+ // Describe the initial data
34
+ const data = {
35
+ content: [
36
+ {
37
+ type: "HeadingBlock",
38
+ props: {
39
+ title: "Home Page",
40
+ },
41
+ },
42
+ ],
43
+ };
44
+
45
+ // Render Puck
46
+ export function Page() {
47
+ return <Puck config={config} data={data} />;
48
+ }
49
+ ```
50
+
51
+ ## Installation
52
+
53
+ Install the package
54
+
55
+ ```
56
+ npm i puck --save
57
+ ```
58
+
59
+ Or generate a puck application using a recipe
60
+
61
+ ```sh
62
+ npx create-puck-app my-app
63
+ ```
64
+
65
+ ## Recipes
66
+
67
+ Puck is a React component that can be easily integrated into your existing application. We also provide helpful recipes for common use cases:
68
+
69
+ - [**next**](https://github.com/measuredco/puck/tree/main/recipes/next): Next.js app example
70
+
71
+ ## Plugins
72
+
73
+ Puck can be configured to work with plugins. Plugins can extend the functionality to support novel functionality.
74
+
75
+ ### Official plugins
76
+
77
+ - [`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 accessiblity standards.
78
+
79
+ ### Developing a plugin
80
+
81
+ The plugin API follows a React paradigm. Each plugin passed to the Puck editor can provide three functions:
82
+
83
+ #### `Plugin`
84
+
85
+ - `renderPage` (`Component`): Render the root node of the preview content
86
+ - `renderPageFields` (`Component`): Render the page fields
87
+ - `renderFields` (`Component`): Render the fields for the currently selected component
88
+
89
+ Each render function receives the `children` prop, which you should render to show the page or fields, and the `data` prop, which can be used to read the data model for the page.
90
+
91
+ #### Example
92
+
93
+ Here's a basic plugin that renders a "My plugin" heading in the page field area:
94
+
95
+ ```jsx
96
+ const myPlugin = {
97
+ renderPageFields: (props) => (
98
+ <div>
99
+ {props.children}
100
+
101
+ <h2>My plugin</h2>
102
+ </div>
103
+ ),
104
+ };
105
+ ```
106
+
107
+ ## Reference
108
+
109
+ ### `Config`
110
+
111
+ The `Config` object describes which components Puck should render, how they should render and which inputs are available to them.
112
+
113
+ - **page** (`object`)
114
+ - **fields** (`object`):
115
+ - **title** (`Field`): A mandatory field for the page title.
116
+ - **[fieldName]** (`Field`): User defined fields, used to describe the input data stored in the `page` key.
117
+ - **render** (`Component`): Render a React component at the root of your component tree. Useful for defining context providers.
118
+ - **components** (`object`): Definitions for each of the components you want to show in the visual editor
119
+ - **[componentName]** (`object`)
120
+ - **fields** (`Field`): The Field objects describing the input data stored against this component.
121
+ - **render** (`Component`): Render function for your React component. Receives props as defined in fields.
122
+ - **defaultProps** (`object` [optional]): Default props to pass to your component. Will show in fields.
123
+
124
+ ### `Field`
125
+
126
+ A `Field` represents a user input field shown in the Puck interface.
127
+
128
+ - **type** (`text` | `textarea` | `number` | `select` | `radio` | `external` | `array`): The input type to render
129
+ - **label** (`text` [optional]): A label for the input. Will use the key if not provided.
130
+ - **arrayFields** (`object`): Object describing sub-fields for items in an `array` input
131
+ - **[fieldName]** (`Field`): The Field objects describing the input data for each item
132
+ - **getItemSummary** (`(object, number) => string` [optional]): Function to get the name of each item when using an `array` field type
133
+ - **defaultItemProps** (`object` [optional]): Default props to pass to each new item added, when using a `array` field type
134
+ - **options** (`object[]`): array of items to render for select-type inputs
135
+ - **label** (`string`)
136
+ - **value** (`string`)
137
+
138
+ ### `Data`
139
+
140
+ The `Data` object stores the state of a page.
141
+
142
+ - **page** (`object`):
143
+ - **title** (string): Page title
144
+ - **[prop]** (string): User defined data from page fields
145
+ - **content** (`object[]`):
146
+ - **type** (string): Component name
147
+ - **props** (object):
148
+ - **[prop]** (string): User defined data from component fields
149
+
150
+ ## License
151
+
152
+ MIT © [Measured Co.](https://github.com/measuredco)
package/dist/index.css CHANGED
@@ -140,13 +140,14 @@
140
140
  /* styles/global.css */
141
141
 
142
142
  /* css-module:/home/runner/work/puck/puck/packages/core/components/DraggableComponent/styles.module.css/#css-module-data */
143
- ._DraggableComponent_10y0g_1 {
143
+ ._DraggableComponent_1sbv6_1 {
144
144
  position: relative;
145
145
  }
146
- ._DraggableComponent-contents_10y0g_5 {
146
+ ._DraggableComponent-contents_1sbv6_5 {
147
+ border: 1px inset transparent;
147
148
  position: relative;
148
149
  }
149
- ._DraggableComponent-overlay_10y0g_9 {
150
+ ._DraggableComponent-overlay_1sbv6_10 {
150
151
  display: none;
151
152
  height: 100%;
152
153
  width: 100%;
@@ -155,22 +156,22 @@
155
156
  z-index: 1;
156
157
  font-family: var(--puck-font-stack);
157
158
  }
158
- ._DraggableComponent_10y0g_1:hover ._DraggableComponent-overlay_10y0g_9 {
159
+ ._DraggableComponent_1sbv6_1:hover ._DraggableComponent-overlay_1sbv6_10 {
159
160
  display: block;
160
161
  background-color: #cdcdcd50;
161
162
  box-shadow: inset 0 0 0 4px var(--puck-color-azure-6);
162
163
  }
163
- ._DraggableComponent--isModifierHeld_10y0g_25:hover ._DraggableComponent-overlay_10y0g_9 {
164
+ ._DraggableComponent--isModifierHeld_1sbv6_26:hover ._DraggableComponent-overlay_1sbv6_10 {
164
165
  display: none;
165
166
  }
166
- ._DraggableComponent--isSelected_10y0g_29 ._DraggableComponent-overlay_10y0g_9 {
167
+ ._DraggableComponent--isSelected_1sbv6_30 ._DraggableComponent-overlay_1sbv6_10 {
167
168
  box-shadow: inset 0 0 0 4px var(--puck-color-azure-6);
168
169
  display: block;
169
170
  }
170
- ._DraggableComponent-actions_10y0g_34 {
171
+ ._DraggableComponent-actions_1sbv6_35 {
171
172
  display: none;
172
173
  }
173
- ._DraggableComponent_10y0g_1:hover ._DraggableComponent-actions_10y0g_34 {
174
+ ._DraggableComponent_1sbv6_1:hover ._DraggableComponent-actions_1sbv6_35 {
174
175
  position: absolute;
175
176
  right: 0;
176
177
  padding: 8px;
@@ -180,7 +181,7 @@
180
181
  gap: 4px;
181
182
  border: 1px solid var(--puck-color-grey-8);
182
183
  }
183
- ._DraggableComponent-actionsLabel_10y0g_49 {
184
+ ._DraggableComponent-actionsLabel_1sbv6_50 {
184
185
  display: flex;
185
186
  justify-content: center;
186
187
  align-items: center;
@@ -189,14 +190,14 @@
189
190
  margin-right: 8px;
190
191
  border-right: 1px solid var(--puck-color-grey-8);
191
192
  }
192
- ._DraggableComponent-action_10y0g_34 {
193
+ ._DraggableComponent-action_1sbv6_35 {
193
194
  background: transparent;
194
195
  border: none;
195
196
  color: var(--puck-color-grey-2);
196
197
  padding: 8px;
197
198
  border-radius: 4px;
198
199
  }
199
- ._DraggableComponent-action_10y0g_34:hover {
200
+ ._DraggableComponent-action_1sbv6_35:hover {
200
201
  background: var(--puck-color-grey-9);
201
202
  color: var(--puck-color-blue);
202
203
  cursor: pointer;
@@ -317,22 +318,34 @@
317
318
  }
318
319
 
319
320
  /* css-module:/home/runner/work/puck/puck/packages/core/components/InputOrGroup/styles.module.css/#css-module-data */
320
- ._Input_1vwgb_1 {
321
+ ._Input_y3456_1 {
322
+ background: white;
323
+ color: var(--puck-color-grey-3);
324
+ padding: 16px;
325
+ border-radius: 4px;
321
326
  display: block;
322
327
  font-family: var(--puck-font-stack);
323
328
  }
324
- ._Input_1vwgb_1 * {
329
+ ._Input_y3456_1 ._Input_y3456_1 {
330
+ padding: 0px;
331
+ }
332
+ ._Input_y3456_1 * {
325
333
  box-sizing: border-box;
326
334
  }
327
- ._Input_1vwgb_1 + ._Input_1vwgb_1 {
335
+ ._Input_y3456_1 + ._Input_y3456_1 {
328
336
  margin-top: 8px;
329
337
  }
330
- ._Input-label_1vwgb_14 {
331
- margin-bottom: 4px;
338
+ ._Input-label_y3456_22 {
339
+ display: flex;
340
+ padding-bottom: 12px;
332
341
  font-size: var(--puck-font-size-xxs);
333
342
  font-weight: 500;
334
343
  }
335
- ._Input-input_1vwgb_20 {
344
+ ._Input-labelIcon_y3456_29 {
345
+ color: var(--puck-color-grey-6);
346
+ margin-right: 4px;
347
+ }
348
+ ._Input-input_y3456_34 {
336
349
  border-width: 1px;
337
350
  border-style: solid;
338
351
  border-color: var(--puck-color-grey-8);
@@ -341,7 +354,7 @@
341
354
  padding: 12px 16px;
342
355
  width: 100%;
343
356
  }
344
- ._Input_1vwgb_1 select {
357
+ ._Input_y3456_1 select {
345
358
  appearance: none;
346
359
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23c3c3c3'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
347
360
  background-size: 12px;
@@ -349,34 +362,40 @@
349
362
  background-repeat: no-repeat;
350
363
  background-color: white;
351
364
  }
352
- ._Input--readOnly_1vwgb_41 ._Input-input_1vwgb_20 {
365
+ ._Input--readOnly_y3456_55 ._Input-input_y3456_34 {
353
366
  background-color: var(--puck-color-grey-9);
354
367
  border-color: var(--puck-color-grey-8);
355
368
  }
356
- ._Input-input_1vwgb_20:hover {
369
+ ._Input-input_y3456_34:hover {
357
370
  border-color: var(--puck-color-neutral-3);
358
371
  }
359
- ._Input-group_1vwgb_50 {
372
+ ._Input-array_y3456_64 {
360
373
  background: white;
361
- border-bottom: var(--puck-color-grey-8) solid 1px;
362
374
  }
363
- ._Input-group_1vwgb_50 > summary {
364
- padding: 16px;
375
+ ._Input-array_y3456_64 > summary {
376
+ color: var(--puck-color-grey-3);
377
+ font-size: var(--puck-font-size-xxs);
378
+ padding: 12px 16px;
365
379
  position: relative;
366
380
  }
367
- ._Input-group_1vwgb_50 > summary:hover {
381
+ ._Input-array_y3456_64 > summary:hover {
368
382
  cursor: pointer;
369
383
  color: var(--puck-color-blue);
370
384
  }
371
- ._Input-group_1vwgb_50 > fieldset {
385
+ ._Input-array_y3456_64 > fieldset {
372
386
  border: none;
373
- border-top: var(--puck-color-grey-8) solid 1px;
374
387
  margin: 0;
375
- padding: 16px;
376
388
  }
377
- ._Input-group_1vwgb_50 ._Input-action_1vwgb_72 {
389
+ ._Input-array_y3456_64 > fieldset ._Input_y3456_1 + ._Input-array_y3456_64 > fieldset ._Input_y3456_1 {
390
+ margin-top: 16px;
391
+ }
392
+ ._Input-array_y3456_64 > fieldset ._Input-label_y3456_22 {
393
+ padding-bottom: 4px;
394
+ }
395
+ ._Input-array_y3456_64 ._Input-action_y3456_92 {
378
396
  background: transparent;
379
397
  border: none;
398
+ border-radius: 4px;
380
399
  color: var(--puck-color-grey-2);
381
400
  display: none;
382
401
  padding: 8px;
@@ -384,15 +403,15 @@
384
403
  right: 4px;
385
404
  top: 4px;
386
405
  }
387
- ._Input-group_1vwgb_50 summary:hover ._Input-action_1vwgb_72 {
406
+ ._Input-array_y3456_64 summary:hover ._Input-action_y3456_92 {
388
407
  display: block;
389
408
  }
390
- ._Input-group_1vwgb_50 ._Input-action_1vwgb_72:hover {
409
+ ._Input-array_y3456_64 ._Input-action_y3456_92:hover {
391
410
  background: var(--puck-color-grey-9);
392
411
  color: var(--puck-color-blue);
393
412
  cursor: pointer;
394
413
  }
395
- ._Input-addButton_1vwgb_93 {
414
+ ._Input-addButton_y3456_114 {
396
415
  background-color: white;
397
416
  border: none;
398
417
  color: var(--puck-color-blue);
@@ -400,29 +419,44 @@
400
419
  width: 100%;
401
420
  margin: 0;
402
421
  padding: 12px 16px;
422
+ text-align: left;
403
423
  }
404
- ._Input-addButton_1vwgb_93:hover {
424
+ ._Input-addButton_y3456_114:hover {
405
425
  background: var(--puck-color-grey-9);
406
426
  }
407
- ._Input-item_1vwgb_107 {
408
- border: 1px solid var(--puck-color-grey-8);
409
- border-radius: 4px;
410
- margin-top: 4px;
427
+ ._Input-item_y3456_129 {
411
428
  overflow: hidden;
412
429
  }
413
- ._Input-radioGroup_1vwgb_114 {
414
- margin-bottom: 8px;
415
- margin-top: 8px;
416
- }
417
- ._Input-radioGroupItems_1vwgb_119 {
430
+ ._Input-radioGroupItems_y3456_133 {
418
431
  display: flex;
419
- gap: 8px;
432
+ border: 1px solid var(--puck-color-grey-7);
433
+ border-radius: 4px;
420
434
  flex-wrap: wrap;
435
+ overflow: hidden;
421
436
  }
422
- ._Input-radio_1vwgb_114 {
423
- display: flex;
424
- align-items: center;
425
- gap: 4px;
437
+ ._Input-radio_y3456_133 {
438
+ border-right: 1px solid var(--puck-color-grey-7);
439
+ flex-grow: 1;
440
+ }
441
+ ._Input-radio_y3456_133:last-of-type {
442
+ border-right: none;
443
+ }
444
+ ._Input-radioInner_y3456_150 {
445
+ font-size: var(--puck-font-size-xxxs);
446
+ padding: 8px 12px;
447
+ text-align: center;
448
+ }
449
+ ._Input-radioInner_y3456_150:hover {
450
+ background-color: var(--puck-color-azure-8);
451
+ cursor: pointer;
452
+ }
453
+ ._Input-radio_y3456_133 input:checked ~ ._Input-radioInner_y3456_150 {
454
+ background-color: var(--puck-color-azure-4);
455
+ color: white;
456
+ font-weight: 500;
457
+ }
458
+ ._Input-radio_y3456_133 input {
459
+ display: none;
426
460
  }
427
461
 
428
462
  /* css-module:/home/runner/work/puck/puck/packages/core/components/ComponentList/styles.module.css/#css-module-data */
@@ -549,27 +583,34 @@
549
583
  }
550
584
 
551
585
  /* css-module:/home/runner/work/puck/puck/packages/core/components/SidebarSection/styles.module.css/#css-module-data */
552
- ._SidebarSection_jsf8x_1:last-of-type ._SidebarSection-content_jsf8x_1 {
553
- border-bottom: none;
554
- height: 100%;
586
+ ._SidebarSection_yd8db_1 {
587
+ display: flex;
588
+ flex-direction: column;
555
589
  }
556
- ._SidebarSection-title_jsf8x_6 {
590
+ ._SidebarSection_yd8db_1:last-of-type {
591
+ flex-grow: 1;
592
+ }
593
+ ._SidebarSection-title_yd8db_10 {
557
594
  background: white;
558
595
  padding: 16px;
559
596
  border-bottom: 1px solid var(--puck-color-grey-8);
560
597
  }
561
- ._SidebarSection-title_jsf8x_6:hover {
598
+ ._SidebarSection-title_yd8db_10:hover {
562
599
  opacity: 0.6;
563
600
  cursor: pointer;
564
601
  }
565
- ._SidebarSection-content_jsf8x_1 {
602
+ ._SidebarSection-content_yd8db_21 {
566
603
  border-bottom: 1px solid var(--puck-color-grey-8);
567
604
  padding: 16px;
568
605
  }
569
- ._SidebarSection_jsf8x_1 > summary {
606
+ ._SidebarSection_yd8db_1:last-of-type ._SidebarSection-content_yd8db_21 {
607
+ border-bottom: none;
608
+ flex-grow: 1;
609
+ }
610
+ ._SidebarSection_yd8db_1 > summary {
570
611
  list-style: none;
571
612
  }
572
- ._SidebarSection_jsf8x_1 > summary::-webkit-details-marker {
613
+ ._SidebarSection_yd8db_1 > summary::-webkit-details-marker {
573
614
  display: none;
574
615
  }
575
616
 
package/dist/index.d.ts CHANGED
@@ -10,11 +10,11 @@ type Field<Props extends {
10
10
  } = {
11
11
  [key: string]: any;
12
12
  }> = {
13
- type: "text" | "textarea" | "number" | "select" | "group" | "external" | "radio";
13
+ type: "text" | "textarea" | "number" | "select" | "array" | "external" | "radio";
14
14
  label?: string;
15
15
  adaptor?: Adaptor;
16
16
  adaptorParams?: object;
17
- groupFields?: {
17
+ arrayFields?: {
18
18
  [SubPropName in keyof Props]: Field<Props[SubPropName]>;
19
19
  };
20
20
  getItemSummary?: (item: Props, index: number) => string;
package/dist/index.js CHANGED
@@ -188,7 +188,7 @@ var import_react_beautiful_dnd2 = require("react-beautiful-dnd");
188
188
 
189
189
  // css-module:/home/runner/work/puck/puck/packages/core/components/DraggableComponent/styles.module.css#css-module
190
190
  init_react_import();
191
- var styles_module_default = { "DraggableComponent": "_DraggableComponent_10y0g_1", "DraggableComponent-contents": "_DraggableComponent-contents_10y0g_5", "DraggableComponent-overlay": "_DraggableComponent-overlay_10y0g_9", "DraggableComponent--isModifierHeld": "_DraggableComponent--isModifierHeld_10y0g_25", "DraggableComponent--isSelected": "_DraggableComponent--isSelected_10y0g_29", "DraggableComponent-actions": "_DraggableComponent-actions_10y0g_34", "DraggableComponent-actionsLabel": "_DraggableComponent-actionsLabel_10y0g_49", "DraggableComponent-action": "_DraggableComponent-action_10y0g_34" };
191
+ var styles_module_default = { "DraggableComponent": "_DraggableComponent_1sbv6_1", "DraggableComponent-contents": "_DraggableComponent-contents_1sbv6_5", "DraggableComponent-overlay": "_DraggableComponent-overlay_1sbv6_10", "DraggableComponent--isModifierHeld": "_DraggableComponent--isModifierHeld_1sbv6_26", "DraggableComponent--isSelected": "_DraggableComponent--isSelected_1sbv6_30", "DraggableComponent-actions": "_DraggableComponent-actions_1sbv6_35", "DraggableComponent-actionsLabel": "_DraggableComponent-actionsLabel_1sbv6_50", "DraggableComponent-action": "_DraggableComponent-action_1sbv6_35" };
192
192
 
193
193
  // lib/get-class-name-factory.ts
194
194
  init_react_import();
@@ -383,7 +383,7 @@ var ExternalInput = ({
383
383
 
384
384
  // css-module:/home/runner/work/puck/puck/packages/core/components/InputOrGroup/styles.module.css#css-module
385
385
  init_react_import();
386
- var styles_module_default3 = { "Input": "_Input_1vwgb_1", "Input-label": "_Input-label_1vwgb_14", "Input-input": "_Input-input_1vwgb_20", "Input--readOnly": "_Input--readOnly_1vwgb_41", "Input-group": "_Input-group_1vwgb_50", "Input-action": "_Input-action_1vwgb_72", "Input-addButton": "_Input-addButton_1vwgb_93", "Input-item": "_Input-item_1vwgb_107", "Input-radioGroup": "_Input-radioGroup_1vwgb_114", "Input-radioGroupItems": "_Input-radioGroupItems_1vwgb_119", "Input-radio": "_Input-radio_1vwgb_114" };
386
+ var styles_module_default3 = { "Input": "_Input_y3456_1", "Input-label": "_Input-label_y3456_22", "Input-labelIcon": "_Input-labelIcon_y3456_29", "Input-input": "_Input-input_y3456_34", "Input--readOnly": "_Input--readOnly_y3456_55", "Input-array": "_Input-array_y3456_64", "Input-action": "_Input-action_y3456_92", "Input-addButton": "_Input-addButton_y3456_114", "Input-item": "_Input-item_y3456_129", "Input-radioGroupItems": "_Input-radioGroupItems_y3456_133", "Input-radio": "_Input-radio_y3456_133", "Input-radioInner": "_Input-radioInner_y3456_150" };
387
387
 
388
388
  // lib/index.ts
389
389
  init_react_import();
@@ -429,14 +429,17 @@ var InputOrGroup = ({
429
429
  onChange,
430
430
  readOnly
431
431
  }) => {
432
- if (field.type === "group") {
433
- if (!field.groupFields) {
432
+ if (field.type === "array") {
433
+ if (!field.arrayFields) {
434
434
  return null;
435
435
  }
436
436
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3(), children: [
437
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("b", { className: getClassName3("label"), children: label || name }),
437
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("b", { className: getClassName3("label"), children: [
438
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("labelIcon"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.List, { size: 16 }) }),
439
+ label || name
440
+ ] }),
438
441
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("item"), children: [
439
- Array.isArray(value) ? value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { className: getClassName3("group"), children: [
442
+ Array.isArray(value) ? value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { className: getClassName3("array"), children: [
440
443
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("summary", { children: [
441
444
  field.getItemSummary ? field.getItemSummary(item, i) : `Item #${i}`,
442
445
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -448,12 +451,12 @@ var InputOrGroup = ({
448
451
  existingValue.splice(i, 1);
449
452
  onChange(existingValue);
450
453
  },
451
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.Trash, {})
454
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.Trash, { size: 21 })
452
455
  }
453
456
  )
454
457
  ] }),
455
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("fieldset", { children: Object.keys(field.groupFields).map((fieldName) => {
456
- const subField = field.groupFields[fieldName];
458
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("fieldset", { children: Object.keys(field.arrayFields).map((fieldName) => {
459
+ const subField = field.arrayFields[fieldName];
457
460
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
458
461
  InputOrGroup,
459
462
  {
@@ -477,7 +480,7 @@ var InputOrGroup = ({
477
480
  const existingValue = value || [];
478
481
  onChange([...existingValue, field.defaultItemProps || {}]);
479
482
  },
480
- children: "Add item"
483
+ children: "+ Add item"
481
484
  }
482
485
  )
483
486
  ] })
@@ -497,7 +500,10 @@ var InputOrGroup = ({
497
500
  return null;
498
501
  }
499
502
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: getClassName3(), children: [
500
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("label"), children: label || name }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("label"), children: [
504
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("labelIcon"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.ChevronDown, { size: 16 }) }),
505
+ label || name
506
+ ] }),
501
507
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
502
508
  "select",
503
509
  {
@@ -518,7 +524,10 @@ var InputOrGroup = ({
518
524
  }
519
525
  if (field.type === "textarea") {
520
526
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: getClassName3({ readOnly }), children: [
521
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("label"), children: label || name }),
527
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("label"), children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("labelIcon"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.Type, { size: 16 }) }),
529
+ label || name
530
+ ] }),
522
531
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
523
532
  "textarea",
524
533
  {
@@ -537,8 +546,11 @@ var InputOrGroup = ({
537
546
  if (!field.options) {
538
547
  return null;
539
548
  }
540
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("radioGroup"), children: [
541
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("label"), children: field.label || name }),
549
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("radioGroup"), children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("label"), children: [
551
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("labelIcon"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.CheckCircle, { size: 16 }) }),
552
+ field.label || name
553
+ ] }),
542
554
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("radioGroupItems"), children: field.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
543
555
  "label",
544
556
  {
@@ -555,15 +567,21 @@ var InputOrGroup = ({
555
567
  defaultChecked: value === option.value
556
568
  }
557
569
  ),
558
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: option.label || option.value })
570
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("radioInner"), children: option.label || option.value })
559
571
  ]
560
572
  },
561
573
  option.label + option.value
562
574
  )) })
563
- ] });
575
+ ] }) });
564
576
  }
565
577
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: getClassName3({ readOnly }), children: [
566
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: getClassName3("label"), children: label || name }),
578
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("label"), children: [
579
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: getClassName3("labelIcon"), children: [
580
+ field.type === "text" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.Type, { size: 16 }),
581
+ field.type === "number" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_feather2.Hash, { size: 16 })
582
+ ] }),
583
+ label || name
584
+ ] }),
567
585
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
568
586
  "input",
569
587
  {
@@ -760,7 +778,9 @@ var usePlaceholderStyle = () => {
760
778
  if (destinationIndex > 0) {
761
779
  const children = Array.from(targetListElement.children).filter((item) => item !== draggedDOM).slice(0, destinationIndex);
762
780
  clientY = children.reduce(
763
- (total, item) => total + item.clientHeight + parseInt(window.getComputedStyle(item).marginTop.replace("px", "")),
781
+ (total, item) => total + item.clientHeight + parseInt(window.getComputedStyle(item).marginTop.replace("px", "")) + parseInt(
782
+ window.getComputedStyle(item).marginBottom.replace("px", "")
783
+ ),
764
784
  0
765
785
  );
766
786
  }
@@ -780,7 +800,7 @@ init_react_import();
780
800
 
781
801
  // css-module:/home/runner/work/puck/puck/packages/core/components/SidebarSection/styles.module.css#css-module
782
802
  init_react_import();
783
- var styles_module_default6 = { "SidebarSection": "_SidebarSection_jsf8x_1", "SidebarSection-content": "_SidebarSection-content_jsf8x_1", "SidebarSection-title": "_SidebarSection-title_jsf8x_6" };
803
+ var styles_module_default6 = { "SidebarSection": "_SidebarSection_yd8db_1", "SidebarSection-title": "_SidebarSection-title_yd8db_10", "SidebarSection-content": "_SidebarSection-content_yd8db_21" };
784
804
 
785
805
  // components/Heading/index.tsx
786
806
  init_react_import();
@@ -810,9 +830,10 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
810
830
  var getClassName8 = get_class_name_factory_default("SidebarSection", styles_module_default6);
811
831
  var SidebarSection = ({
812
832
  children,
813
- title
833
+ title,
834
+ background
814
835
  }) => {
815
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("details", { className: getClassName8({}), open: true, children: [
836
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("details", { className: getClassName8(), open: true, style: { background }, children: [
816
837
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("summary", { className: getClassName8("title"), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Heading, { rank: 2, size: "xs", children: title }) }),
817
838
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: getClassName8("content"), children })
818
839
  ] });
@@ -945,7 +966,7 @@ function Puck({
945
966
  style: {
946
967
  display: "grid",
947
968
  gridTemplateAreas: '"header header header" "left editor right"',
948
- gridTemplateColumns: "256px auto 256px",
969
+ gridTemplateColumns: "288px auto 288px",
949
970
  gridTemplateRows: "min-content auto",
950
971
  height: "100vh",
951
972
  position: "fixed",
@@ -1003,28 +1024,42 @@ function Puck({
1003
1024
  style: {
1004
1025
  gridArea: "left",
1005
1026
  background: "var(--puck-color-grey-10)",
1006
- overflowY: "auto"
1027
+ overflowY: "auto",
1028
+ display: "flex",
1029
+ flexDirection: "column"
1007
1030
  },
1008
1031
  children: [
1009
1032
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarSection, { title: "Components", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComponentList, { config }) }),
1010
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarSection, { title: "Outline", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OutlineList, { children: data.content.map((item, i) => {
1011
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1012
- OutlineList.Item,
1033
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SidebarSection, { title: "Outline", children: [
1034
+ data.content.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1035
+ "div",
1013
1036
  {
1014
- onClick: () => {
1015
- setSelectedIndex(i);
1016
- const id = data.content[i].props.id;
1017
- scrollIntoView(
1018
- document.querySelector(
1019
- `[data-rbd-drag-handle-draggable-id="draggable-${id}"]`
1020
- )
1021
- );
1037
+ style: {
1038
+ textAlign: "center",
1039
+ color: "var(--puck-color-grey-6)"
1022
1040
  },
1023
- children: item.type
1024
- },
1025
- i
1026
- );
1027
- }) }) })
1041
+ children: "Add items to your page"
1042
+ }
1043
+ ),
1044
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OutlineList, { children: data.content.map((item, i) => {
1045
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1046
+ OutlineList.Item,
1047
+ {
1048
+ onClick: () => {
1049
+ setSelectedIndex(i);
1050
+ const id = data.content[i].props.id;
1051
+ scrollIntoView(
1052
+ document.querySelector(
1053
+ `[data-rbd-drag-handle-draggable-id="draggable-${id}"]`
1054
+ )
1055
+ );
1056
+ },
1057
+ children: item.type
1058
+ },
1059
+ i
1060
+ );
1061
+ }) })
1062
+ ] })
1028
1063
  ]
1029
1064
  }
1030
1065
  ),
@@ -1123,11 +1158,14 @@ function Puck({
1123
1158
  background: "var(--puck-color-grey-10)",
1124
1159
  overflowY: "auto",
1125
1160
  gridArea: "right",
1126
- fontFamily: "var(--puck-font-stack)"
1161
+ fontFamily: "var(--puck-font-stack)",
1162
+ display: "flex",
1163
+ flexDirection: "column"
1127
1164
  },
1128
1165
  children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FieldWrapper, { data, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1129
1166
  SidebarSection,
1130
1167
  {
1168
+ background: "var(--puck-color-grey-9)",
1131
1169
  title: selectedIndex !== null ? data.content[selectedIndex].type : "Page",
1132
1170
  children: Object.keys(fields).map((fieldName) => {
1133
1171
  var _a2, _b2, _c, _d;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@measured/puck",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -8,7 +8,8 @@
8
8
  "scripts": {
9
9
  "lint": "eslint \"**/*.ts*\"",
10
10
  "build": "rm -rf dist && tsup index.ts",
11
- "prepare": "yarn build"
11
+ "prepare": "cp ../../README.md . && yarn build",
12
+ "postpublish": "rm README.md"
12
13
  },
13
14
  "files": [
14
15
  "dist"