@measured/puck 0.6.2 → 0.7.1-canary.9b15c6b

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 CHANGED
@@ -16,6 +16,7 @@ Render the editor:
16
16
  ```jsx
17
17
  // Editor.jsx
18
18
  import { Puck } from "@measured/puck";
19
+ import "@measured/puck/dist/index.css";
19
20
 
20
21
  // Create puck component config
21
22
  const config = {
@@ -34,7 +35,10 @@ const config = {
34
35
  };
35
36
 
36
37
  // Describe the initial data
37
- const initialData = {};
38
+ const initialData = {
39
+ content: [],
40
+ root: {},
41
+ };
38
42
 
39
43
  // Save the data to your database
40
44
  const save = (data) => {};
@@ -82,7 +86,7 @@ Puck can be configured to work with plugins. Plugins can extend the functionalit
82
86
 
83
87
  ### Official plugins
84
88
 
85
- - [`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.
89
+ - [`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.
86
90
 
87
91
  ### Developing a plugin
88
92
 
@@ -110,6 +114,37 @@ const myPlugin = {
110
114
  };
111
115
  ```
112
116
 
117
+ ## Custom fields
118
+
119
+ Puck supports custom fields using the `custom` field type and `render` method.
120
+
121
+ In this example, we optionally add the `<FieldLabel>` component to add a label:
122
+
123
+ ```tsx
124
+ import { FieldLabel } from "@measured/puck";
125
+
126
+ export const MyComponent: ComponentConfig = {
127
+ fields: {
128
+ myField: {
129
+ type: "custom",
130
+ render: ({ field, name, onChange, value }) => {
131
+ return (
132
+ <FieldLabel label={field.label || name}>
133
+ <input
134
+ placeholder="Enter text..."
135
+ type="text"
136
+ name={name}
137
+ defaultValue={value}
138
+ onChange={(e) => onChange(e.currentTarget.value)}
139
+ ></input>
140
+ </FieldLabel>
141
+ );
142
+ },
143
+ },
144
+ },
145
+ };
146
+ ```
147
+
113
148
  ## Reference
114
149
 
115
150
  ### `<Puck>`
@@ -152,7 +187,7 @@ The `Config` object describes which components Puck should render, how they shou
152
187
 
153
188
  A `Field` represents a user input field shown in the Puck interface.
154
189
 
155
- - **type** (`text` | `textarea` | `number` | `select` | `radio` | `external` | `array`): The input type to render
190
+ - **type** (`text` | `textarea` | `number` | `select` | `radio` | `external` | `array` | `custom`): The input type to render
156
191
  - **label** (`text` [optional]): A label for the input. Will use the key if not provided.
157
192
  - **arrayFields** (`object`): Object describing sub-fields for items in an `array` input
158
193
  - **[fieldName]** (`Field`): The Field objects describing the input data for each item
@@ -163,6 +198,12 @@ A `Field` represents a user input field shown in the Puck interface.
163
198
  - **value** (`string` | `number` | `boolean`)
164
199
  - **adaptor** (`Adaptor`): Content adaptor if using the `external` input type
165
200
  - **adaptorParams** (`object`): Paramaters passed to the adaptor
201
+ - **render** (`Component`): Render a custom field. Receives the props:
202
+ - **field** (`Field`): Field configuration
203
+ - **name** (`string`): Name of the field
204
+ - **value** (`any`): Value for the field
205
+ - **onChange** (`(value: any) => void`): Callback to change the value
206
+ - **readOnly** (`boolean` | `undefined`): Whether or not the field should be in readOnly mode
166
207
 
167
208
  ### `Data`
168
209
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ReactNode, ReactElement } from 'react';
1
+ import { ReactElement, ReactNode } from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
4
  type Adaptor<AdaptorParams = {}> = {
@@ -10,7 +10,7 @@ type Field<Props extends {
10
10
  } = {
11
11
  [key: string]: any;
12
12
  }> = {
13
- type: "text" | "textarea" | "number" | "select" | "array" | "external" | "radio";
13
+ type: "text" | "textarea" | "number" | "select" | "array" | "external" | "radio" | "custom";
14
14
  label?: string;
15
15
  adaptor?: Adaptor;
16
16
  adaptorParams?: object;
@@ -19,6 +19,13 @@ type Field<Props extends {
19
19
  };
20
20
  getItemSummary?: (item: Props, index?: number) => string;
21
21
  defaultItemProps?: Props;
22
+ render?: (props: {
23
+ field: Field;
24
+ name: string;
25
+ value: any;
26
+ onChange: (value: any) => void;
27
+ readOnly?: boolean;
28
+ }) => ReactElement;
22
29
  options?: {
23
30
  label: string;
24
31
  value: string | number | boolean;
@@ -149,4 +156,10 @@ declare function Render({ config, data }: {
149
156
  data: Data;
150
157
  }): react_jsx_runtime.JSX.Element;
151
158
 
152
- export { Adaptor, Button, ComponentConfig, Config, Data, DefaultComponentProps, DefaultRootProps, Field, Fields, IconButton, Puck, Render };
159
+ declare const FieldLabel: ({ children, icon, label, }: {
160
+ children?: ReactNode;
161
+ icon?: ReactNode;
162
+ label: string;
163
+ }) => react_jsx_runtime.JSX.Element;
164
+
165
+ export { Adaptor, Button, ComponentConfig, Config, Data, DefaultComponentProps, DefaultRootProps, Field, FieldLabel, Fields, IconButton, Puck, Render };
package/dist/index.js CHANGED
@@ -147,6 +147,7 @@ var require_classnames = __commonJS({
147
147
  var core_exports = {};
148
148
  __export(core_exports, {
149
149
  Button: () => Button,
150
+ FieldLabel: () => FieldLabel,
150
151
  IconButton: () => IconButton,
151
152
  Puck: () => Puck,
152
153
  Render: () => Render
@@ -562,6 +563,19 @@ var replace = (list, index, newItem) => {
562
563
  var import_react_feather3 = require("react-feather");
563
564
  var import_jsx_runtime6 = require("react/jsx-runtime");
564
565
  var getClassName5 = get_class_name_factory_default("Input", styles_module_default3);
566
+ var FieldLabel = ({
567
+ children,
568
+ icon,
569
+ label
570
+ }) => {
571
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
572
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: getClassName5("label"), children: [
573
+ icon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: getClassName5("labelIcon") }),
574
+ label
575
+ ] }),
576
+ children
577
+ ] });
578
+ };
565
579
  var InputOrGroup = ({
566
580
  name,
567
581
  field,
@@ -734,6 +748,18 @@ var InputOrGroup = ({
734
748
  )) })
735
749
  ] }) });
