@@ -35,8 +35,6 @@ Add dev dependencies, since there currently seems to be an issue with shadcn/ui
35
35
npm install -D @types/lodash.template @tailwindcss/typography @types/react-syntax-highlighter react-docgen-typescript tailwindcss-animate ts-morph ts-to-zod
36
36
```
37
37
38
-
39
-
40
38
And that's it! You have a UI Builder that you can use to build your UI.
41
39
42
40
## Usage
@@ -82,11 +80,10 @@ const initialLayers: PageLayer[] = [
82
80
children: [
83
81
{
84
82
id: " UzZY6Dp" ,
85
- type: " _text_" ,
86
- name: " Text" ,
87
- text: " Github" ,
88
- textType: " text" ,
83
+ type: " span" ,
84
+ name: " span" ,
89
85
props: {},
86
+ children: " Hello World" ,
90
87
},
91
88
{
92
89
id: " hn3PF6A" ,
@@ -109,7 +106,7 @@ const initialLayers: PageLayer[] = [
109
106
110
107
const App = () => {
111
108
const handleLayersChange = (updatedLayers : PageLayer []) => {
112
- // Here you can save the updated layers to the database
109
+ // Here you can send the updated layers to the backend
113
110
console .log (updatedLayers );
114
111
};
115
112
@@ -218,7 +215,7 @@ Note: This project is an work in progress and the API will change.
218
215
219
216
### Layers
220
217
221
- - ** Layers** are the fundamental units representing components, text, or pages within the UI structure.
218
+ - ** Layers** are the fundamental units representing components or pages within the UI structure.
222
219
- They form a hierarchical tree, allowing for complex and nested UI layouts.
223
220
- Each layer possesses properties and can contain child layers, enabling modular and scalable UI designs.
224
221
@@ -250,25 +247,15 @@ The `layer-store.ts` module defines the essential types used to manage UI layers
250
247
``` ts
251
248
252
249
export type Layer =
253
- | {
254
- id: string ;
255
- name? : string ;
256
- type: keyof typeof componentRegistry ;
257
- props: Record <string , any >;
258
- children: Layer [];
259
- }
260
- | TextLayer
250
+ | ComponentLayer
261
251
| PageLayer ;
262
252
263
- export type ComponentLayer = Exclude <Layer , TextLayer >;
264
-
265
- export type TextLayer = {
253
+ export type ComponentLayer = {
266
254
id: string ;
267
255
name? : string ;
268
- type: ' _text_ ' ;
256
+ type: keyof typeof componentRegistry ;
269
257
props: Record <string , any >;
270
- text: string ;
271
- textType: ' text' | ' markdown' ;
258
+ children: Layer [] | string ;
272
259
};
273
260
274
261
export type PageLayer = {
@@ -277,15 +264,14 @@ export type PageLayer = {
277
264
type: ' _page_' ;
278
265
props: Record <string , any >;
279
266
children: Layer [];
280
- };
267
+ }
281
268
282
269
interface LayerStore {
283
270
pages: PageLayer [];
284
271
selectedLayerId: string | null ;
285
272
selectedPageId: string ;
286
273
initialize: (pages : PageLayer []) => void ;
287
274
addComponentLayer: (layerType : keyof typeof componentRegistry , parentId : string , parentPosition ? : number ) => void ;
288
- addTextLayer: (text : string , textType : ' text' | ' markdown' , parentId : string , parentPosition ? : number ) => void ;
289
275
addPageLayer: (pageId : string ) => void ;
290
276
duplicateLayer: (layerId : string , parentId ? : string ) => void ;
291
277
removeLayer: (layerId : string ) => void ;
@@ -298,9 +284,8 @@ interface LayerStore {
298
284
299
285
```
300
286
301
- - ` Layer ` : A union type representing any possible layer, encompassing component, text, or page layers.
302
- - ` ComponentLayer ` : Represents layers that are components, excluding text layers.
303
- - ` TextLayer ` : Represents layers containing text content. Text layers dont have children.
287
+ - ` Layer ` : A union type representing any possible layer, encompassing component or page layers.
288
+ - ` ComponentLayer ` : Represents layers that are components.
304
289
- ` PageLayer ` : Represents layers that serve as pages containing other layers.
305
290
- ` LayerStore ` : Defines the structure of the state, including pages, selected layer/page IDs, and various actions to manipulate layers.
306
291
@@ -314,7 +299,7 @@ export interface RegistryEntry<T extends ReactComponentType<any>> {
314
299
component? : T ;
315
300
schema: ZodObject <any >;
316
301
from? : string ;
317
- defaultChildren? : (ComponentLayer | TextLayer )[];
302
+ defaultChildren? : (ComponentLayer )[];
318
303
fieldOverrides? : Record <string , FieldConfigFunction >;
319
304
}
320
305
@@ -323,15 +308,15 @@ export type ComponentRegistry = Record<
323
308
RegistryEntry <ReactComponentType <any >>
324
309
>;
325
310
326
- export type FieldConfigFunction = (layer : ComponentLayer | TextLayer ) => FieldConfigItem ;
311
+ export type FieldConfigFunction = (layer : ComponentLayer ) => FieldConfigItem ;
327
312
328
313
export const componentRegistry: ComponentRegistry = {
329
314
// ...YourOtherProjectComponentDefinitions
330
315
... complexComponentDefinitions ,
331
316
... primitiveComponentDefinitions ,
332
317
} as const ;
333
318
334
- export const generateFieldOverrides = (layer : ComponentLayer | TextLayer ): Record <string , FieldConfigItem > => {... }
319
+ export const generateFieldOverrides = (layer : ComponentLayer ): Record <string , FieldConfigItem > => {... }
335
320
336
321
```
337
322
@@ -355,37 +340,50 @@ export const componentRegistry: ComponentRegistry = {
355
340
Button: {
356
341
component: Button ,
357
342
schema: z .object ({
358
- className: z .string ().optional (),
359
- asChild: z .boolean ().optional (),
360
- children: z .any ().optional (),
361
- variant: z .enum ([" default" , " destructive" , " outline" , " secondary" , " ghost" , " link" ]).default (" default" ),
362
- size: z .enum ([" default" , " sm" , " lg" , " icon" ]).default (" default" ),
343
+ className: z .string ().optional (),
344
+ children: z .any ().optional (),
345
+ asChild: z .boolean ().optional (),
346
+ variant: z
347
+ .enum ([
348
+ " default" ,
349
+ " destructive" ,
350
+ " outline" ,
351
+ " secondary" ,
352
+ " ghost" ,
353
+ " link" ,
354
+ ])
355
+ .default (" default" ),
356
+ size: z .enum ([" default" , " sm" , " lg" , " icon" ]).default (" default" ),
363
357
}),
364
358
from: " @/components/ui/button" ,
365
359
defaultChildren: [
366
- {
367
- id: " button-text" ,
368
- type: " _text_" ,
369
- name: " Text" ,
370
- text: " Button" ,
371
- textType: " text" ,
372
- props: {},
373
- },
360
+ {
361
+ id: " button-text" ,
362
+ type: " span" ,
363
+ name: " span" ,
364
+ props: {},
365
+ children: " Button" ,
366
+ } satisfies ComponentLayer ,
374
367
],
375
368
fieldOverrides: {
376
- className : (layer ) => classNameFieldOverrides (layer ),
377
- children : (layer ) => childrenFieldOverrides (layer ),
378
- },
379
- },
369
+ className :(layer )=> classNameFieldOverrides (layer ),
370
+ children : (layer )=> childrenFieldOverrides (layer )
371
+ }
372
+ }
380
373
// ... Other component definitions
381
374
};
382
375
```
383
376
384
377
### Button Component:
385
378
- ` Schema ` : Defines props like className, variant, and size with default values.
386
- - ` Default Children ` : A text layer with default text "Button".
379
+ - ` Default Children ` : A span layer with default text "Button".
387
380
- ` Field Overrides ` : Customizes form fields for className and children properties.
388
381
382
+ ## Changelog
383
+
384
+ ### v0.0.2
385
+ - Removed _ text_ layer type in favor of using span and Markdown components. You should migrate any layers stored in the database to use the new components. You can use the [ migrateV1ToV2] ( lib/ui-builder/store/layer-utils.ts ) function in layer-utils.ts to help with the migration.
386
+
389
387
## Development
390
388
391
389
Build component registry after updating lib or ui:
@@ -415,8 +413,8 @@ npm run test
415
413
## Roadmap
416
414
417
415
- [ ] Increase test coverage
416
+ - [ ] Refactor page layers to be more consistent with component layers
418
417
- [ ] Improve performance
419
- - [ ] Rework text layers to be more consistent with component layers
420
418
- [ ] Add form component definitions since we already depend on most shadcn/ui form components
421
419
- [ ] Add option to add children component layers by reference to existing layers (this would be like figma component instances)
422
420
- [ ] Add event handlers to component layers (onClick, onSubmit, etc)
0 commit comments