@blocklet/component-studio-cli 0.4.134

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.
Files changed (84) hide show
  1. package/README.md +84 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +11 -0
  4. package/dist/commands/add.d.ts +2 -0
  5. package/dist/commands/add.js +140 -0
  6. package/dist/commands/component-studio.d.ts +2 -0
  7. package/dist/commands/component-studio.js +70 -0
  8. package/dist/commands/dev.d.ts +2 -0
  9. package/dist/commands/dev.js +87 -0
  10. package/dist/commands/init.d.ts +2 -0
  11. package/dist/commands/init.js +114 -0
  12. package/dist/commands/migrate.d.ts +2 -0
  13. package/dist/commands/migrate.js +177 -0
  14. package/dist/commands/update.d.ts +2 -0
  15. package/dist/commands/update.js +22 -0
  16. package/dist/utils/display-logo.d.ts +2 -0
  17. package/dist/utils/display-logo.js +24 -0
  18. package/dist/utils/helper.d.ts +97 -0
  19. package/dist/utils/helper.js +479 -0
  20. package/package.json +58 -0
  21. package/templates/add/components/HelloWorld/@metadata.json +433 -0
  22. package/templates/add/components/HelloWorld/@template.json +4 -0
  23. package/templates/add/components/HelloWorld/index.tsx +560 -0
  24. package/templates/add/tools/cursor-rules/.cursor/rules/@metadata-json.mdc +549 -0
  25. package/templates/add/tools/cursor-rules/.cursor/rules/component-studio.mdc +138 -0
  26. package/templates/add/tools/cursor-rules/.cursor/rules/index-tsx.mdc +192 -0
  27. package/templates/add/tools/cursor-rules/@template.json +4 -0
  28. package/templates/init/0-basic/@template.json +4 -0
  29. package/templates/init/0-basic/README.md +30 -0
  30. package/templates/init/0-basic/package.json +26 -0
  31. package/templates/init/0-basic/src/HelloWorld/@metadata.json +433 -0
  32. package/templates/init/0-basic/src/HelloWorld/index.tsx +560 -0
  33. package/templates/init/1-professional/@template.json +4 -0
  34. package/templates/init/1-professional/README.md +75 -0
  35. package/templates/init/1-professional/biome.json +36 -0
  36. package/templates/init/1-professional/global.d.ts +131 -0
  37. package/templates/init/1-professional/package.json +73 -0
  38. package/templates/init/1-professional/scripts/bump-version.mjs +35 -0
  39. package/templates/init/1-professional/src/atoms/AnimationWrapper.tsx +95 -0
  40. package/templates/init/1-professional/src/atoms/ArrayTable.tsx +114 -0
  41. package/templates/init/1-professional/src/atoms/Card.tsx +52 -0
  42. package/templates/init/1-professional/src/atoms/ContentWrapper.tsx +72 -0
  43. package/templates/init/1-professional/src/atoms/CopyrightFooter.tsx +31 -0
  44. package/templates/init/1-professional/src/atoms/DataDisplays.tsx +157 -0
  45. package/templates/init/1-professional/src/atoms/GradientTitle.tsx +64 -0
  46. package/templates/init/1-professional/src/atoms/Logo.tsx +58 -0
  47. package/templates/init/1-professional/src/atoms/index.ts +27 -0
  48. package/templates/init/1-professional/src/components/HelloWorld/@metadata.json +433 -0
  49. package/templates/init/1-professional/src/components/HelloWorld/index.tsx +224 -0
  50. package/templates/init/1-professional/src/type.d.ts +42 -0
  51. package/templates/init/1-professional/src/utils/index.ts +1 -0
  52. package/templates/init/1-professional/tsconfig.json +102 -0
  53. package/templates/init/1-professional/version +1 -0
  54. package/templates/init/2-blank/@template.json +4 -0
  55. package/templates/init/2-blank/README.md +27 -0
  56. package/templates/init/2-blank/package.json +26 -0
  57. package/templates/workspace/.component-studio-runtime/_theme.tsx +4 -0
  58. package/templates/workspace/.editorconfig +23 -0
  59. package/templates/workspace/.env +1 -0
  60. package/templates/workspace/.init-component-studio +0 -0
  61. package/templates/workspace/LICENSE +13 -0
  62. package/templates/workspace/README.md +127 -0
  63. package/templates/workspace/api/dev.ts +21 -0
  64. package/templates/workspace/api/src/index.ts +50 -0
  65. package/templates/workspace/api/src/libs/auth.ts +17 -0
  66. package/templates/workspace/api/src/libs/env.ts +6 -0
  67. package/templates/workspace/api/src/libs/logger.ts +3 -0
  68. package/templates/workspace/api/src/routes/index.ts +12 -0
  69. package/templates/workspace/api/third.d.ts +17 -0
  70. package/templates/workspace/biome.json +36 -0
  71. package/templates/workspace/blocklet.md +8 -0
  72. package/templates/workspace/blocklet.yml +58 -0
  73. package/templates/workspace/index.html +15 -0
  74. package/templates/workspace/logo.png +0 -0
  75. package/templates/workspace/package.json +125 -0
  76. package/templates/workspace/pnpm-workspace.yaml +3 -0
  77. package/templates/workspace/scripts/build-clean.mjs +6 -0
  78. package/templates/workspace/scripts/bump-version.mjs +39 -0
  79. package/templates/workspace/scripts/init-component-studio.mjs +36 -0
  80. package/templates/workspace/tsconfig.api.json +12 -0
  81. package/templates/workspace/tsconfig.json +102 -0
  82. package/templates/workspace/version +1 -0
  83. package/templates/workspace/vite-server.config.ts +39 -0
  84. package/templates/workspace/vite.config.ts +68 -0