736
750
  }
751
+ if (field.type === "custom") {
752
+ if (!field.render) {
753
+ return null;
754
+ }
755
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: getClassName5(), children: field.render({
756
+ field,
757
+ name,
758
+ value,
759
+ onChange,
760
+ readOnly
761
+ }) });
762
+ }
737
763
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: getClassName5({ readOnly }), children: [
738
764
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: getClassName5("label"), children: [
739
765
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: getClassName5("labelIcon"), children: [
@@ -1275,6 +1301,11 @@ function Puck({
1275
1301
  id: "puck-drop-zone",
1276
1302
  children: [
1277
1303
  data.content.map((item, i) => {
1304
+ var _a2;
1305
+ const Render2 = config.components[item.type] ? config.components[item.type].render : () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { padding: 48, textAlign: "center" }, children: [
1306
+ "No configuration for ",
1307
+ item.type
1308
+ ] });
1278
1309
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1279
1310
  DraggableComponent,
1280
1311
  {
@@ -1304,17 +1335,11 @@ function Puck({
1304
1335
  setData(newData);
1305
1336
  e.stopPropagation();
1306
1337
  },
1307
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { zoom: 0.75 }, children: config.components[item.type] ? config.components[item.type].render(__spreadProps(__spreadValues(__spreadValues({}, config.components[item.type].defaultProps), item.props), {
1308
- editMode: true
1309
- })) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1310
- "div",
1311
- {
1312
- style: { padding: 48, textAlign: "center" },
1313
- children: [
1314
- "No configuration for ",
1315
- item.type
1316
- ]
1317
- }
1338
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { zoom: 0.75 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1339
+ Render2,
1340
+ __spreadProps(__spreadValues(__spreadValues({}, (_a2 = config.components[item.type]) == null ? void 0 : _a2.defaultProps), item.props), {
1341
+ editMode: true
1342
+ })
1318
1343
  ) })
1319
1344
  },
1320
1345
  item.props.id
@@ -1461,6 +1486,7 @@ function Render({ config, data }) {
1461
1486
  // Annotate the CommonJS export names for ESM import in node:
1462
1487
  0 && (module.exports = {
1463
1488
  Button,
1489
+ FieldLabel,
1464
1490
  IconButton,
1465
1491
  Puck,
1466
1492
  Render
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@measured/puck",
3
- "version": "0.6.2",
3
+ "version": "0.7.1-canary.9b15c6b",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",