@simple-builder/react 1.3.4 → 1.3.6

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.
@@ -0,0 +1,269 @@
1
+ 'use strict';
2
+
3
+ var chunkNUDE6YTK_js = require('./chunk-NUDE6YTK.js');
4
+ var React = require('react');
5
+ var reactSlot = require('@radix-ui/react-slot');
6
+ var classVarianceAuthority = require('class-variance-authority');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
27
+
28
+ var BuilderContext = React__namespace.createContext(
29
+ null
30
+ );
31
+ var BuilderProvider = (props) => {
32
+ const url = props.url ?? "/api/simple-builder";
33
+ const [content, setContent] = React__namespace.useState(
34
+ props.content ?? []
35
+ );
36
+ const getItem = React__namespace.useCallback(
37
+ (id) => {
38
+ return findRecursive(content, (item) => item.id === id);
39
+ },
40
+ [content]
41
+ );
42
+ const patchItem = React__namespace.useCallback(
43
+ (id, patch) => {
44
+ setContent(
45
+ (content2) => mapRecursive(content2, (item) => {
46
+ if (item.id === id) {
47
+ return {
48
+ ...item,
49
+ ...patch
50
+ };
51
+ }
52
+ return item;
53
+ })
54
+ );
55
+ },
56
+ [setContent, mapRecursive]
57
+ );
58
+ const addContent = React__namespace.useCallback(
59
+ (name, container, parent, index = 0) => {
60
+ const component = chunkNUDE6YTK_js.builder.getComponent(name);
61
+ if (!component) {
62
+ throw new Error(`[simple-builder]: Component "${name}" not found`);
63
+ }
64
+ const entry = {
65
+ id: crypto.randomUUID(),
66
+ component: component.name,
67
+ ...parent && { parent },
68
+ ...component.inputs && {
69
+ props: component.inputs.reduce(
70
+ (acc, input) => ({
71
+ ...acc,
72
+ [input.name]: input.defaultValue
73
+ }),
74
+ {}
75
+ )
76
+ },
77
+ ...component.defaultStyles && {
78
+ styles: component.defaultStyles
79
+ }
80
+ };
81
+ if (!parent) {
82
+ setContent((content2) => chunkNUDE6YTK_js.insertAt(content2, index, entry));
83
+ return;
84
+ }
85
+ setContent(
86
+ (content2) => mapRecursive(content2, (item) => {
87
+ if (item.id === parent) {
88
+ return {
89
+ ...item,
90
+ content: {
91
+ ...item.content,
92
+ [container]: chunkNUDE6YTK_js.insertAt(item.content?.[container], index, entry)
93
+ }
94
+ };
95
+ }
96
+ return item;
97
+ })
98
+ );
99
+ },
100
+ [setContent, mapRecursive]
101
+ );
102
+ const deleteContent = React__namespace.useCallback(
103
+ (id) => setContent((prev) => filterRecursive(prev, (item) => item.id !== id)),
104
+ [setContent, filterRecursive]
105
+ );
106
+ const bringUp = React__namespace.useCallback(
107
+ (id) => {
108
+ setContent(
109
+ (content2) => mapRecursive(content2, (item, index, arr) => {
110
+ if (item.id === id && index > 0) {
111
+ return arr[index - 1];
112
+ }
113
+ if (arr[index + 1]?.id === id) {
114
+ return arr[index + 1];
115
+ }
116
+ return item;
117
+ })
118
+ );
119
+ },
120
+ [setContent, mapRecursive]
121
+ );
122
+ const bringDown = React__namespace.useCallback(
123
+ (id) => {
124
+ setContent(
125
+ (content2) => mapRecursive(content2, (item, index, arr) => {
126
+ if (item.id === id && index < arr.length - 1) {
127
+ return arr[index + 1];
128
+ }
129
+ if (arr[index - 1]?.id === id) {
130
+ return arr[index - 1];
131
+ }
132
+ return item;
133
+ })
134
+ );
135
+ },
136
+ [setContent, mapRecursive]
137
+ );
138
+ const save = React__namespace.useCallback(async () => {
139
+ const slug = window.location.pathname;
140
+ try {
141
+ await fetch(`${url}/page/update`, {
142
+ method: "POST",
143
+ body: JSON.stringify({
144
+ slug,
145
+ content
146
+ })
147
+ });
148
+ alert("Pagina opgeslagen!");
149
+ } catch (e) {
150
+ console.error("[simple-builder]: Failed to save content", e);
151
+ alert("Er is iets fout gegaan. Bekijk de console voor meer info.");
152
+ }
153
+ }, [content]);
154
+ return /* @__PURE__ */ React__namespace.createElement(
155
+ BuilderContext.Provider,
156
+ {
157
+ value: {
158
+ url,
159
+ content,
160
+ setContent,
161
+ getItem,
162
+ patchItem,
163
+ addContent,
164
+ bringUp,
165
+ bringDown,
166
+ deleteContent,
167
+ save
168
+ }
169
+ },
170
+ props.children
171
+ );
172
+ };
173
+ var useBuilder = () => {
174
+ const context = React__namespace.useContext(BuilderContext);
175
+ if (!context) {
176
+ throw new Error(
177
+ "[simple-builder]: useBuilder must be used within a BuilderProvider"
178
+ );
179
+ }
180
+ return context;
181
+ };
182
+ var filterRecursive = (items, predicate, key = "content") => {
183
+ return items.filter(predicate).map((item) => ({
184
+ ...item,
185
+ ...item[key] && {
186
+ [key]: Object.entries(item[key] ?? {}).reduce(
187
+ (acc, [name, content]) => ({
188
+ ...acc,
189
+ [name]: filterRecursive(content, predicate, key)
190
+ }),
191
+ {}
192
+ )
193
+ }
194
+ }));
195
+ };
196
+ var mapRecursive = (items, predicate, key = "content") => {
197
+ return items.map(predicate).map((item) => ({
198
+ ...item,
199
+ ...item[key] && {
200
+ [key]: Object.entries(item[key] ?? {}).reduce(
201
+ (acc, [name, content]) => ({
202
+ ...acc,
203
+ [name]: mapRecursive(content, predicate, key)
204
+ }),
205
+ {}
206
+ )
207
+ }
208
+ }));
209
+ };
210
+ var findRecursive = (items, predicate, key = "content") => {
211
+ for (const item of items) {
212
+ if (predicate(item)) {
213
+ return item;
214
+ }
215
+ if (item[key]) {
216
+ const keys = Object.keys(item[key] ?? {});
217
+ for (const x of keys) {
218
+ const found = findRecursive(item[key][x], predicate, key);
219
+ if (found) {
220
+ return found;
221
+ }
222
+ }
223
+ }
224
+ }
225
+ };
226
+ var buttonVariants = classVarianceAuthority.cva(
227
+ "sb:inline-flex sb:items-center sb:justify-center sb:gap-2 sb:whitespace-nowrap sb:rounded-md sb:text-sm sb:font-medium sb:transition-colors sb:focus-visible:outline-hidden sb:focus-visible:ring-1 sb:focus-visible:ring-ring sb:disabled:pointer-events-none sb:disabled:opacity-50 sb:[&_svg]:pointer-events-none sb:[&_svg]:size-4 sb:[&_svg]:shrink-0",
228
+ {
229
+ variants: {
230
+ variant: {
231
+ default: "sb:bg-primary sb:text-primary-foreground sb:shadow sb:hover:bg-primary/90",
232
+ destructive: "sb:bg-destructive sb:text-destructive-foreground sb:shadow-sm sb:hover:bg-destructive/90",
233
+ outline: "sb:border sb:border-input sb:bg-background sb:shadow-sm sb:hover:bg-accent sb:hover:text-accent-foreground",
234
+ secondary: "sb:bg-secondary sb:text-secondary-foreground sb:shadow-sm sb:hover:bg-secondary/80",
235
+ ghost: "sb:hover:bg-accent sb:hover:text-accent-foreground",
236
+ link: "sb:text-primary sb:underline-offset-4 sb:hover:underline"
237
+ },
238
+ size: {
239
+ default: "sb:h-9 sb:px-4 sb:py-2",
240
+ sm: "sb:h-8 sb:rounded-md sb:px-3 sb:text-xs",
241
+ lg: "sb:h-10 sb:rounded-md sb:px-8",
242
+ icon: "sb:h-9 sb:w-9"
243
+ }
244
+ },
245
+ defaultVariants: {
246
+ variant: "default",
247
+ size: "default"
248
+ }
249
+ }
250
+ );
251
+ var Button = React__namespace.forwardRef(
252
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
253
+ const Comp = asChild ? reactSlot.Slot : "button";
254
+ return /* @__PURE__ */ React__namespace.createElement(
255
+ Comp,
256
+ {
257
+ className: chunkNUDE6YTK_js.cn(buttonVariants({ variant, size, className })),
258
+ ref,
259
+ ...props
260
+ }
261
+ );
262
+ }
263
+ );
264
+ Button.displayName = "Button";
265
+
266
+ exports.BuilderProvider = BuilderProvider;
267
+ exports.Button = Button;
268
+ exports.buttonVariants = buttonVariants;
269
+ exports.useBuilder = useBuilder;
@@ -0,0 +1,244 @@
1
+ import { cn, builder, insertAt } from './chunk-6GCUWI4L.mjs';
2
+ import * as React from 'react';
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { cva } from 'class-variance-authority';
5
+
6
+ var BuilderContext = React.createContext(
7
+ null
8
+ );
9
+ var BuilderProvider = (props) => {
10
+ const url = props.url ?? "/api/simple-builder";
11
+ const [content, setContent] = React.useState(
12
+ props.content ?? []
13
+ );
14
+ const getItem = React.useCallback(
15
+ (id) => {
16
+ return findRecursive(content, (item) => item.id === id);
17
+ },
18
+ [content]
19
+ );
20
+ const patchItem = React.useCallback(
21
+ (id, patch) => {
22
+ setContent(
23
+ (content2) => mapRecursive(content2, (item) => {
24
+ if (item.id === id) {
25
+ return {
26
+ ...item,
27
+ ...patch
28
+ };
29
+ }
30
+ return item;
31
+ })
32
+ );
33
+ },
34
+ [setContent, mapRecursive]
35
+ );
36
+ const addContent = React.useCallback(
37
+ (name, container, parent, index = 0) => {
38
+ const component = builder.getComponent(name);
39
+ if (!component) {
40
+ throw new Error(`[simple-builder]: Component "${name}" not found`);
41
+ }
42
+ const entry = {
43
+ id: crypto.randomUUID(),
44
+ component: component.name,
45
+ ...parent && { parent },
46
+ ...component.inputs && {
47
+ props: component.inputs.reduce(
48
+ (acc, input) => ({
49
+ ...acc,
50
+ [input.name]: input.defaultValue
51
+ }),
52
+ {}
53
+ )
54
+ },
55
+ ...component.defaultStyles && {
56
+ styles: component.defaultStyles
57
+ }
58
+ };
59
+ if (!parent) {
60
+ setContent((content2) => insertAt(content2, index, entry));
61
+ return;
62
+ }
63
+ setContent(
64
+ (content2) => mapRecursive(content2, (item) => {
65
+ if (item.id === parent) {
66
+ return {
67
+ ...item,
68
+ content: {
69
+ ...item.content,
70
+ [container]: insertAt(item.content?.[container], index, entry)
71
+ }
72
+ };
73
+ }
74
+ return item;
75
+ })
76
+ );
77
+ },
78
+ [setContent, mapRecursive]
79
+ );
80
+ const deleteContent = React.useCallback(
81
+ (id) => setContent((prev) => filterRecursive(prev, (item) => item.id !== id)),
82
+ [setContent, filterRecursive]
83
+ );
84
+ const bringUp = React.useCallback(
85
+ (id) => {
86
+ setContent(
87
+ (content2) => mapRecursive(content2, (item, index, arr) => {
88
+ if (item.id === id && index > 0) {
89
+ return arr[index - 1];
90
+ }
91
+ if (arr[index + 1]?.id === id) {
92
+ return arr[index + 1];
93
+ }
94
+ return item;
95
+ })
96
+ );
97
+ },
98
+ [setContent, mapRecursive]
99
+ );
100
+ const bringDown = React.useCallback(
101
+ (id) => {
102
+ setContent(
103
+ (content2) => mapRecursive(content2, (item, index, arr) => {
104
+ if (item.id === id && index < arr.length - 1) {
105
+ return arr[index + 1];
106
+ }
107
+ if (arr[index - 1]?.id === id) {
108
+ return arr[index - 1];
109
+ }
110
+ return item;
111
+ })
112
+ );
113
+ },
114
+ [setContent, mapRecursive]
115
+ );
116
+ const save = React.useCallback(async () => {
117
+ const slug = window.location.pathname;
118
+ try {
119
+ await fetch(`${url}/page/update`, {
120
+ method: "POST",
121
+ body: JSON.stringify({
122
+ slug,
123
+ content
124
+ })
125
+ });
126
+ alert("Pagina opgeslagen!");
127
+ } catch (e) {
128
+ console.error("[simple-builder]: Failed to save content", e);
129
+ alert("Er is iets fout gegaan. Bekijk de console voor meer info.");
130
+ }
131
+ }, [content]);
132
+ return /* @__PURE__ */ React.createElement(
133
+ BuilderContext.Provider,
134
+ {
135
+ value: {
136
+ url,
137
+ content,
138
+ setContent,
139
+ getItem,
140
+ patchItem,
141
+ addContent,
142
+ bringUp,
143
+ bringDown,
144
+ deleteContent,
145
+ save
146
+ }
147
+ },
148
+ props.children
149
+ );
150
+ };
151
+ var useBuilder = () => {
152
+ const context = React.useContext(BuilderContext);
153
+ if (!context) {
154
+ throw new Error(
155
+ "[simple-builder]: useBuilder must be used within a BuilderProvider"
156
+ );
157
+ }
158
+ return context;
159
+ };
160
+ var filterRecursive = (items, predicate, key = "content") => {
161
+ return items.filter(predicate).map((item) => ({
162
+ ...item,
163
+ ...item[key] && {
164
+ [key]: Object.entries(item[key] ?? {}).reduce(
165
+ (acc, [name, content]) => ({
166
+ ...acc,
167
+ [name]: filterRecursive(content, predicate, key)
168
+ }),
169
+ {}
170
+ )
171
+ }
172
+ }));
173
+ };
174
+ var mapRecursive = (items, predicate, key = "content") => {
175
+ return items.map(predicate).map((item) => ({
176
+ ...item,
177
+ ...item[key] && {
178
+ [key]: Object.entries(item[key] ?? {}).reduce(
179
+ (acc, [name, content]) => ({
180
+ ...acc,
181
+ [name]: mapRecursive(content, predicate, key)
182
+ }),
183
+ {}
184
+ )
185
+ }
186
+ }));
187
+ };
188
+ var findRecursive = (items, predicate, key = "content") => {
189
+ for (const item of items) {
190
+ if (predicate(item)) {
191
+ return item;
192
+ }
193
+ if (item[key]) {
194
+ const keys = Object.keys(item[key] ?? {});
195
+ for (const x of keys) {
196
+ const found = findRecursive(item[key][x], predicate, key);
197
+ if (found) {
198
+ return found;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ };
204
+ var buttonVariants = cva(
205
+ "sb:inline-flex sb:items-center sb:justify-center sb:gap-2 sb:whitespace-nowrap sb:rounded-md sb:text-sm sb:font-medium sb:transition-colors sb:focus-visible:outline-hidden sb:focus-visible:ring-1 sb:focus-visible:ring-ring sb:disabled:pointer-events-none sb:disabled:opacity-50 sb:[&_svg]:pointer-events-none sb:[&_svg]:size-4 sb:[&_svg]:shrink-0",
206
+ {
207
+ variants: {
208
+ variant: {
209
+ default: "sb:bg-primary sb:text-primary-foreground sb:shadow sb:hover:bg-primary/90",
210
+ destructive: "sb:bg-destructive sb:text-destructive-foreground sb:shadow-sm sb:hover:bg-destructive/90",
211
+ outline: "sb:border sb:border-input sb:bg-background sb:shadow-sm sb:hover:bg-accent sb:hover:text-accent-foreground",
212
+ secondary: "sb:bg-secondary sb:text-secondary-foreground sb:shadow-sm sb:hover:bg-secondary/80",
213
+ ghost: "sb:hover:bg-accent sb:hover:text-accent-foreground",
214
+ link: "sb:text-primary sb:underline-offset-4 sb:hover:underline"
215
+ },
216
+ size: {
217
+ default: "sb:h-9 sb:px-4 sb:py-2",
218
+ sm: "sb:h-8 sb:rounded-md sb:px-3 sb:text-xs",
219
+ lg: "sb:h-10 sb:rounded-md sb:px-8",
220
+ icon: "sb:h-9 sb:w-9"
221
+ }
222
+ },
223
+ defaultVariants: {
224
+ variant: "default",
225
+ size: "default"
226
+ }
227
+ }
228
+ );
229
+ var Button = React.forwardRef(
230
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
231
+ const Comp = asChild ? Slot : "button";
232
+ return /* @__PURE__ */ React.createElement(
233
+ Comp,
234
+ {
235
+ className: cn(buttonVariants({ variant, size, className })),
236
+ ref,
237
+ ...props
238
+ }
239
+ );
240
+ }
241
+ );
242
+ Button.displayName = "Button";
243
+
244
+ export { BuilderProvider, Button, buttonVariants, useBuilder };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { createElement } from 'react';
2
3
  import * as _simple_builder_server from '@simple-builder/server';
3
4
  import { BuilderContent as BuilderContent$1, ContentItem } from '@simple-builder/server';
4
5
 
@@ -36,12 +37,17 @@ type BuildContainerProps$1 = {
36
37
  };
37
38
  };
38
39
 
39
- declare const builder: {
40
- register: (component: any, config: Omit<Component, "component">) => void;
41
- getComponents: () => Component[];
42
- getComponent: (name: string) => Component | undefined;
43
- bindComponent: ({ content, ...block }: ContentItem, edit?: boolean) => React.FunctionComponentElement<any>;
44
- };
40
+ declare class Builder {
41
+ private static instance;
42
+ private components;
43
+ private constructor();
44
+ static getInstance(): Builder;
45
+ register(component: Component["component"], config: Omit<Component, "component">): void;
46
+ getComponents(): Component[];
47
+ getComponent(name: string): Component | undefined;
48
+ bindComponent({ content, ...block }: ContentItem, edit?: boolean): ReturnType<typeof createElement>;
49
+ }
50
+ declare const builder: Builder;
45
51
 
46
52
  type StaticContentProps = {
47
53
  content?: BuilderContent$1;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { createElement } from 'react';
2
3
  import * as _simple_builder_server from '@simple-builder/server';
3
4
  import { BuilderContent as BuilderContent$1, ContentItem } from '@simple-builder/server';
4
5
 
@@ -36,12 +37,17 @@ type BuildContainerProps$1 = {
36
37
  };
37
38
  };
38
39
 
39
- declare const builder: {
40
- register: (component: any, config: Omit<Component, "component">) => void;
41
- getComponents: () => Component[];
42
- getComponent: (name: string) => Component | undefined;
43
- bindComponent: ({ content, ...block }: ContentItem, edit?: boolean) => React.FunctionComponentElement<any>;
44
- };
40
+ declare class Builder {
41
+ private static instance;
42
+ private components;
43
+ private constructor();
44
+ static getInstance(): Builder;
45
+ register(component: Component["component"], config: Omit<Component, "component">): void;
46
+ getComponents(): Component[];
47
+ getComponent(name: string): Component | undefined;
48
+ bindComponent({ content, ...block }: ContentItem, edit?: boolean): ReturnType<typeof createElement>;
49
+ }
50
+ declare const builder: Builder;
45
51
 
46
52
  type StaticContentProps = {
47
53
  content?: BuilderContent$1;
package/dist/index.js CHANGED
@@ -1,23 +1,23 @@
1
1
  'use strict';
2
2
 
3
- var chunk7X5S5JRE_js = require('./chunk-7X5S5JRE.js');
4
- var chunkLEIASP7E_js = require('./chunk-LEIASP7E.js');
3
+ var chunkNZ4ZQMIS_js = require('./chunk-NZ4ZQMIS.js');
4
+ var chunkNUDE6YTK_js = require('./chunk-NUDE6YTK.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "BuilderContent", {
9
9
  enumerable: true,
10
- get: function () { return chunk7X5S5JRE_js.BuilderContent; }
10
+ get: function () { return chunkNZ4ZQMIS_js.BuilderContent; }
11
11
  });
12
12
  Object.defineProperty(exports, "StaticContent", {
13
13
  enumerable: true,
14
- get: function () { return chunk7X5S5JRE_js.StaticContent; }
14
+ get: function () { return chunkNZ4ZQMIS_js.StaticContent; }
15
15
  });
16
16
  Object.defineProperty(exports, "BuildContainer", {
17
17
  enumerable: true,
18
- get: function () { return chunkLEIASP7E_js.BuildContainer; }
18
+ get: function () { return chunkNUDE6YTK_js.BuildContainer; }
19
19
  });
20
20
  Object.defineProperty(exports, "builder", {
21
21
  enumerable: true,
22
- get: function () { return chunkLEIASP7E_js.builder; }
22
+ get: function () { return chunkNUDE6YTK_js.builder; }
23
23
  });
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export { BuilderContent, StaticContent } from './chunk-X5GVLHI2.mjs';
2
- export { BuildContainer, builder } from './chunk-TQQ4WVQU.mjs';
1
+ export { BuilderContent, StaticContent } from './chunk-F5JWY4CM.mjs';
2
+ export { BuildContainer, builder } from './chunk-6GCUWI4L.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simple-builder/react",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "private": false,
5
5
  "description": "React package for the simple builder package.",
6
6
  "repository": "https://github.com/pieter-berkel/simple-builder.git",
@@ -59,7 +59,7 @@
59
59
  "tailwind-merge": "^2.2.0",
60
60
  "tailwind-variants": "^0.1.20",
61
61
  "zod": "^3.22.4",
62
- "@simple-builder/server": "1.3.4"
62
+ "@simple-builder/server": "1.3.6"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "react": ">=16.8.0",