@@ -0,0 +1,560 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ export interface BlockProps {
4
+ /** @description id: gs1rn5jmxfvpxptx | type: string | visible: true */
5
+ title?: string;
6
+ /** @description id: 9ajrz12ik7esfk1z | type: string | visible: true */
7
+ description?: string;
8
+ /** @description id: 3ckcfvf6b7zyskk8 | type: url | visible: true */
9
+ logo?: {
10
+ url: string;
11
+ mediaKitUrl?: string;
12
+ width?: number;
13
+ height?: number;
14
+ };
15
+ /** @description id: x3lqht8ikble1itx | type: string | visible: false */
16
+ copyright?: string;
17
+ /** @description id: q0ezdj81v0m14y5m | type: number | visible: true */
18
+ number?: number;
19
+ /** @description id: bl0rimfebwbencoj | type: decimal | visible: true */
20
+ decimal?: number;
21
+ /** @description id: gioetxz8d13jabz6 | type: boolean | visible: true */
22
+ showCopyright?: boolean;
23
+ /** @description id: yi1oj4rq1eziup1d | type: color | visible: true */
24
+ titleColor?: string;
25
+ /** @description id: 4f49q5uidkcp5ak4 | type: json | visible: true */
26
+ json?: {
27
+ /** @description id: gpy89bsxc6ovvlsp | type: string | visible: true */
28
+ foo?: string;
29
+ /** @description id: 1j34jdhdptp2xm5e | type: string | visible: true */
30
+ bar?: string;
31
+ };
32
+ /** @description id: lbclpm6mxrp10w2k | type: array | visible: true */
33
+ array?: {
34
+ /** @description id: 1c5vl2p9cn9ryvgh | type: string | visible: true */
35
+ name?: string;
36
+ /** @description id: c5whnccwzqqzaa0w | type: multiline | visible: true */
37
+ bio?: string;
38
+ }[];
39
+ /** @description id: s0tund4p07bzizgv | type: yaml | visible: true */
40
+ yaml?: {
41
+ /** @description id: 1q8tsreh4k2mhbgs | type: string | visible: true */
42
+ ya?: string;
43
+ /** @description id: 09w8sncxwrj6tldi | type: string | visible: true */
44
+ ml?: string;
45
+ };
46
+ /** @description id: 8e7g6c61pxcy0q4w | type: component | visible: true */
47
+ children?: any;
48
+ }
49
+
50
+ // default export
51
+ export default function BlockComponent({
52
+ title = 'Hello World',
53
+ logo,
54
+ description,
55
+ copyright = 'Powered by Component Studio',
56
+ number,
57
+ decimal,
58
+ showCopyright = true,
59
+ titleColor = '#6366F1',
60
+ json,
61
+ array,
62
+ yaml,
63
+ children,
64
+ }: BlockProps) {
65
+ const [animateIn, setAnimateIn] = useState(false);
66
+
67
+ useEffect(() => {
68
+ // Trigger entrance animation after component mounts
69
+ setAnimateIn(true);
70
+
71
+ // Add animation keyframes to the document
72
+ const styleEl = document.createElement('style');
73
+ styleEl.textContent = `
74
+ @keyframes fadeIn {
75
+ from { opacity: 0; }
76
+ to { opacity: 1; }
77
+ }
78
+
79
+ @keyframes fadeSlideDown {
80
+ from {
81
+ opacity: 0;
82
+ transform: translateY(-20px);
83
+ }
84
+ to {
85
+ opacity: 1;
86
+ transform: translateY(0);
87
+ }
88
+ }
89
+
90
+ @keyframes fadeSlideUp {
91
+ from {
92
+ opacity: 0;
93
+ transform: translateY(20px);
94
+ }
95
+ to {
96
+ opacity: 1;
97
+ transform: translateY(0);
98
+ }
99
+ }
100
+ `;
101
+ document.head.appendChild(styleEl);
102
+
103
+ // Cleanup
104
+ return () => {
105
+ document.head.removeChild(styleEl);
106
+ };
107
+ }, []);
108
+
109
+ // Modern card style for data blocks
110
+ const cardStyle = {
111
+ padding: '1.5rem',
112
+ borderRadius: '12px',
113
+ background: 'rgba(255, 255, 255, 0.7)',
114
+ backdropFilter: 'blur(10px)',
115
+ boxShadow: '0 10px 30px rgba(0, 0, 0, 0.08), 0 6px 12px rgba(99, 102, 241, 0.1)',
116
+ transition: 'transform 0.3s ease, box-shadow 0.3s ease',
117
+ margin: '1rem',
118
+ flex: '1 1 300px',
119
+ minWidth: '250px',
120
+ border: '1px solid rgba(255, 255, 255, 0.3)',
121
+ transform: animateIn ? 'translateY(0)' : 'translateY(20px)',
122
+ opacity: animateIn ? 1 : 0,
123
+ };
124
+
125
+ // Hover effect for cards
126
+ const cardHoverEffect = (e: React.MouseEvent) => {
127
+ const target = e.currentTarget as HTMLElement;
128
+ target.style.transform = 'translateY(-5px)';
129
+ target.style.boxShadow = '0 15px 35px rgba(0, 0, 0, 0.1), 0 8px 15px rgba(99, 102, 241, 0.2)';
130
+ };
131
+
132
+ const cardLeaveEffect = (e: React.MouseEvent) => {
133
+ const target = e.currentTarget as HTMLElement;
134
+ target.style.transform = 'translateY(0)';
135
+ target.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.08), 0 6px 12px rgba(99, 102, 241, 0.1)';
136
+ };
137
+
138
+ return (
139
+ <div
140
+ className="hello-world-component"
141
+ style={{
142
+ fontFamily: '"Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif',
143
+ padding: '2.5rem',
144
+ maxWidth: '1200px',
145
+ margin: '0 auto',
146
+ background: 'linear-gradient(135deg, #f5f7ff 0%, #ffffff 100%)',
147
+ borderRadius: '20px',
148
+ boxShadow: '0 20px 60px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.05)',
149
+ overflow: 'hidden',
150
+ position: 'relative',
151
+ }}>
152
+ {/* Background decoration */}
153
+ <div
154
+ style={{
155
+ position: 'absolute',
156
+ top: 0,
157
+ right: 0,
158
+ width: '300px',
159
+ height: '300px',
160
+ borderRadius: '50%',
161
+ background: 'radial-gradient(circle, rgba(99, 102, 241, 0.1) 0%, rgba(99, 102, 241, 0) 70%)',
162
+ zIndex: 0,
163
+ }}
164
+ />
165
+ <div
166
+ style={{
167
+ position: 'absolute',
168
+ bottom: '-100px',
169
+ left: '-100px',
170
+ width: '400px',
171
+ height: '400px',
172
+ borderRadius: '50%',
173
+ background: 'radial-gradient(circle, rgba(249, 115, 22, 0.08) 0%, rgba(249, 115, 22, 0) 70%)',
174
+ zIndex: 0,
175
+ }}
176
+ />
177
+
178
+ {/* Logo区域 */}
179
+ {logo && (
180
+ <div
181
+ style={{
182
+ textAlign: 'center',
183
+ margin: '1rem 0',
184
+ animation: animateIn ? 'fadeIn 0.9s ease forwards' : 'none',
185
+ opacity: animateIn ? 1 : 0,
186
+ }}>
187
+ <img
188
+ src={typeof logo === 'object' ? logo.url : logo}
189
+ alt="logo"
190
+ style={{
191
+ borderRadius: '4px',
192
+ maxWidth: '240px',
193
+ maxHeight: '120px',
194
+ filter: 'drop-shadow(0 10px 15px rgba(0, 0, 0, 0.1))',
195
+ width: typeof logo === 'object' && logo.width ? `${logo.width}px` : 'auto',
196
+ height: typeof logo === 'object' && logo.height ? `${logo.height}px` : 'auto',
197
+ transition: 'transform 0.3s ease',
198
+ }}
199
+ onMouseOver={(e) => {
200
+ e.currentTarget.style.transform = 'scale(1.05)';
201
+ }}
202
+ onMouseOut={(e) => {
203
+ e.currentTarget.style.transform = 'scale(1)';
204
+ }}
205
+ />
206
+ </div>
207
+ )}
208
+
209
+ {/* Content wrapper with relative position to show above background */}
210
+ <div style={{ position: 'relative', zIndex: 1 }}>
211
+ {/* 标题区域 */}
212
+ {title && (
213
+ <h1
214
+ key={title}
215
+ style={{
216
+ borderRadius: '12px',
217
+ textAlign: 'center',
218
+ fontSize: '3.5rem',
219
+ fontWeight: 800,
220
+ letterSpacing: '-0.03em',
221
+ margin: '0 0 1.5rem',
222
+ background: `linear-gradient(135deg, ${titleColor} 0%, #3773F2 100%)`,
223
+ WebkitBackgroundClip: 'text',
224
+ WebkitTextFillColor: 'transparent',
225
+ backgroundClip: 'text',
226
+ color: 'transparent',
227
+ // @ts-ignore
228
+ textFillColor: 'transparent',
229
+ animation: animateIn ? 'fadeSlideDown 0.7s ease forwards' : 'none',
230
+ }}>
231
+ {title}
232
+ </h1>
233
+ )}
234
+
235
+ {/* 描述区域 */}
236
+ {description && (
237
+ <div
238
+ style={{
239
+ color: '#4B5563',
240
+ padding: '1.5rem 2rem',
241
+ background: 'rgba(255, 255, 255, 0.8)',
242
+ backdropFilter: 'blur(10px)',
243
+ borderRadius: '16px',
244
+ marginTop: '1.5rem',
245
+ border: '1px solid rgba(255, 255, 255, 0.5)',
246
+ boxShadow: '0 4px 20px rgba(0, 0, 0, 0.05)',
247
+ whiteSpace: 'pre-wrap',
248
+ lineHeight: 1.7,
249
+ fontSize: '1.1rem',
250
+ animation: animateIn ? 'fadeSlideUp 0.8s ease forwards' : 'none',
251
+ opacity: animateIn ? 1 : 0,
252
+ transform: animateIn ? 'translateY(0)' : 'translateY(20px)',
253
+ transition: 'transform 0.3s ease, opacity 0.3s ease',
254
+ }}>
255
+ {description}
256
+ </div>
257
+ )}
258
+
259
+ {/* 数字展示区域 和 JSON数据展示 */}
260
+ <div
261
+ className="data-section"
262
+ style={{
263
+ display: 'flex',
264
+ gap: '1.5rem',
265
+ margin: '2rem 0',
266
+ flexWrap: 'wrap',
267
+ justifyContent: 'center',
268
+ }}>
269
+ {(number !== undefined || decimal !== undefined) && (
270
+ <div
271
+ style={{
272
+ ...cardStyle,
273
+ background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(240, 248, 255, 0.9) 100%)',
274
+ transitionDelay: '0.1s',
275
+ }}
276
+ onMouseOver={cardHoverEffect}
277
+ onMouseOut={cardLeaveEffect}>
278
+ <h3
279
+ style={{
280
+ margin: '0 0 1rem 0',
281
+ color: '#4F46E5',
282
+ fontSize: '1.3rem',
283
+ fontWeight: 600,
284
+ }}>
285
+ Number Values
286
+ </h3>
287
+ {number !== undefined && (
288
+ <div style={{ margin: '0.8rem 0', fontSize: '1.1rem', color: '#1F2937' }}>
289
+ <span style={{ fontWeight: 500, marginRight: '0.5rem', color: '#6366F1' }}>Integer:</span>
290
+ <span style={{ fontSize: '1.5rem', fontWeight: 700 }}>{number}</span>
291
+ </div>
292
+ )}
293
+ {decimal !== undefined && (
294
+ <div style={{ margin: '0.8rem 0', fontSize: '1.1rem', color: '#1F2937' }}>
295
+ <span style={{ fontWeight: 500, marginRight: '0.5rem', color: '#6366F1' }}>Decimal:</span>
296
+ <span style={{ fontSize: '1.5rem', fontWeight: 700 }}>{decimal.toFixed(2)}</span>
297
+ </div>
298
+ )}
299
+ </div>
300
+ )}
301
+
302
+ {/* JSON数据展示 */}
303
+ {json && (
304
+ <div
305
+ style={{
306
+ ...cardStyle,
307
+ background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 248, 240, 0.9) 100%)',
308
+ transitionDelay: '0.2s',
309
+ }}
310
+ onMouseOver={cardHoverEffect}
311
+ onMouseOut={cardLeaveEffect}>
312
+ <h3
313
+ style={{
314
+ margin: '0 0 1rem 0',
315
+ color: '#F59E0B',
316
+ fontSize: '1.3rem',
317
+ fontWeight: 600,
318
+ }}>
319
+ JSON Data
320
+ </h3>
321
+ {Object.entries(json).map(([key, value]) => (
322
+ <div style={{ margin: '0.8rem 0', fontSize: '1.1rem', color: '#1F2937' }}>
323
+ <span style={{ fontWeight: 500, marginRight: '0.5rem', color: '#F59E0B' }}>{key}:</span>
324
+ <span style={{ fontSize: '1.15rem' }}>{value}</span>
325
+ </div>
326
+ ))}
327
+ </div>
328
+ )}
329
+ </div>
330
+
331
+ {/* 数组数据表格 */}
332
+ {array && array.length > 0 && (
333
+ <div
334
+ style={{
335
+ margin: '2.5rem 0',
336
+ animation: animateIn ? 'fadeSlideUp 0.9s ease forwards' : 'none',
337
+ opacity: animateIn ? 1 : 0,
338
+ transform: animateIn ? 'translateY(0)' : 'translateY(20px)',
339
+ transition: 'transform 0.4s ease, opacity 0.4s ease',
340
+ transitionDelay: '0.3s',
341
+ background: 'rgba(255, 255, 255, 0.8)',
342
+ borderRadius: '16px',
343
+ padding: '1.5rem',
344
+ backdropFilter: 'blur(10px)',
345
+ boxShadow: '0 10px 30px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.03)',
346
+ border: '1px solid rgba(255, 255, 255, 0.7)',
347
+ }}>
348
+ <h3
349
+ style={{
350
+ textAlign: 'center',
351
+ margin: '0 0 1.5rem 0',
352
+ color: '#4F46E5',
353
+ fontSize: '1.5rem',
354
+ fontWeight: 600,
355
+ }}>
356
+ Array Data
357
+ </h3>
358
+ <div style={{ overflowX: 'auto' }}>
359
+ <table style={{ width: '100%', borderCollapse: 'separate', borderSpacing: '0' }}>
360
+ <thead>
361
+ <tr>
362
+ <th
363
+ style={{
364
+ padding: '1rem 1.5rem',
365
+ textAlign: 'left',
366
+ borderBottom: '2px solid rgba(99, 102, 241, 0.2)',
367
+ color: '#4F46E5',
368
+ fontWeight: 600,
369
+ fontSize: '1.1rem',
370
+ }}>
371
+ Name
372
+ </th>
373
+ <th
374
+ style={{
375
+ padding: '1rem 1.5rem',
376
+ textAlign: 'left',
377
+ borderBottom: '2px solid rgba(99, 102, 241, 0.2)',
378
+ color: '#4F46E5',
379
+ fontWeight: 600,
380
+ fontSize: '1.1rem',
381
+ }}>
382
+ Bio
383
+ </th>
384
+ </tr>
385
+ </thead>
386
+ <tbody>
387
+ {array.map((item, index) => (
388
+ <tr
389
+ key={index}
390
+ style={{
391
+ background: index % 2 === 0 ? 'rgba(255, 255, 255, 0.5)' : 'rgba(249, 250, 251, 0.5)',
392
+ transition: 'background-color 0.2s ease',
393
+ }}
394
+ onMouseOver={(e) => {
395
+ e.currentTarget.style.backgroundColor = 'rgba(238, 242, 255, 0.7)';
396
+ }}
397
+ onMouseOut={(e) => {
398
+ e.currentTarget.style.backgroundColor =
399
+ index % 2 === 0 ? 'rgba(255, 255, 255, 0.5)' : 'rgba(249, 250, 251, 0.5)';
400
+ }}>
401
+ <td
402
+ style={{
403
+ padding: '1rem 1.5rem',
404
+ borderBottom: '1px solid rgba(229, 231, 235, 0.7)',
405
+ fontSize: '1.05rem',
406
+ }}>
407
+ {item.name || '-'}
408
+ </td>
409
+ <td
410
+ style={{
411
+ padding: '1rem 1.5rem',
412
+ borderBottom: '1px solid rgba(229, 231, 235, 0.7)',
413
+ fontSize: '1.05rem',
414
+ }}>
415
+ {item.bio || '-'}
416
+ </td>
417
+ </tr>
418
+ ))}
419
+ </tbody>
420
+ </table>
421
+ </div>
422
+ </div>
423
+ )}
424
+
425
+ {/* YAML显示区域 */}
426
+ {yaml && (
427
+ <div
428
+ style={{
429
+ margin: '2.5rem 0',
430
+ animation: animateIn ? 'fadeSlideUp 1s ease forwards' : 'none',
431
+ opacity: animateIn ? 1 : 0,
432
+ transform: animateIn ? 'translateY(0)' : 'translateY(20px)',
433
+ transition: 'transform 0.4s ease, opacity 0.4s ease',
434
+ transitionDelay: '0.4s',
435
+ }}>
436
+ <h3
437
+ style={{
438
+ textAlign: 'center',
439
+ margin: '0 0 1.5rem 0',
440
+ color: '#4F46E5',
441
+ fontSize: '1.5rem',
442
+ fontWeight: 600,
443
+ }}>
444
+ YAML to JSON Data
445
+ </h3>
446
+ <pre
447
+ style={{
448
+ background: 'linear-gradient(135deg, rgba(31, 41, 55, 0.95) 0%, rgba(17, 24, 39, 0.95) 100%)',
449
+ padding: '1.5rem',
450
+ borderRadius: '12px',
451
+ overflow: 'auto',
452
+ fontSize: '0.95rem',
453
+ color: '#E5E7EB',
454
+ boxShadow: '0 15px 30px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.05)',
455
+ fontFamily: '"Fira Code", "Menlo", monospace',
456
+ lineHeight: 1.6,
457
+ border: '1px solid rgba(55, 65, 81, 0.5)',
458
+ }}>
459
+ {JSON.stringify(yaml, null, 2)}
460
+ </pre>
461
+ </div>
462
+ )}
463
+
464
+ {/* 子组件 */}
465
+ {children && (
466
+ <div
467
+ style={{
468
+ margin: '2.5rem 0',
469
+ padding: '2rem',
470
+ borderRadius: '16px',
471
+ background: 'rgba(255, 255, 255, 0.7)',
472
+ backdropFilter: 'blur(10px)',
473
+ border: '1px solid rgba(99, 102, 241, 0.2)',
474
+ boxShadow: '0 10px 30px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.03)',
475
+ animation: animateIn ? 'fadeSlideUp 1.1s ease forwards' : 'none',
476
+ opacity: animateIn ? 1 : 0,
477
+ transform: animateIn ? 'translateY(0)' : 'translateY(20px)',
478
+ transition: 'transform 0.4s ease, opacity 0.4s ease',
479
+ transitionDelay: '0.5s',
480
+ }}>
481
+ <h3
482
+ style={{
483
+ textAlign: 'center',
484
+ marginTop: '0',
485
+ marginBottom: '1.5rem',
486
+ color: '#4F46E5',
487
+ fontSize: '1.5rem',
488
+ fontWeight: 600,
489
+ }}>
490
+ Children Components
491
+ </h3>
492
+ {children}
493
+ </div>
494
+ )}
495
+
496
+ {/* 版权信息 */}
497
+ {showCopyright && copyright && (
498
+ <div
499
+ style={{
500
+ textAlign: 'center',
501
+ color: '#6B7280',
502
+ fontSize: '0.9rem',
503
+ marginTop: '3rem',
504
+ padding: '1rem 0',
505
+ borderTop: '1px solid rgba(229, 231, 235, 0.7)',
506
+ animation: animateIn ? 'fadeIn 1.2s ease forwards' : 'none',
507
+ opacity: animateIn ? 0.8 : 0,
508
+ marginBottom: '-2.5rem',
509
+ }}>
510
+ {copyright}
511
+ </div>
512
+ )}
513
+ </div>
514
+ </div>
515
+ );
516
+ }
517
+
518
+ // export edit component
519
+ export const EditComponent: React.FC<BlockProps & { onChange?: (value: BlockProps) => void }> = ({
520
+ onChange,
521
+ ...props
522
+ }) => {
523
+ return (
524
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
525
+ <div
526
+ style={{
527
+ fontSize: '14px',
528
+ fontWeight: 500,
529
+ color: '#333',
530
+ padding: '8px 0',
531
+ borderBottom: '1px solid #eee',
532
+ }}>
533
+ Extra Edit Component
534
+ </div>
535
+
536
+ {/* 版权信息输入 */}
537
+ <div>
538
+ <label htmlFor="copyright-input" style={{ display: 'block', marginBottom: '4px', fontSize: '14px' }}>
539
+ Copyright Text
540
+ </label>
541
+ <input
542
+ id="copyright-input"
543
+ type="text"
544
+ style={{
545
+ width: '100%',
546
+ padding: '8px 12px',
547
+ border: '1px solid #ddd',
548
+ borderRadius: '4px',
549
+ fontSize: '14px',
550
+ transition: 'border-color 0.3s',
551
+ outline: 'none',
552
+ }}
553
+ value={props.copyright || ''}
554
+ onChange={(e) => onChange?.({ ...props, copyright: e.target.value })}
555
+ placeholder="Please Input Copyright"
556
+ />
557
+ </div>
558
+ </div>
559
+ );
560
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "Professional Project",
3
+ "description": "A professional component studio project, with engineered project structure"
4
+ }
@@ -0,0 +1,75 @@
1
+ # Professional Component Studio Project
2
+
3
+ This is a professional component project created with Component Studio. This template provides a complete engineering design and development environment to help you quickly build high-quality components.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ {your-project-name}/
9
+ ├── src/ # Source code directory
10
+ │ ├── components/ # common components directory
11
+ | ├── HelloWorld/ # Example component
12
+ | ├── index.tsx # Component entry
13
+ | └── @metadata.json # Component metadata
14
+ | ├── utils/ # Utility functions
15
+ ├── scripts/ # Utility scripts
16
+ │ └── bump-version.mjs # Version update script
17
+ ├── global.d.ts # Global type declarations
18
+ ├── package.json # Project configuration and dependencies
19
+ ├── tsconfig.json # TypeScript configuration
20
+ ├── biome.json # Biome configuration (code formatting)
21
+ ├── .gitignore # Git ignore configuration
22
+ └── README.md # Project documentation
23
+ ```
24
+
25
+ ## Features
26
+
27
+ - **TypeScript Support** - Complete type definitions and type checking
28
+ - **Engineering Design** - Project structure and toolchain following best practices
29
+ - **Component Metadata** - Auto-generated component documentation and property descriptions
30
+ - **Development Toolchain** - Hot reload development server and optimized build process
31
+ - **Code Quality Tools** - Code formatting and quality checking
32
+
33
+ ## Quick Start
34
+
35
+ ### Development Environment
36
+
37
+ Start development server:
38
+
39
+ ```bash
40
+ pnpm run dev
41
+ ```
42
+
43
+ ### Publish Component
44
+
45
+ 1. Update version number
46
+
47
+ ```bash
48
+ pnpm run bump-version
49
+ ```
50
+
51
+ 2. Build and publish
52
+
53
+ ```bash
54
+ pnpm run build
55
+ pnpm publish
56
+ ```
57
+
58
+ ## Command List
59
+
60
+ - `pnpm run dev` - Start development server
61
+ - `pnpm run lint` - Run code checks
62
+ - `pnpm run format` - Format code
63
+ - `pnpm run bump-version` - Update version number
64
+
65
+ ## Custom Configuration
66
+
67
+ You can customize the following configuration files as needed:
68
+
69
+ - `tsconfig.json` - TypeScript configuration
70
+ - `biome.json` - Code formatting rules
71
+ - `package.json` - Dependencies and script configuration
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
3
+ "organizeImports": {
4
+ "enabled": true
5
+ },
6
+ "linter": {
7
+ "enabled": true,
8
+ "rules": {
9
+ "recommended": true,
10
+ "correctness": {
11
+ "noUnusedVariables": "error"
12
+ },
13
+ "suspicious": {
14
+ "noExplicitAny": "warn"
15
+ },
16
+ "style": {
17
+ "noNonNullAssertion": "off",
18
+ "useShorthandArrayType": "error"
19
+ },
20
+ "a11y": {
21
+ "noNoninteractiveElementToInteractiveRole": "off",
22
+ "useKeyWithClickEvents": "off",
23
+ "useValidAnchor": "off",
24
+ "noSvgWithoutTitle": "off",
25
+ "useKeyWithMouseEvents": "off"
26
+ }
27
+ },
28
+ "ignore": ["**/node_modules/**", "*.md"]
29
+ },
30
+ "formatter": {
31
+ "enabled": true,
32
+ "indentStyle": "space",
33
+ "indentWidth": 2,
34
+ "lineWidth": 100
35
+ }
36
+ }