1
- import React from "react" ;
1
+ import React , { useState } from "react" ;
2
2
import { ComponentConfig , Slot } from "@/core/types" ;
3
3
import styles from "./styles.module.css" ;
4
4
import { getClassNameFactory } from "@/core/lib" ;
5
5
import { Section } from "../../components/Section" ;
6
6
import { withLayout } from "../../components/Layout" ;
7
7
import { generateId } from "@/core/lib/generate-id" ;
8
- import { type Props } from "../../index" ;
8
+ import { componentKey , type Props } from "../../index" ;
9
+ import { AutoField , Button , createUsePuck , FieldLabel } from "@/core" ;
10
+
11
+ const usePuck = createUsePuck ( ) ;
9
12
10
13
async function createComponent < T extends keyof Props > (
11
14
component : T ,
12
15
props ?: Partial < Props [ T ] >
13
16
) {
14
- // const test = dynamic(() => import("../../index"));
15
17
const { conf : config } = await import ( "../../index" ) ;
16
18
17
- // "a-arrow-down": () => import('./dist/esm/icons/a-arrow-down.js'),
18
-
19
19
return {
20
20
type : component ,
21
21
props : {
@@ -33,104 +33,148 @@ export type TemplateProps = {
33
33
children : Slot ;
34
34
} ;
35
35
36
+ type TemplateData = Record < string , { label : string ; data : Slot } > ;
37
+
36
38
export const TemplateInternal : ComponentConfig < TemplateProps > = {
37
39
fields : {
38
40
template : {
39
- type : "select" ,
40
- options : [
41
- { label : "Template 1" , value : "template_1" } ,
42
- { label : "Template 2" , value : "template_2" } ,
43
- ] ,
41
+ type : "custom" ,
42
+ render : ( { name, value, onChange } ) => {
43
+ const templateKey = `puck-demo-templates:${ componentKey } ` ;
44
+
45
+ const props : TemplateProps | undefined = usePuck (
46
+ ( s ) => s . selectedItem ?. props
47
+ ) ;
48
+
49
+ const [ templates , setTemplates ] = useState < TemplateData > (
50
+ JSON . parse ( localStorage . getItem ( templateKey ) ?? "{}" )
51
+ ) ;
52
+
53
+ return (
54
+ < FieldLabel label = { name } >
55
+ < AutoField
56
+ value = { value }
57
+ onChange = { onChange }
58
+ field = { {
59
+ type : "select" ,
60
+ options : [
61
+ { label : "Blank" , value : "blank" } ,
62
+ { label : "Example 1" , value : "example_1" } ,
63
+ { label : "Example 2" , value : "example_2" } ,
64
+ ...Object . entries ( templates ) . map ( ( [ key , template ] ) => ( {
65
+ value : key ,
66
+ label : template . label ,
67
+ } ) ) ,
68
+ ] ,
69
+ } }
70
+ />
71
+ < div style = { { marginLeft : "auto" , marginTop : 16 } } >
72
+ < Button
73
+ variant = "secondary"
74
+ onClick = { ( ) => {
75
+ if ( ! props ?. children ) {
76
+ return ;
77
+ }
78
+
79
+ const templateId = generateId ( ) ;
80
+
81
+ const templateData = {
82
+ ...templates ,
83
+ [ templateId ] : {
84
+ label : new Date ( ) . toLocaleString ( ) ,
85
+ data : props . children ,
86
+ } ,
87
+ } ;
88
+
89
+ localStorage . setItem (
90
+ templateKey ,
91
+ JSON . stringify ( templateData )
92
+ ) ;
93
+
94
+ setTemplates ( templateData ) ;
95
+
96
+ onChange ( templateId ) ;
97
+ } }
98
+ >
99
+ Save new template
100
+ </ Button >
101
+ </ div >
102
+ </ FieldLabel >
103
+ ) ;
104
+ } ,
44
105
} ,
45
106
children : {
46
107
type : "slot" ,
47
108
} ,
48
109
} ,
49
110
defaultProps : {
50
- template : "template_1 " ,
111
+ template : "example_1 " ,
51
112
children : [ ] ,
52
113
} ,
53
114
resolveData : async ( data , { changed } ) => {
54
115
if ( ! changed . template ) return data ;
55
116
56
- const templates : Record < string , Slot > = {
57
- template_1 : [
58
- await createComponent ( "Grid" , {
59
- numColumns : 2 ,
60
- children : [
61
- await createComponent ( "Card" , { title : "A card" , mode : "card" } ) ,
62
- await createComponent ( "Flex" , {
63
- direction : "column" ,
64
- gap : 0 ,
65
- children : [
66
- await createComponent ( "Space" , {
67
- size : "32px" ,
68
- } ) ,
69
- await createComponent ( "Heading" , {
70
- text : "Template example" ,
71
- size : "xl" ,
72
- } ) ,
73
- await createComponent ( "Text" , {
74
- text : "Dynamically create components using the new slots API." ,
75
- } ) ,
76
- await createComponent ( "Space" , {
77
- size : "16px" ,
78
- } ) ,
79
- await createComponent ( "Button" , {
80
- variant : "secondary" ,
81
- label : "Learn more" ,
82
- } ) ,
83
- await createComponent ( "Space" , {
84
- size : "32px" ,
85
- } ) ,
86
- ] ,
87
- } ) ,
88
- ] ,
89
- } ) ,
90
- ] ,
91
- template_2 : [
92
- await createComponent ( "Grid" , {
93
- numColumns : 3 ,
94
- children : [
95
- await createComponent ( "Space" , {
96
- size : "32px" ,
97
- } ) ,
98
- await createComponent ( "Flex" , {
99
- direction : "column" ,
100
- gap : 0 ,
101
- justifyContent : "center" ,
102
- children : [
103
- await createComponent ( "Space" , {
104
- size : "32px" ,
105
- } ) ,
106
- await createComponent ( "Heading" , {
107
- text : "Template example" ,
108
- size : "xl" ,
109
- } ) ,
110
- await createComponent ( "Text" , {
111
- text : "Dynamically create components using the new slots API." ,
112
- } ) ,
113
- await createComponent ( "Space" , {
114
- size : "16px" ,
115
- } ) ,
116
- await createComponent ( "Button" , {
117
- variant : "secondary" ,
118
- label : "Learn more" ,
119
- } ) ,
120
- await createComponent ( "Space" , {
121
- size : "32px" ,
122
- } ) ,
123
- ] ,
124
- } ) ,
125
- await createComponent ( "Space" , {
126
- size : "32px" ,
127
- } ) ,
128
- ] ,
129
- } ) ,
130
- ] ,
117
+ const templateKey = `puck-demo-templates:${ componentKey } ` ;
118
+
119
+ const templates : TemplateData = {
120
+ ...JSON . parse ( localStorage . getItem ( templateKey ) ?? "{}" ) ,
121
+ blank : {
122
+ label : "Blank" ,
123
+ data : [ ] ,
124
+ } ,
125
+ example_1 : {
126
+ label : "Example 1" ,
127
+ data : [
128
+ await createComponent ( "Heading" , {
129
+ text : "Template example." ,
130
+ size : "xl" ,
131
+ } ) ,
132
+ await createComponent ( "Text" , {
133
+ text : "This component uses the slots API. Try changing template, or saving a new one via the template field." ,
134
+ } ) ,
135
+ ] ,
136
+ } ,
137
+ example_2 : {
138
+ label : "Example 2" ,
139
+ data : [
140
+ await createComponent ( "Grid" , {
141
+ numColumns : 2 ,
142
+ children : [
143
+ await createComponent ( "Card" , { title : "A card" , mode : "card" } ) ,
144
+ await createComponent ( "Flex" , {
145
+ direction : "column" ,
146
+ gap : 0 ,
147
+ children : [
148
+ await createComponent ( "Space" , {
149
+ size : "32px" ,
150
+ } ) ,
151
+ await createComponent ( "Heading" , {
152
+ text : "Template example" ,
153
+ size : "xl" ,
154
+ } ) ,
155
+ await createComponent ( "Text" , {
156
+ text : "Dynamically create components using the new slots API." ,
157
+ } ) ,
158
+ await createComponent ( "Space" , {
159
+ size : "16px" ,
160
+ } ) ,
161
+ await createComponent ( "Button" , {
162
+ variant : "secondary" ,
163
+ label : "Learn more" ,
164
+ } ) ,
165
+ await createComponent ( "Space" , {
166
+ size : "32px" ,
167
+ } ) ,
168
+ ] ,
169
+ } ) ,
170
+ ] ,
171
+ } ) ,
172
+ ] ,
173
+ } ,
131
174
} ;
132
175
133
- const children = templates [ data . props . template ] ;
176
+ const children =
177
+ templates [ data . props . template ] ?. data || templates [ "example_1" ] . data ;
134
178
135
179
return {
136
180
...data ,
0 commit comments