create-next-imagicma 0.1.15 → 0.2.0
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 +2 -0
- package/package.json +1 -1
- package/template-hono/.env.example +6 -14
- package/template-hono/.imagicma/AGENTS.md +7 -0
- package/template-hono/AGENTS.md +98 -128
- package/template-hono/README.md +86 -118
- package/template-hono/client/index.html +1 -1
- package/template-hono/client/public/imagicma-picker-bridge.js +2 -6
- package/template-hono/client/public/imagicma-preview-feedback.js +0 -1
- package/template-hono/client/src/components/HelloClient.tsx +1 -1
- package/template-hono/client/src/globals.css +417 -1
- package/template-hono/client/src/lib/imagicma-preview-bridge.ts +1 -1
- package/template-hono/client/src/lib/imagicma-preview-picker.ts +28 -130
- package/template-hono/client/src/providers.tsx +1 -1
- package/template-hono/gitignore +2 -1
- package/template-hono/package.json +9 -9
- package/template-hono/pnpm-lock.yaml +646 -1173
- package/template-hono/server/app.ts +3 -2
- package/template-hono/server/controllers/greeting.controller.ts +22 -0
- package/template-hono/server/db/index.ts +129 -0
- package/template-hono/server/index.ts +3 -3
- package/template-hono/server/middlewares/error-handler.ts +8 -0
- package/template-hono/server/models/entities/message.entity.ts +13 -0
- package/template-hono/server/models/repositories/message.repository.ts +43 -0
- package/template-hono/server/models/services/greeting.service.ts +14 -0
- package/template-hono/server/models/types/message.ts +7 -0
- package/template-hono/server/routes/greeting.ts +1 -1
- package/template-hono/shared/constants/greeting.ts +1 -0
- package/template-hono/shared/contracts/routes.ts +14 -0
- package/template-hono/shared/routes.ts +1 -68
- package/template-hono/shared/schema.ts +5 -8
- package/template-hono/shared/types/greeting.ts +3 -0
- package/template-hono/tailwind.config.mjs +62 -111
- package/template-hono/tsconfig.json +3 -2
- package/template-hono/tsconfig.server.json +2 -0
- package/template-hono/vite.config.ts +4 -4
- package/template-hono/client/src/lib/ai-ui-stream.ts +0 -64
- package/template-hono/client/src/theme/default-theme.css +0 -482
- package/template-hono/drizzle.config.ts +0 -13
- package/template-hono/server/controllers/ai-chat-controller.ts +0 -49
- package/template-hono/server/controllers/greeting-controller.ts +0 -25
- package/template-hono/server/db/client.ts +0 -25
- package/template-hono/server/env.ts +0 -89
- package/template-hono/server/lib/ai-provider.ts +0 -74
- package/template-hono/server/lib/ai.ts +0 -205
- package/template-hono/server/middlewares/auth.ts +0 -69
- package/template-hono/server/middlewares/index.ts +0 -12
- package/template-hono/server/repositories/message-repository.ts +0 -13
- package/template-hono/server/routes/ai-chat.ts +0 -9
- package/template-hono/shared/schema/greeting.ts +0 -17
|
@@ -1,11 +1,427 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800&display=swap");
|
|
1
2
|
@import "tailwindcss";
|
|
2
|
-
@import "./theme/default-theme.css";
|
|
3
3
|
@config "../../tailwind.config.mjs";
|
|
4
4
|
|
|
5
5
|
.backdrop {
|
|
6
6
|
display: none;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
:root {
|
|
10
|
+
/* Fonts */
|
|
11
|
+
--font-sans: "Poppins", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
12
|
+
"Noto Sans SC", "Helvetica Neue", sans-serif;
|
|
13
|
+
--font-display: "Poppins", "PingFang SC", "Hiragino Sans GB",
|
|
14
|
+
"Microsoft YaHei", sans-serif;
|
|
15
|
+
--font-serif: "Poppins", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
16
|
+
"Noto Sans SC", "Helvetica Neue", sans-serif;
|
|
17
|
+
--font-mono: Menlo, ui-monospace, SFMono-Regular, Monaco, Consolas,
|
|
18
|
+
"Liberation Mono", "Courier New", monospace;
|
|
19
|
+
|
|
20
|
+
/* Core theme tokens (HSL triples) */
|
|
21
|
+
--background: 0 0% 100%;
|
|
22
|
+
--foreground: 240 10% 3.9%;
|
|
23
|
+
|
|
24
|
+
--card: 0 0% 100%;
|
|
25
|
+
--card-foreground: 240 10% 3.9%;
|
|
26
|
+
|
|
27
|
+
--popover: 0 0% 100%;
|
|
28
|
+
--popover-foreground: 240 10% 3.9%;
|
|
29
|
+
|
|
30
|
+
--primary: 240 5.9% 10%;
|
|
31
|
+
--primary-foreground: 0 0% 98%;
|
|
32
|
+
|
|
33
|
+
--secondary: 240 4.8% 95.9%;
|
|
34
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
35
|
+
|
|
36
|
+
--muted: 240 4.8% 95.9%;
|
|
37
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
38
|
+
|
|
39
|
+
--accent: 240 4.8% 95.9%;
|
|
40
|
+
--accent-foreground: 240 5.9% 10%;
|
|
41
|
+
|
|
42
|
+
--destructive: 0 84.2% 60.2%;
|
|
43
|
+
--destructive-foreground: 0 0% 98%;
|
|
44
|
+
|
|
45
|
+
--border: 240 5.9% 90%;
|
|
46
|
+
--input: 240 5.9% 90%;
|
|
47
|
+
--ring: 240 5.9% 10%;
|
|
48
|
+
|
|
49
|
+
--radius: 0.8rem;
|
|
50
|
+
|
|
51
|
+
/* Visual system tokens for showcase pages */
|
|
52
|
+
--surface-1: 224 40% 98%;
|
|
53
|
+
--surface-2: 220 35% 95%;
|
|
54
|
+
--brand-accent: 201 92% 56%;
|
|
55
|
+
--brand-success: 156 72% 40%;
|
|
56
|
+
--elevation-soft: 0 14px 34px rgba(15, 23, 42, 0.12);
|
|
57
|
+
--elevation-strong: 0 22px 56px rgba(15, 23, 42, 0.18);
|
|
58
|
+
--space-xs: 0.625rem;
|
|
59
|
+
--space-sm: 0.875rem;
|
|
60
|
+
--space-md: 1.125rem;
|
|
61
|
+
--space-lg: 1.625rem;
|
|
62
|
+
|
|
63
|
+
/* Extra tokens used by the migrated shadcn components */
|
|
64
|
+
--card-border: var(--border);
|
|
65
|
+
--popover-border: var(--border);
|
|
66
|
+
--sidebar: var(--background);
|
|
67
|
+
--sidebar-foreground: var(--foreground);
|
|
68
|
+
--sidebar-border: var(--border);
|
|
69
|
+
--sidebar-ring: var(--ring);
|
|
70
|
+
|
|
71
|
+
--chart-1: 220 70% 50%;
|
|
72
|
+
--chart-2: 160 60% 45%;
|
|
73
|
+
--chart-3: 30 80% 55%;
|
|
74
|
+
--chart-4: 280 65% 60%;
|
|
75
|
+
--chart-5: 340 75% 55%;
|
|
76
|
+
|
|
77
|
+
/* Border colors expected by template classnames */
|
|
78
|
+
--primary-border: hsl(var(--primary) / 0.18);
|
|
79
|
+
--secondary-border: hsl(var(--border));
|
|
80
|
+
--muted-border: hsl(var(--border));
|
|
81
|
+
--accent-border: hsl(var(--border));
|
|
82
|
+
--destructive-border: hsl(var(--destructive) / 0.25);
|
|
83
|
+
|
|
84
|
+
--button-outline: hsl(var(--border));
|
|
85
|
+
--badge-outline: hsl(var(--border));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.dark {
|
|
89
|
+
--background: 240 10% 3.9%;
|
|
90
|
+
--foreground: 0 0% 98%;
|
|
91
|
+
|
|
92
|
+
--card: 240 10% 3.9%;
|
|
93
|
+
--card-foreground: 0 0% 98%;
|
|
94
|
+
|
|
95
|
+
--popover: 240 10% 3.9%;
|
|
96
|
+
--popover-foreground: 0 0% 98%;
|
|
97
|
+
|
|
98
|
+
--primary: 0 0% 98%;
|
|
99
|
+
--primary-foreground: 240 5.9% 10%;
|
|
100
|
+
|
|
101
|
+
--secondary: 240 3.7% 15.9%;
|
|
102
|
+
--secondary-foreground: 0 0% 98%;
|
|
103
|
+
|
|
104
|
+
--muted: 240 3.7% 15.9%;
|
|
105
|
+
--muted-foreground: 240 5% 64.9%;
|
|
106
|
+
|
|
107
|
+
--accent: 240 3.7% 15.9%;
|
|
108
|
+
--accent-foreground: 0 0% 98%;
|
|
109
|
+
|
|
110
|
+
--destructive: 0 62.8% 30.6%;
|
|
111
|
+
--destructive-foreground: 0 0% 98%;
|
|
112
|
+
|
|
113
|
+
--border: 240 3.7% 15.9%;
|
|
114
|
+
--input: 240 3.7% 15.9%;
|
|
115
|
+
--ring: 240 4.9% 83.9%;
|
|
116
|
+
|
|
117
|
+
--card-border: var(--border);
|
|
118
|
+
--popover-border: var(--border);
|
|
119
|
+
--sidebar: var(--background);
|
|
120
|
+
--sidebar-foreground: var(--foreground);
|
|
121
|
+
--sidebar-border: var(--border);
|
|
122
|
+
--sidebar-ring: var(--ring);
|
|
123
|
+
|
|
124
|
+
--primary-border: hsl(var(--primary) / 0.15);
|
|
125
|
+
--secondary-border: hsl(var(--border));
|
|
126
|
+
--muted-border: hsl(var(--border));
|
|
127
|
+
--accent-border: hsl(var(--border));
|
|
128
|
+
--destructive-border: hsl(var(--destructive) / 0.35);
|
|
129
|
+
|
|
130
|
+
--button-outline: hsl(var(--border));
|
|
131
|
+
--badge-outline: hsl(var(--border));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Theme style presets (used by html[data-theme-style="<preset>"]) */
|
|
135
|
+
:root[data-theme-style="quadratic"] {
|
|
136
|
+
--background: 246 33% 96%;
|
|
137
|
+
--foreground: 233 24% 17%;
|
|
138
|
+
|
|
139
|
+
--card: 0 0% 100%;
|
|
140
|
+
--card-foreground: 233 24% 17%;
|
|
141
|
+
--popover: 0 0% 100%;
|
|
142
|
+
--popover-foreground: 233 24% 17%;
|
|
143
|
+
|
|
144
|
+
--primary: 258 84% 63%;
|
|
145
|
+
--primary-foreground: 0 0% 100%;
|
|
146
|
+
--secondary: 250 44% 92%;
|
|
147
|
+
--secondary-foreground: 233 24% 20%;
|
|
148
|
+
--muted: 246 36% 93%;
|
|
149
|
+
--muted-foreground: 230 12% 42%;
|
|
150
|
+
--accent: 257 62% 88%;
|
|
151
|
+
--accent-foreground: 234 24% 24%;
|
|
152
|
+
|
|
153
|
+
--border: 246 24% 86%;
|
|
154
|
+
--input: 246 24% 84%;
|
|
155
|
+
--ring: 258 84% 63%;
|
|
156
|
+
|
|
157
|
+
--chart-1: 258 78% 56%;
|
|
158
|
+
--chart-2: 201 84% 56%;
|
|
159
|
+
--chart-3: 172 65% 45%;
|
|
160
|
+
--chart-4: 338 74% 58%;
|
|
161
|
+
--chart-5: 39 84% 58%;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.dark[data-theme-style="quadratic"] {
|
|
165
|
+
--background: 233 22% 11%;
|
|
166
|
+
--foreground: 246 33% 96%;
|
|
167
|
+
|
|
168
|
+
--card: 232 20% 14%;
|
|
169
|
+
--card-foreground: 246 33% 96%;
|
|
170
|
+
--popover: 232 20% 14%;
|
|
171
|
+
--popover-foreground: 246 33% 96%;
|
|
172
|
+
|
|
173
|
+
--primary: 258 90% 70%;
|
|
174
|
+
--primary-foreground: 233 22% 11%;
|
|
175
|
+
--secondary: 235 16% 20%;
|
|
176
|
+
--secondary-foreground: 246 30% 94%;
|
|
177
|
+
--muted: 234 14% 18%;
|
|
178
|
+
--muted-foreground: 240 15% 76%;
|
|
179
|
+
--accent: 235 16% 20%;
|
|
180
|
+
--accent-foreground: 246 30% 94%;
|
|
181
|
+
|
|
182
|
+
--border: 234 14% 26%;
|
|
183
|
+
--input: 234 14% 26%;
|
|
184
|
+
--ring: 258 90% 70%;
|
|
185
|
+
|
|
186
|
+
--chart-1: 258 90% 70%;
|
|
187
|
+
--chart-2: 201 78% 68%;
|
|
188
|
+
--chart-3: 172 58% 62%;
|
|
189
|
+
--chart-4: 338 76% 72%;
|
|
190
|
+
--chart-5: 39 78% 70%;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:root[data-theme-style="nomad"] {
|
|
194
|
+
--background: 0 0% 94.1%;
|
|
195
|
+
--foreground: 0 0% 10.2%;
|
|
196
|
+
|
|
197
|
+
--card: 0 0% 98.8%;
|
|
198
|
+
--card-foreground: 0 0% 0%;
|
|
199
|
+
--popover: 45 25% 96.9%;
|
|
200
|
+
--popover-foreground: 0 0% 10.2%;
|
|
201
|
+
|
|
202
|
+
--primary: 341.9 85.1% 52.5%;
|
|
203
|
+
--primary-foreground: 0 0% 100%;
|
|
204
|
+
--secondary: 0 0% 76.9%;
|
|
205
|
+
--secondary-foreground: 0 0% 10.2%;
|
|
206
|
+
--muted: 0 0% 89%;
|
|
207
|
+
--muted-foreground: 0 0% 12.9%;
|
|
208
|
+
--accent: 0 0% 100%;
|
|
209
|
+
--accent-foreground: 0 0% 10.2%;
|
|
210
|
+
|
|
211
|
+
--border: 0 0% 91%;
|
|
212
|
+
--input: 0 0% 71%;
|
|
213
|
+
--ring: 0 0% 42%;
|
|
214
|
+
|
|
215
|
+
--chart-1: 203.9 88.3% 53.1%;
|
|
216
|
+
--chart-2: 159.8 100% 36.1%;
|
|
217
|
+
--chart-3: 42 92.8% 56.3%;
|
|
218
|
+
--chart-4: 147.1 78.5% 42%;
|
|
219
|
+
--chart-5: 341.5 75.2% 51%;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.dark[data-theme-style="nomad"] {
|
|
223
|
+
--background: 0 0% 10%;
|
|
224
|
+
--foreground: 0 0% 96%;
|
|
225
|
+
|
|
226
|
+
--card: 0 0% 13%;
|
|
227
|
+
--card-foreground: 0 0% 98%;
|
|
228
|
+
--popover: 0 0% 8%;
|
|
229
|
+
--popover-foreground: 0 0% 96%;
|
|
230
|
+
|
|
231
|
+
--primary: 341.9 85.1% 60%;
|
|
232
|
+
--primary-foreground: 0 0% 100%;
|
|
233
|
+
--secondary: 0 0% 26%;
|
|
234
|
+
--secondary-foreground: 0 0% 96%;
|
|
235
|
+
--muted: 0 0% 18%;
|
|
236
|
+
--muted-foreground: 0 0% 72%;
|
|
237
|
+
--accent: 0 0% 22%;
|
|
238
|
+
--accent-foreground: 0 0% 96%;
|
|
239
|
+
|
|
240
|
+
--border: 0 0% 24%;
|
|
241
|
+
--input: 0 0% 34%;
|
|
242
|
+
--ring: 0 0% 62%;
|
|
243
|
+
|
|
244
|
+
--chart-1: 203.9 88.3% 62%;
|
|
245
|
+
--chart-2: 159.8 100% 44%;
|
|
246
|
+
--chart-3: 42 92.8% 64%;
|
|
247
|
+
--chart-4: 147.1 78.5% 50%;
|
|
248
|
+
--chart-5: 341.5 75.2% 59%;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
:root[data-theme-style="honey"] {
|
|
252
|
+
--background: 49 38.1% 91.8%;
|
|
253
|
+
--foreground: 40 52.9% 27.5%;
|
|
254
|
+
|
|
255
|
+
--card: 49 42% 95%;
|
|
256
|
+
--card-foreground: 40 52.9% 27.5%;
|
|
257
|
+
--popover: 49 42% 95%;
|
|
258
|
+
--popover-foreground: 40 52.9% 27.5%;
|
|
259
|
+
|
|
260
|
+
--primary: 40 72.8% 68.2%;
|
|
261
|
+
--primary-foreground: 40 52.9% 18%;
|
|
262
|
+
--secondary: 63 20.8% 79.2%;
|
|
263
|
+
--secondary-foreground: 40 52.9% 27.5%;
|
|
264
|
+
--muted: 49 30% 88%;
|
|
265
|
+
--muted-foreground: 40 24% 38%;
|
|
266
|
+
--accent: 63 20.8% 79.2%;
|
|
267
|
+
--accent-foreground: 40 52.9% 27.5%;
|
|
268
|
+
|
|
269
|
+
--border: 52 22% 74%;
|
|
270
|
+
--input: 52 22% 74%;
|
|
271
|
+
--ring: 40 72.8% 68.2%;
|
|
272
|
+
|
|
273
|
+
--chart-1: 40 72.8% 55%;
|
|
274
|
+
--chart-2: 63 30% 45%;
|
|
275
|
+
--chart-3: 173 25% 42%;
|
|
276
|
+
--chart-4: 18 56% 50%;
|
|
277
|
+
--chart-5: 240 16% 52%;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.dark[data-theme-style="honey"] {
|
|
281
|
+
--background: 36 38% 10%;
|
|
282
|
+
--foreground: 49 30% 88%;
|
|
283
|
+
|
|
284
|
+
--card: 34 30% 14%;
|
|
285
|
+
--card-foreground: 49 30% 88%;
|
|
286
|
+
--popover: 34 30% 14%;
|
|
287
|
+
--popover-foreground: 49 30% 88%;
|
|
288
|
+
|
|
289
|
+
--primary: 40 72.8% 68.2%;
|
|
290
|
+
--primary-foreground: 36 38% 10%;
|
|
291
|
+
--secondary: 38 20% 20%;
|
|
292
|
+
--secondary-foreground: 49 30% 88%;
|
|
293
|
+
--muted: 38 18% 18%;
|
|
294
|
+
--muted-foreground: 49 18% 70%;
|
|
295
|
+
--accent: 38 18% 18%;
|
|
296
|
+
--accent-foreground: 49 30% 88%;
|
|
297
|
+
|
|
298
|
+
--border: 38 18% 26%;
|
|
299
|
+
--input: 38 18% 26%;
|
|
300
|
+
--ring: 40 72.8% 68.2%;
|
|
301
|
+
|
|
302
|
+
--chart-1: 40 72.8% 68.2%;
|
|
303
|
+
--chart-2: 63 35% 58%;
|
|
304
|
+
--chart-3: 173 30% 56%;
|
|
305
|
+
--chart-4: 20 56% 64%;
|
|
306
|
+
--chart-5: 240 22% 70%;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
:root[data-theme-style="zen-garden"] {
|
|
310
|
+
--background: 84 9.8% 90%;
|
|
311
|
+
--foreground: 225 18.2% 8.6%;
|
|
312
|
+
|
|
313
|
+
--card: 84 12% 94%;
|
|
314
|
+
--card-foreground: 225 18.2% 8.6%;
|
|
315
|
+
--popover: 84 12% 94%;
|
|
316
|
+
--popover-foreground: 225 18.2% 8.6%;
|
|
317
|
+
|
|
318
|
+
--primary: 173 24.7% 62%;
|
|
319
|
+
--primary-foreground: 225 18.2% 8.6%;
|
|
320
|
+
--secondary: 289 32.9% 72%;
|
|
321
|
+
--secondary-foreground: 225 18.2% 8.6%;
|
|
322
|
+
--muted: 84 10% 86%;
|
|
323
|
+
--muted-foreground: 225 10% 36%;
|
|
324
|
+
--accent: 289 32.9% 72%;
|
|
325
|
+
--accent-foreground: 225 18.2% 8.6%;
|
|
326
|
+
|
|
327
|
+
--border: 84 8% 78%;
|
|
328
|
+
--input: 84 8% 78%;
|
|
329
|
+
--ring: 173 24.7% 62%;
|
|
330
|
+
|
|
331
|
+
--chart-1: 173 24.7% 48%;
|
|
332
|
+
--chart-2: 289 32.9% 58%;
|
|
333
|
+
--chart-3: 40 68% 56%;
|
|
334
|
+
--chart-4: 220 26% 50%;
|
|
335
|
+
--chart-5: 0 55% 58%;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.dark[data-theme-style="zen-garden"] {
|
|
339
|
+
--background: 225 18.2% 8.6%;
|
|
340
|
+
--foreground: 84 9.8% 90%;
|
|
341
|
+
|
|
342
|
+
--card: 225 16% 12%;
|
|
343
|
+
--card-foreground: 84 9.8% 90%;
|
|
344
|
+
--popover: 225 16% 12%;
|
|
345
|
+
--popover-foreground: 84 9.8% 90%;
|
|
346
|
+
|
|
347
|
+
--primary: 173 30% 66%;
|
|
348
|
+
--primary-foreground: 225 18.2% 8.6%;
|
|
349
|
+
--secondary: 225 12% 18%;
|
|
350
|
+
--secondary-foreground: 84 9.8% 90%;
|
|
351
|
+
--muted: 225 10% 15%;
|
|
352
|
+
--muted-foreground: 84 8% 72%;
|
|
353
|
+
--accent: 225 10% 15%;
|
|
354
|
+
--accent-foreground: 84 9.8% 90%;
|
|
355
|
+
|
|
356
|
+
--border: 225 10% 24%;
|
|
357
|
+
--input: 225 10% 24%;
|
|
358
|
+
--ring: 173 30% 66%;
|
|
359
|
+
|
|
360
|
+
--chart-1: 173 30% 66%;
|
|
361
|
+
--chart-2: 289 36% 70%;
|
|
362
|
+
--chart-3: 40 68% 64%;
|
|
363
|
+
--chart-4: 220 30% 70%;
|
|
364
|
+
--chart-5: 355 65% 68%;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
:root[data-theme-style="highlighter"] {
|
|
368
|
+
--background: 228 23.8% 95.9%;
|
|
369
|
+
--foreground: 223 18.9% 7.3%;
|
|
370
|
+
|
|
371
|
+
--card: 228 24% 98%;
|
|
372
|
+
--card-foreground: 223 18.9% 7.3%;
|
|
373
|
+
--popover: 228 24% 98%;
|
|
374
|
+
--popover-foreground: 223 18.9% 7.3%;
|
|
375
|
+
|
|
376
|
+
--primary: 97 70.5% 64.1%;
|
|
377
|
+
--primary-foreground: 223 18.9% 7.3%;
|
|
378
|
+
--secondary: 249 35.6% 88.4%;
|
|
379
|
+
--secondary-foreground: 223 18.9% 7.3%;
|
|
380
|
+
--muted: 228 20% 92%;
|
|
381
|
+
--muted-foreground: 223 10% 35%;
|
|
382
|
+
--accent: 249 35.6% 88.4%;
|
|
383
|
+
--accent-foreground: 223 18.9% 7.3%;
|
|
384
|
+
|
|
385
|
+
--border: 238 20% 84%;
|
|
386
|
+
--input: 238 20% 84%;
|
|
387
|
+
--ring: 97 70.5% 64.1%;
|
|
388
|
+
|
|
389
|
+
--chart-1: 97 70.5% 48%;
|
|
390
|
+
--chart-2: 249 45% 56%;
|
|
391
|
+
--chart-3: 202 72% 54%;
|
|
392
|
+
--chart-4: 339 78% 58%;
|
|
393
|
+
--chart-5: 40 78% 58%;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.dark[data-theme-style="highlighter"] {
|
|
397
|
+
--background: 223 18.9% 7.3%;
|
|
398
|
+
--foreground: 228 23.8% 95.9%;
|
|
399
|
+
|
|
400
|
+
--card: 223 16% 11%;
|
|
401
|
+
--card-foreground: 228 23.8% 95.9%;
|
|
402
|
+
--popover: 223 16% 11%;
|
|
403
|
+
--popover-foreground: 228 23.8% 95.9%;
|
|
404
|
+
|
|
405
|
+
--primary: 97 74% 66%;
|
|
406
|
+
--primary-foreground: 223 18.9% 7.3%;
|
|
407
|
+
--secondary: 223 12% 18%;
|
|
408
|
+
--secondary-foreground: 228 23.8% 95.9%;
|
|
409
|
+
--muted: 223 10% 15%;
|
|
410
|
+
--muted-foreground: 228 14% 72%;
|
|
411
|
+
--accent: 223 10% 15%;
|
|
412
|
+
--accent-foreground: 228 23.8% 95.9%;
|
|
413
|
+
|
|
414
|
+
--border: 223 10% 24%;
|
|
415
|
+
--input: 223 10% 24%;
|
|
416
|
+
--ring: 97 74% 66%;
|
|
417
|
+
|
|
418
|
+
--chart-1: 97 74% 66%;
|
|
419
|
+
--chart-2: 249 50% 72%;
|
|
420
|
+
--chart-3: 202 78% 70%;
|
|
421
|
+
--chart-4: 339 80% 70%;
|
|
422
|
+
--chart-5: 40 78% 68%;
|
|
423
|
+
}
|
|
424
|
+
|
|
9
425
|
@layer base {
|
|
10
426
|
* {
|
|
11
427
|
border-color: hsl(var(--border));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const PROD_PARENT_ORIGINS = new Set(["https://agentma.cn", "https://imagicma.cn"
|
|
1
|
+
const PROD_PARENT_ORIGINS = new Set(["https://agentma.cn", "https://imagicma.cn"]);
|
|
2
2
|
const LOCAL_PARENT_RE = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;
|
|
3
3
|
const LOCAL_IMAGICMA_PARENT_RE = /^https?:\/\/([a-z0-9-]+\.)?local\.(agentma\.cn|imagicma\.cn)(:\d+)?$/i;
|
|
4
4
|
|
|
@@ -142,8 +142,6 @@ type PreviewPickerStateSyncPayload = {
|
|
|
142
142
|
pageKey: string;
|
|
143
143
|
overrides: PreviewOverridePageEntry | null;
|
|
144
144
|
selectedNodeId: string | null;
|
|
145
|
-
selectedTextEditable: boolean;
|
|
146
|
-
draftTargetScope: PreviewDraftTargetScope;
|
|
147
145
|
draft: PreviewDraftApplyPayload | null;
|
|
148
146
|
drafts: PreviewDraftApplyPayload[];
|
|
149
147
|
pendingSort: PreviewSortPreviewPayload | null;
|
|
@@ -169,19 +167,6 @@ type PickerMessage =
|
|
|
169
167
|
sessionId: string | null;
|
|
170
168
|
payload: PreviewPickerStateSyncPayload;
|
|
171
169
|
}
|
|
172
|
-
| {
|
|
173
|
-
channel: typeof PREVIEW_PICKER_CHANNEL;
|
|
174
|
-
version: typeof PREVIEW_PICKER_VERSION;
|
|
175
|
-
type: "IMAGICMA_PICKER_DRAFT_PATCH";
|
|
176
|
-
frameInstanceId: string;
|
|
177
|
-
sessionId: string | null;
|
|
178
|
-
payload?: {
|
|
179
|
-
nodeId?: string;
|
|
180
|
-
patch?: {
|
|
181
|
-
textContent?: string;
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
170
|
| {
|
|
186
171
|
channel: typeof PREVIEW_PICKER_CHANNEL;
|
|
187
172
|
version: typeof PREVIEW_PICKER_VERSION;
|
|
@@ -208,8 +193,6 @@ type RuntimeState = {
|
|
|
208
193
|
selectedSiblingBoxEls: HTMLDivElement[];
|
|
209
194
|
draftStyleEl: HTMLStyleElement | null;
|
|
210
195
|
persistedOverrides: PreviewOverridePageEntry | null;
|
|
211
|
-
selectedTextEditable: boolean;
|
|
212
|
-
draftTargetScope: PreviewDraftTargetScope;
|
|
213
196
|
draftPayload: PreviewDraftApplyPayload | null;
|
|
214
197
|
draftPayloads: PreviewDraftApplyPayload[];
|
|
215
198
|
pendingSort: { groupKey: string; orderedSortKeys: readonly string[] } | null;
|
|
@@ -232,10 +215,6 @@ type RuntimeState = {
|
|
|
232
215
|
throttledRecalculate: (() => void) | null;
|
|
233
216
|
mutationObserver: MutationObserver | null;
|
|
234
217
|
suppressMutationObserver: number;
|
|
235
|
-
inlineEditingElement: HTMLElement | null;
|
|
236
|
-
inlineEditingAbortController: AbortController | null;
|
|
237
|
-
inlineEditingOriginalContentEditable: string | null;
|
|
238
|
-
inlineEditingOriginalSpellcheck: boolean;
|
|
239
218
|
};
|
|
240
219
|
|
|
241
220
|
type SortableMetadata = {
|
|
@@ -524,6 +503,14 @@ function getElementNodeId(element: HTMLElement | null | undefined): string {
|
|
|
524
503
|
return trimText(element?.getAttribute("data-imagicma-node-id"));
|
|
525
504
|
}
|
|
526
505
|
|
|
506
|
+
function getRepeatItemScopeKey(element: HTMLElement | null | undefined): string | null {
|
|
507
|
+
const repeatRoot = element ? getRepeatItemRoot(element) : null;
|
|
508
|
+
const groupKey = trimText(repeatRoot?.getAttribute("data-imagicma-repeat-group"));
|
|
509
|
+
const itemKey = trimText(repeatRoot?.getAttribute("data-imagicma-sort-key"));
|
|
510
|
+
if (!groupKey || !itemKey) return null;
|
|
511
|
+
return `${groupKey}::${itemKey}`;
|
|
512
|
+
}
|
|
513
|
+
|
|
527
514
|
function getIndexedElementsByNodeKey(state: RuntimeState, nodeKey: string): HTMLElement[] {
|
|
528
515
|
const cached = state.nodeIdIndex.get(nodeKey)?.filter((element) => element.isConnected) ?? [];
|
|
529
516
|
if (cached.length > 0) return cached;
|
|
@@ -535,13 +522,26 @@ function getIndexedElementsByNodeKey(state: RuntimeState, nodeKey: string): HTML
|
|
|
535
522
|
);
|
|
536
523
|
}
|
|
537
524
|
|
|
525
|
+
function isRepeatScopedNodeIdentity(peers: HTMLElement[]): boolean {
|
|
526
|
+
if (peers.length <= 1) return false;
|
|
527
|
+
|
|
528
|
+
const seenScopes = new Set<string>();
|
|
529
|
+
for (const peer of peers) {
|
|
530
|
+
const scopeKey = getRepeatItemScopeKey(peer);
|
|
531
|
+
if (!scopeKey || seenScopes.has(scopeKey)) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
seenScopes.add(scopeKey);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return seenScopes.size === peers.length;
|
|
538
|
+
}
|
|
539
|
+
|
|
538
540
|
function getDirectSemanticSiblingItems(parent: HTMLElement | null): HTMLElement[] {
|
|
539
541
|
if (!parent) return [];
|
|
540
542
|
|
|
541
543
|
const items = Array.from(parent.children).filter((child): child is HTMLElement => {
|
|
542
|
-
return child instanceof HTMLElement
|
|
543
|
-
&& Boolean(getElementNodeId(child))
|
|
544
|
-
&& trimText(child.getAttribute("data-imagicma-kind")) === "repeat-item";
|
|
544
|
+
return child instanceof HTMLElement && Boolean(getElementNodeId(child));
|
|
545
545
|
});
|
|
546
546
|
|
|
547
547
|
if (items.length < 2) return [];
|
|
@@ -559,10 +559,6 @@ function getSyntheticSortableParentId(parent: HTMLElement | null): string | null
|
|
|
559
559
|
}
|
|
560
560
|
|
|
561
561
|
function getSiblingSortableMetadata(element: HTMLElement): SortableMetadata | null {
|
|
562
|
-
if (trimText(element.getAttribute("data-imagicma-kind")) !== "repeat-item") {
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
562
|
const nodeId = getElementNodeId(element);
|
|
567
563
|
if (!nodeId) return null;
|
|
568
564
|
|
|
@@ -1694,92 +1690,6 @@ function applyCurrentDraftToSelectedElement(state: RuntimeState) {
|
|
|
1694
1690
|
});
|
|
1695
1691
|
}
|
|
1696
1692
|
|
|
1697
|
-
function disableInlineTextEditing(state: RuntimeState) {
|
|
1698
|
-
const element = state.inlineEditingElement;
|
|
1699
|
-
state.inlineEditingAbortController?.abort();
|
|
1700
|
-
state.inlineEditingAbortController = null;
|
|
1701
|
-
|
|
1702
|
-
if (element?.isConnected) {
|
|
1703
|
-
if (state.inlineEditingOriginalContentEditable === null) {
|
|
1704
|
-
element.removeAttribute("contenteditable");
|
|
1705
|
-
} else {
|
|
1706
|
-
element.setAttribute("contenteditable", state.inlineEditingOriginalContentEditable);
|
|
1707
|
-
}
|
|
1708
|
-
element.spellcheck = state.inlineEditingOriginalSpellcheck;
|
|
1709
|
-
element.removeAttribute("data-imagicma-inline-editing");
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
state.inlineEditingElement = null;
|
|
1713
|
-
state.inlineEditingOriginalContentEditable = null;
|
|
1714
|
-
state.inlineEditingOriginalSpellcheck = false;
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
function moveCaretToEnd(element: HTMLElement) {
|
|
1718
|
-
const selection = window.getSelection();
|
|
1719
|
-
if (!selection) return;
|
|
1720
|
-
const range = document.createRange();
|
|
1721
|
-
range.selectNodeContents(element);
|
|
1722
|
-
range.collapse(false);
|
|
1723
|
-
selection.removeAllRanges();
|
|
1724
|
-
selection.addRange(range);
|
|
1725
|
-
}
|
|
1726
|
-
|
|
1727
|
-
function shouldEnableInlineTextEditing(state: RuntimeState, element: HTMLElement | null): element is HTMLElement {
|
|
1728
|
-
if (!state.enabled || !element || element !== state.selectedElement) return false;
|
|
1729
|
-
if (state.draftTargetScope !== "single") return false;
|
|
1730
|
-
if (!state.selectedTextEditable) return false;
|
|
1731
|
-
if (!isSimpleTextElement(element)) return false;
|
|
1732
|
-
return true;
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
function enableInlineTextEditing(state: RuntimeState, element: HTMLElement) {
|
|
1736
|
-
if (state.inlineEditingElement === element) return;
|
|
1737
|
-
disableInlineTextEditing(state);
|
|
1738
|
-
|
|
1739
|
-
state.inlineEditingElement = element;
|
|
1740
|
-
state.inlineEditingOriginalContentEditable = element.getAttribute("contenteditable");
|
|
1741
|
-
state.inlineEditingOriginalSpellcheck = element.spellcheck;
|
|
1742
|
-
|
|
1743
|
-
const abortController = new AbortController();
|
|
1744
|
-
state.inlineEditingAbortController = abortController;
|
|
1745
|
-
|
|
1746
|
-
element.setAttribute("contenteditable", "plaintext-only");
|
|
1747
|
-
element.setAttribute("data-imagicma-inline-editing", "true");
|
|
1748
|
-
element.spellcheck = false;
|
|
1749
|
-
|
|
1750
|
-
element.addEventListener("input", () => {
|
|
1751
|
-
postToParent(state, {
|
|
1752
|
-
channel: PREVIEW_PICKER_CHANNEL,
|
|
1753
|
-
version: PREVIEW_PICKER_VERSION,
|
|
1754
|
-
type: "IMAGICMA_PICKER_DRAFT_PATCH",
|
|
1755
|
-
frameInstanceId: state.frameInstanceId,
|
|
1756
|
-
sessionId: state.activeSessionId,
|
|
1757
|
-
payload: {
|
|
1758
|
-
nodeId: getElementNodeId(element),
|
|
1759
|
-
patch: {
|
|
1760
|
-
textContent: element.textContent || "",
|
|
1761
|
-
},
|
|
1762
|
-
},
|
|
1763
|
-
});
|
|
1764
|
-
}, { signal: abortController.signal });
|
|
1765
|
-
|
|
1766
|
-
window.requestAnimationFrame(() => {
|
|
1767
|
-
if (state.inlineEditingElement !== element) return;
|
|
1768
|
-
if (document.activeElement !== element) {
|
|
1769
|
-
element.focus({ preventScroll: true });
|
|
1770
|
-
moveCaretToEnd(element);
|
|
1771
|
-
}
|
|
1772
|
-
});
|
|
1773
|
-
}
|
|
1774
|
-
|
|
1775
|
-
function syncInlineTextEditing(state: RuntimeState) {
|
|
1776
|
-
if (shouldEnableInlineTextEditing(state, state.selectedElement)) {
|
|
1777
|
-
enableInlineTextEditing(state, state.selectedElement);
|
|
1778
|
-
return;
|
|
1779
|
-
}
|
|
1780
|
-
disableInlineTextEditing(state);
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
1693
|
function applySortPreview(state: RuntimeState, items: HTMLElement[], orderedKeys: readonly string[]) {
|
|
1784
1694
|
if (items.length < 2 || orderedKeys.length === 0) return;
|
|
1785
1695
|
|
|
@@ -1861,7 +1771,6 @@ function reapplyVisualState(state: RuntimeState) {
|
|
|
1861
1771
|
applyTextOverrides(state, state.persistedOverrides, state.draftPayloads);
|
|
1862
1772
|
applyCurrentDraftToSelectedElement(state);
|
|
1863
1773
|
applySortOverrides(state, state.persistedOverrides, state.pendingSort);
|
|
1864
|
-
syncInlineTextEditing(state);
|
|
1865
1774
|
|
|
1866
1775
|
const hoverTarget = state.hoveredElement && state.hoveredElement !== state.selectedElement
|
|
1867
1776
|
? state.hoveredElement
|
|
@@ -1883,10 +1792,12 @@ function reapplyVisualState(state: RuntimeState) {
|
|
|
1883
1792
|
}
|
|
1884
1793
|
}
|
|
1885
1794
|
|
|
1886
|
-
function isNodeSelectableElement(
|
|
1795
|
+
function isNodeSelectableElement(state: RuntimeState, element: HTMLElement): boolean {
|
|
1887
1796
|
const nodeId = getElementNodeId(element);
|
|
1888
1797
|
if (!nodeId) return false;
|
|
1889
|
-
|
|
1798
|
+
|
|
1799
|
+
const peers = getIndexedElementsByNodeKey(state, nodeId);
|
|
1800
|
+
return peers.length <= 1 || isRepeatScopedNodeIdentity(peers);
|
|
1890
1801
|
}
|
|
1891
1802
|
|
|
1892
1803
|
function isOverlayElement(state: RuntimeState, element: HTMLElement): boolean {
|
|
@@ -1968,8 +1879,6 @@ function createRuntimeState(): RuntimeState {
|
|
|
1968
1879
|
selectedSiblingBoxEls: [],
|
|
1969
1880
|
draftStyleEl: null,
|
|
1970
1881
|
persistedOverrides: null,
|
|
1971
|
-
selectedTextEditable: false,
|
|
1972
|
-
draftTargetScope: "single",
|
|
1973
1882
|
draftPayload: null,
|
|
1974
1883
|
draftPayloads: [],
|
|
1975
1884
|
pendingSort: null,
|
|
@@ -1988,10 +1897,6 @@ function createRuntimeState(): RuntimeState {
|
|
|
1988
1897
|
throttledRecalculate: null,
|
|
1989
1898
|
mutationObserver: null,
|
|
1990
1899
|
suppressMutationObserver: 0,
|
|
1991
|
-
inlineEditingElement: null,
|
|
1992
|
-
inlineEditingAbortController: null,
|
|
1993
|
-
inlineEditingOriginalContentEditable: null,
|
|
1994
|
-
inlineEditingOriginalSpellcheck: false,
|
|
1995
1900
|
};
|
|
1996
1901
|
}
|
|
1997
1902
|
|
|
@@ -2199,8 +2104,6 @@ export function installPreviewPickerRuntime() {
|
|
|
2199
2104
|
state.activeSessionId = event.data.sessionId;
|
|
2200
2105
|
state.enabled = event.data.payload.mode === "picking";
|
|
2201
2106
|
state.persistedOverrides = event.data.payload.overrides;
|
|
2202
|
-
state.selectedTextEditable = event.data.payload.selectedTextEditable === true;
|
|
2203
|
-
state.draftTargetScope = event.data.payload.draftTargetScope;
|
|
2204
2107
|
state.draftPayload = event.data.payload.draft;
|
|
2205
2108
|
state.draftPayloads = event.data.payload.drafts ?? (event.data.payload.draft ? [event.data.payload.draft] : []);
|
|
2206
2109
|
state.pendingSort = event.data.payload.pendingSort
|
|
@@ -2218,8 +2121,6 @@ export function installPreviewPickerRuntime() {
|
|
|
2218
2121
|
sessionId: state.activeSessionId,
|
|
2219
2122
|
mode: event.data.payload.mode,
|
|
2220
2123
|
selectedNodeId: event.data.payload.selectedNodeId,
|
|
2221
|
-
selectedTextEditable: event.data.payload.selectedTextEditable,
|
|
2222
|
-
draftTargetScope: event.data.payload.draftTargetScope,
|
|
2223
2124
|
hasDraft: Boolean(event.data.payload.draft),
|
|
2224
2125
|
hasPendingSort: Boolean(event.data.payload.pendingSort),
|
|
2225
2126
|
pageKey: event.data.payload.pageKey,
|
|
@@ -2233,12 +2134,9 @@ export function installPreviewPickerRuntime() {
|
|
|
2233
2134
|
state.activeSessionId = null;
|
|
2234
2135
|
state.selectedElement = null;
|
|
2235
2136
|
state.hoveredElement = null;
|
|
2236
|
-
state.selectedTextEditable = false;
|
|
2237
|
-
state.draftTargetScope = "single";
|
|
2238
2137
|
state.draftPayload = null;
|
|
2239
2138
|
state.draftPayloads = [];
|
|
2240
2139
|
state.pendingSort = null;
|
|
2241
|
-
disableInlineTextEditing(state);
|
|
2242
2140
|
clearOverlay(state);
|
|
2243
2141
|
applySortableAffordance(state, false);
|
|
2244
2142
|
logPreviewPickerRuntime("stop-session", {
|
|
@@ -9,7 +9,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
9
9
|
const [queryClient] = React.useState(() => makeQueryClient());
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
|
-
<ThemeProvider attribute="class" defaultTheme="
|
|
12
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
13
13
|
<QueryClientProvider client={queryClient}>
|
|
14
14
|
<TooltipProvider>
|
|
15
15
|
<Toaster />
|