mlola-ui 1.0.0 → 1.0.2
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/package.json +2 -2
- package/registry/assets.json +578 -0
- package/registry/index.json +38 -38
- package/registry/source/packages/components/checkbox/checkbox.tsx +3 -1
- package/registry/source-manifest.json +1 -1
- package/src/assets.js +90 -0
- package/src/cli.js +37 -3
- package/src/config.js +1 -0
- package/src/pro.js +7 -1
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mlola-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Source-copy CLI that writes framework-free Mlola UI items into your project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"mlola-ui": "
|
|
7
|
+
"mlola-ui": "bin/index.js"
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./src/cli.js"
|
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"source": "https://ui.mlola.com/asset-files",
|
|
4
|
+
"items": [
|
|
5
|
+
{
|
|
6
|
+
"id": "chat-empty",
|
|
7
|
+
"kind": "2d",
|
|
8
|
+
"title": "No messages",
|
|
9
|
+
"summary": "Two speech bubbles, one still typing. For conversations and assistants before the first message.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"empty-state",
|
|
12
|
+
"chat",
|
|
13
|
+
"ai"
|
|
14
|
+
],
|
|
15
|
+
"themeable": true,
|
|
16
|
+
"files": [
|
|
17
|
+
{
|
|
18
|
+
"path": "chat-empty.svg",
|
|
19
|
+
"role": "source",
|
|
20
|
+
"bytes": 1178,
|
|
21
|
+
"integrity": "sha256-05O1KM7c9gEETSSLRYmQKVhhP3Vzg9NsDU/ROCOH7oA="
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "chat-empty.tsx",
|
|
25
|
+
"role": "react",
|
|
26
|
+
"bytes": 2053,
|
|
27
|
+
"integrity": "sha256-2T65OESaI5widhosExy9CFQcBps17nq7rjkELdNtNSY="
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "empty-calendar",
|
|
33
|
+
"kind": "2d",
|
|
34
|
+
"title": "Empty calendar",
|
|
35
|
+
"summary": "A calendar page with one day picked. For schedules and bookings with nothing planned.",
|
|
36
|
+
"tags": [
|
|
37
|
+
"empty-state",
|
|
38
|
+
"calendar",
|
|
39
|
+
"scheduling"
|
|
40
|
+
],
|
|
41
|
+
"themeable": true,
|
|
42
|
+
"files": [
|
|
43
|
+
{
|
|
44
|
+
"path": "empty-calendar.svg",
|
|
45
|
+
"role": "source",
|
|
46
|
+
"bytes": 2065,
|
|
47
|
+
"integrity": "sha256-cznZC+Rb+M0YwzRxAzrEPrexpNQoEOpYquSeOyu5t6c="
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"path": "empty-calendar.tsx",
|
|
51
|
+
"role": "react",
|
|
52
|
+
"bytes": 3076,
|
|
53
|
+
"integrity": "sha256-Y3cKOYK124hl2XIEkOSwND/Wz/9waVSvWRKFs0RnknQ="
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "empty-cart",
|
|
59
|
+
"kind": "2d",
|
|
60
|
+
"title": "Empty cart",
|
|
61
|
+
"summary": "A shopping cart with nothing in it. For carts, baskets and wish lists.",
|
|
62
|
+
"tags": [
|
|
63
|
+
"empty-state",
|
|
64
|
+
"commerce",
|
|
65
|
+
"cart"
|
|
66
|
+
],
|
|
67
|
+
"themeable": true,
|
|
68
|
+
"files": [
|
|
69
|
+
{
|
|
70
|
+
"path": "empty-cart.svg",
|
|
71
|
+
"role": "source",
|
|
72
|
+
"bytes": 1196,
|
|
73
|
+
"integrity": "sha256-N6wspN+sbKsANvtN5iZnIpULyu5bY3/XZIkNh3/8hOY="
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"path": "empty-cart.tsx",
|
|
77
|
+
"role": "react",
|
|
78
|
+
"bytes": 2052,
|
|
79
|
+
"integrity": "sha256-jgubjdRwZ9DnNxZK6Hm26dIIzTh+ogkfmQRGziPSeuY="
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "empty-folder",
|
|
85
|
+
"kind": "2d",
|
|
86
|
+
"title": "Empty folder",
|
|
87
|
+
"summary": "An open folder waiting for its first file. For projects, drives and collections.",
|
|
88
|
+
"tags": [
|
|
89
|
+
"empty-state",
|
|
90
|
+
"files",
|
|
91
|
+
"projects"
|
|
92
|
+
],
|
|
93
|
+
"themeable": true,
|
|
94
|
+
"files": [
|
|
95
|
+
{
|
|
96
|
+
"path": "empty-folder.svg",
|
|
97
|
+
"role": "source",
|
|
98
|
+
"bytes": 961,
|
|
99
|
+
"integrity": "sha256-3UpQpzsG6dTlczi5f/oFvYHanoE3y3NhzpLG4vn7zWY="
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"path": "empty-folder.tsx",
|
|
103
|
+
"role": "react",
|
|
104
|
+
"bytes": 1817,
|
|
105
|
+
"integrity": "sha256-G/sYUo3LF0XIU8rG37uEKHKcjqcDRfjtVx+dfzQd3m8="
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "empty-inbox",
|
|
111
|
+
"kind": "2d",
|
|
112
|
+
"title": "Empty inbox",
|
|
113
|
+
"summary": "An open tray with a letter hovering above it. For an inbox or feed with nothing new.",
|
|
114
|
+
"tags": [
|
|
115
|
+
"empty-state",
|
|
116
|
+
"mail",
|
|
117
|
+
"inbox"
|
|
118
|
+
],
|
|
119
|
+
"themeable": true,
|
|
120
|
+
"files": [
|
|
121
|
+
{
|
|
122
|
+
"path": "empty-inbox.svg",
|
|
123
|
+
"role": "source",
|
|
124
|
+
"bytes": 1359,
|
|
125
|
+
"integrity": "sha256-MneexxesVlfLiMXrBGeP5uxq/4KnJE+AtXoYCeD2FEs="
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"path": "empty-inbox.tsx",
|
|
129
|
+
"role": "react",
|
|
130
|
+
"bytes": 2234,
|
|
131
|
+
"integrity": "sha256-f0vYKRpqhCzF6E7wgOXB9XUMqEJjTRJO+g37f9fwqBE="
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "integrations",
|
|
137
|
+
"kind": "2d",
|
|
138
|
+
"title": "Integrations",
|
|
139
|
+
"summary": "Two tiles joined by a line. For connecting apps, APIs and first-run setup.",
|
|
140
|
+
"tags": [
|
|
141
|
+
"onboarding",
|
|
142
|
+
"integrations",
|
|
143
|
+
"workflow"
|
|
144
|
+
],
|
|
145
|
+
"themeable": true,
|
|
146
|
+
"files": [
|
|
147
|
+
{
|
|
148
|
+
"path": "integrations.svg",
|
|
149
|
+
"role": "source",
|
|
150
|
+
"bytes": 1446,
|
|
151
|
+
"integrity": "sha256-89lYJP+281uv0mo2kvjpmT+EQhafRAsmEQNFn8GJoy4="
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"path": "integrations.tsx",
|
|
155
|
+
"role": "react",
|
|
156
|
+
"bytes": 2339,
|
|
157
|
+
"integrity": "sha256-Y0XlA0UYv7WRZwhyn7JyT4nKe4aErBRKiy71Yee2WTs="
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"id": "no-results",
|
|
163
|
+
"kind": "2d",
|
|
164
|
+
"title": "No results",
|
|
165
|
+
"summary": "A magnifier over an empty list. For searches and filters that match nothing.",
|
|
166
|
+
"tags": [
|
|
167
|
+
"empty-state",
|
|
168
|
+
"search",
|
|
169
|
+
"filter"
|
|
170
|
+
],
|
|
171
|
+
"themeable": true,
|
|
172
|
+
"files": [
|
|
173
|
+
{
|
|
174
|
+
"path": "no-results.svg",
|
|
175
|
+
"role": "source",
|
|
176
|
+
"bytes": 1436,
|
|
177
|
+
"integrity": "sha256-rtyNnxYnr8K9xn/W6wupyhEzLv4+9CQY6//YjTaEnUI="
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"path": "no-results.tsx",
|
|
181
|
+
"role": "react",
|
|
182
|
+
"bytes": 2330,
|
|
183
|
+
"integrity": "sha256-lCjEqxAhq1oisb9luFl8Poz6GBY0o4SOTd/6+SliWYM="
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "not-found",
|
|
189
|
+
"kind": "2d",
|
|
190
|
+
"title": "Not found",
|
|
191
|
+
"summary": "A folded map with a pin beside the path. For 404 pages and missing records.",
|
|
192
|
+
"tags": [
|
|
193
|
+
"error",
|
|
194
|
+
"404",
|
|
195
|
+
"navigation"
|
|
196
|
+
],
|
|
197
|
+
"themeable": true,
|
|
198
|
+
"files": [
|
|
199
|
+
{
|
|
200
|
+
"path": "not-found.svg",
|
|
201
|
+
"role": "source",
|
|
202
|
+
"bytes": 1049,
|
|
203
|
+
"integrity": "sha256-r0hmYKPp4lqkJyliyIKunk6joN6yqzjHargCMxUCVAk="
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"path": "not-found.tsx",
|
|
207
|
+
"role": "react",
|
|
208
|
+
"bytes": 1889,
|
|
209
|
+
"integrity": "sha256-mPasK7vn4NlBt7QXGj1E+vhjucx+eV8JhJuPBbLekrY="
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": "offline",
|
|
215
|
+
"kind": "2d",
|
|
216
|
+
"title": "Offline",
|
|
217
|
+
"summary": "A signal with a broken arc. For lost connections and sync paused.",
|
|
218
|
+
"tags": [
|
|
219
|
+
"error",
|
|
220
|
+
"network",
|
|
221
|
+
"offline"
|
|
222
|
+
],
|
|
223
|
+
"themeable": true,
|
|
224
|
+
"files": [
|
|
225
|
+
{
|
|
226
|
+
"path": "offline.svg",
|
|
227
|
+
"role": "source",
|
|
228
|
+
"bytes": 1076,
|
|
229
|
+
"integrity": "sha256-jPJMKLzp8AIbFRJk/XXDMqIErvnWrYzeO/1bkuHtUYM="
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"path": "offline.tsx",
|
|
233
|
+
"role": "react",
|
|
234
|
+
"bytes": 1895,
|
|
235
|
+
"integrity": "sha256-NDyHpLTig5lcNA+2e/AyEkSk++1pFKT6hrAfP7/1LFU="
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "secure",
|
|
241
|
+
"kind": "2d",
|
|
242
|
+
"title": "Secure",
|
|
243
|
+
"summary": "A shield holding a padlock. For security settings, privacy and verified accounts.",
|
|
244
|
+
"tags": [
|
|
245
|
+
"security",
|
|
246
|
+
"privacy",
|
|
247
|
+
"auth"
|
|
248
|
+
],
|
|
249
|
+
"themeable": true,
|
|
250
|
+
"files": [
|
|
251
|
+
{
|
|
252
|
+
"path": "secure.svg",
|
|
253
|
+
"role": "source",
|
|
254
|
+
"bytes": 1157,
|
|
255
|
+
"integrity": "sha256-S7DfI9tITKPV9MpG3iVuPGlvxM1U6tC7DMb8gsBd/Sc="
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"path": "secure.tsx",
|
|
259
|
+
"role": "react",
|
|
260
|
+
"bytes": 2003,
|
|
261
|
+
"integrity": "sha256-Aqs8ovnE6JkvOc/yCu+/CoCjkxXYIsUInNJsyv4zORw="
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"id": "success",
|
|
267
|
+
"kind": "2d",
|
|
268
|
+
"title": "Success",
|
|
269
|
+
"summary": "A check in a circle with a little confetti. For completed payments, sign-ups and saves.",
|
|
270
|
+
"tags": [
|
|
271
|
+
"success",
|
|
272
|
+
"confirmation",
|
|
273
|
+
"done"
|
|
274
|
+
],
|
|
275
|
+
"themeable": true,
|
|
276
|
+
"files": [
|
|
277
|
+
{
|
|
278
|
+
"path": "success.svg",
|
|
279
|
+
"role": "source",
|
|
280
|
+
"bytes": 1249,
|
|
281
|
+
"integrity": "sha256-FH8FNIiTorXNtUoSs65z1dV+sdy0rTxT0T0KytHpm6c="
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"path": "success.tsx",
|
|
285
|
+
"role": "react",
|
|
286
|
+
"bytes": 2144,
|
|
287
|
+
"integrity": "sha256-OLuX17yr/GLK7fKT2+KAQJPN1paz9bjNWFWi+zYAX5Y="
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"id": "upload",
|
|
293
|
+
"kind": "2d",
|
|
294
|
+
"title": "Upload",
|
|
295
|
+
"summary": "A cloud taking an arrow. For drop zones, imports and the first file.",
|
|
296
|
+
"tags": [
|
|
297
|
+
"upload",
|
|
298
|
+
"files",
|
|
299
|
+
"import"
|
|
300
|
+
],
|
|
301
|
+
"themeable": true,
|
|
302
|
+
"files": [
|
|
303
|
+
{
|
|
304
|
+
"path": "upload.svg",
|
|
305
|
+
"role": "source",
|
|
306
|
+
"bytes": 932,
|
|
307
|
+
"integrity": "sha256-0NHK1mfA2SwiJhf1xXK8SxdHqQnxSoZh3t8uy6wTEtQ="
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"path": "upload.tsx",
|
|
311
|
+
"role": "react",
|
|
312
|
+
"bytes": 1749,
|
|
313
|
+
"integrity": "sha256-6KlLF4kSQi4oZf923bPvET2CCgSzUYh+i0vvQmHNG8g="
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"id": "blocks",
|
|
319
|
+
"kind": "3d",
|
|
320
|
+
"title": "Building blocks",
|
|
321
|
+
"summary": "Three rounded blocks, stacked. For onboarding, empty workspaces and anything built piece by piece.",
|
|
322
|
+
"tags": [
|
|
323
|
+
"onboarding",
|
|
324
|
+
"empty-state",
|
|
325
|
+
"components"
|
|
326
|
+
],
|
|
327
|
+
"themeable": true,
|
|
328
|
+
"files": [
|
|
329
|
+
{
|
|
330
|
+
"path": "blocks.glb",
|
|
331
|
+
"role": "source",
|
|
332
|
+
"bytes": 123736,
|
|
333
|
+
"integrity": "sha256-hTc1jHfDajmF6Gbhutm6tPiqGy1YScEe+zM4DA/4528="
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"path": "blocks-poster.webp",
|
|
337
|
+
"role": "poster",
|
|
338
|
+
"bytes": 14018,
|
|
339
|
+
"integrity": "sha256-C2XC9bKHwG4OsvlE5Qfr8wU7eadZe1PpnUqNyB0Wsj0="
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"id": "chat",
|
|
345
|
+
"kind": "3d",
|
|
346
|
+
"title": "Chat bubble",
|
|
347
|
+
"summary": "A speech bubble with a typing indicator. Messages, assistants and support.",
|
|
348
|
+
"tags": [
|
|
349
|
+
"chat",
|
|
350
|
+
"ai",
|
|
351
|
+
"support"
|
|
352
|
+
],
|
|
353
|
+
"themeable": true,
|
|
354
|
+
"files": [
|
|
355
|
+
{
|
|
356
|
+
"path": "chat.glb",
|
|
357
|
+
"role": "source",
|
|
358
|
+
"bytes": 83024,
|
|
359
|
+
"integrity": "sha256-W9+fEDcKZ+qK/i9VJ6L8YX7TSAlZDY/65X18whgsRKQ="
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"path": "chat-poster.webp",
|
|
363
|
+
"role": "poster",
|
|
364
|
+
"bytes": 19110,
|
|
365
|
+
"integrity": "sha256-aCQGs7NFLzexJWfJyLzszKC870p/HiW3jp8lwpIIPYI="
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"id": "folder",
|
|
371
|
+
"kind": "3d",
|
|
372
|
+
"title": "Folder",
|
|
373
|
+
"summary": "An open folder with a sheet inside. Files, projects and empty collections.",
|
|
374
|
+
"tags": [
|
|
375
|
+
"files",
|
|
376
|
+
"empty-state",
|
|
377
|
+
"projects"
|
|
378
|
+
],
|
|
379
|
+
"themeable": true,
|
|
380
|
+
"files": [
|
|
381
|
+
{
|
|
382
|
+
"path": "folder.glb",
|
|
383
|
+
"role": "source",
|
|
384
|
+
"bytes": 23248,
|
|
385
|
+
"integrity": "sha256-GAhcw2QvaAcREhWklL9d0UUjEz+ihLKMsPnAm8dwXWs="
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"path": "folder-poster.webp",
|
|
389
|
+
"role": "poster",
|
|
390
|
+
"bytes": 15774,
|
|
391
|
+
"integrity": "sha256-XIpqD76YrUodQQpFRxDeRre6E3WrCoVgma+nkwxpK3g="
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"id": "gear",
|
|
397
|
+
"kind": "3d",
|
|
398
|
+
"title": "Gear",
|
|
399
|
+
"summary": "A bevelled gear on a metal hub. Settings, automation and anything that runs.",
|
|
400
|
+
"tags": [
|
|
401
|
+
"settings",
|
|
402
|
+
"automation",
|
|
403
|
+
"workflow"
|
|
404
|
+
],
|
|
405
|
+
"themeable": true,
|
|
406
|
+
"files": [
|
|
407
|
+
{
|
|
408
|
+
"path": "gear.glb",
|
|
409
|
+
"role": "source",
|
|
410
|
+
"bytes": 90120,
|
|
411
|
+
"integrity": "sha256-ZAB8sC9zKtl91yziF9KsK94v80310Go414rfbTYTIBc="
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
"path": "gear-poster.webp",
|
|
415
|
+
"role": "poster",
|
|
416
|
+
"bytes": 25034,
|
|
417
|
+
"integrity": "sha256-h4ygoRhb6mduALZlbYCNsJk/sl6MhFJJeYhX4nzxNU8="
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"id": "layers",
|
|
423
|
+
"kind": "3d",
|
|
424
|
+
"title": "Layers",
|
|
425
|
+
"summary": "Three slabs, gently fanned. Tokens, themes, stacks and anything with levels.",
|
|
426
|
+
"tags": [
|
|
427
|
+
"theming",
|
|
428
|
+
"tokens",
|
|
429
|
+
"stack"
|
|
430
|
+
],
|
|
431
|
+
"themeable": true,
|
|
432
|
+
"files": [
|
|
433
|
+
{
|
|
434
|
+
"path": "layers.glb",
|
|
435
|
+
"role": "source",
|
|
436
|
+
"bytes": 117840,
|
|
437
|
+
"integrity": "sha256-Jk6Sc/9+vjCIYfc8VCvDgdemoW2W68roRGZTA0iGCxI="
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"path": "layers-poster.webp",
|
|
441
|
+
"role": "poster",
|
|
442
|
+
"bytes": 10430,
|
|
443
|
+
"integrity": "sha256-17LDN5pNVHVXqHIKqNF2LjE0x+EzsUUjbflQaSeOx8Q="
|
|
444
|
+
}
|
|
445
|
+
]
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"id": "orb",
|
|
449
|
+
"kind": "3d",
|
|
450
|
+
"title": "Orb",
|
|
451
|
+
"summary": "A sphere in a tilted ring. AI, voice, and anything that listens or thinks.",
|
|
452
|
+
"tags": [
|
|
453
|
+
"ai",
|
|
454
|
+
"voice",
|
|
455
|
+
"status"
|
|
456
|
+
],
|
|
457
|
+
"themeable": true,
|
|
458
|
+
"files": [
|
|
459
|
+
{
|
|
460
|
+
"path": "orb.glb",
|
|
461
|
+
"role": "source",
|
|
462
|
+
"bytes": 139156,
|
|
463
|
+
"integrity": "sha256-GSHJxonm2LffAc1RMwRYtGyHNJ2TumqfrV4e/o4f/zs="
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
"path": "orb-poster.webp",
|
|
467
|
+
"role": "poster",
|
|
468
|
+
"bytes": 22332,
|
|
469
|
+
"integrity": "sha256-oDj6nZrzKB0u4MOcVEWRDgmtAb4FpSeFYx1CGxZ7U4s="
|
|
470
|
+
}
|
|
471
|
+
]
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"id": "package",
|
|
475
|
+
"kind": "3d",
|
|
476
|
+
"title": "Package",
|
|
477
|
+
"summary": "A taped parcel. Orders, shipping, installs and deliveries.",
|
|
478
|
+
"tags": [
|
|
479
|
+
"commerce",
|
|
480
|
+
"shipping",
|
|
481
|
+
"install"
|
|
482
|
+
],
|
|
483
|
+
"themeable": true,
|
|
484
|
+
"files": [
|
|
485
|
+
{
|
|
486
|
+
"path": "package.glb",
|
|
487
|
+
"role": "source",
|
|
488
|
+
"bytes": 63172,
|
|
489
|
+
"integrity": "sha256-2RcjObZqHS0+mz1XwwX2Xe+Gx7ce5GcER8WXBoxfFLw="
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"path": "package-poster.webp",
|
|
493
|
+
"role": "poster",
|
|
494
|
+
"bytes": 15542,
|
|
495
|
+
"integrity": "sha256-MEjWW6gOTGCZPTwg48br8tgGwSXxx5dBBdjTgDZyyLo="
|
|
496
|
+
}
|
|
497
|
+
]
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"id": "padlock",
|
|
501
|
+
"kind": "3d",
|
|
502
|
+
"title": "Padlock",
|
|
503
|
+
"summary": "A closed padlock with a metal shackle. Sign-in, locked content and licences.",
|
|
504
|
+
"tags": [
|
|
505
|
+
"auth",
|
|
506
|
+
"security",
|
|
507
|
+
"pro"
|
|
508
|
+
],
|
|
509
|
+
"themeable": true,
|
|
510
|
+
"files": [
|
|
511
|
+
{
|
|
512
|
+
"path": "padlock.glb",
|
|
513
|
+
"role": "source",
|
|
514
|
+
"bytes": 135232,
|
|
515
|
+
"integrity": "sha256-+kD9l10nq/4SVn0+8AqVsqJJrnsVEAQYcz5GubrWEFQ="
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"path": "padlock-poster.webp",
|
|
519
|
+
"role": "poster",
|
|
520
|
+
"bytes": 16918,
|
|
521
|
+
"integrity": "sha256-js5IRav1fho9ktiqDXUWE8Qvvg8rMCMchTsJ/IcNuYQ="
|
|
522
|
+
}
|
|
523
|
+
]
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"id": "rocket",
|
|
527
|
+
"kind": "3d",
|
|
528
|
+
"title": "Rocket",
|
|
529
|
+
"summary": "A small rocket with three fins. Launches, upgrades and getting started.",
|
|
530
|
+
"tags": [
|
|
531
|
+
"launch",
|
|
532
|
+
"onboarding",
|
|
533
|
+
"growth"
|
|
534
|
+
],
|
|
535
|
+
"themeable": true,
|
|
536
|
+
"files": [
|
|
537
|
+
{
|
|
538
|
+
"path": "rocket.glb",
|
|
539
|
+
"role": "source",
|
|
540
|
+
"bytes": 133184,
|
|
541
|
+
"integrity": "sha256-c2dVDhZ0kfms6osU9FB4ErRkrvUmN54pmn6/uJMGjL8="
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"path": "rocket-poster.webp",
|
|
545
|
+
"role": "poster",
|
|
546
|
+
"bytes": 13722,
|
|
547
|
+
"integrity": "sha256-mjVFGM9PKNfWeenNn216kd2yqb6Fe9J3rQX7W9NJr7M="
|
|
548
|
+
}
|
|
549
|
+
]
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"id": "shield",
|
|
553
|
+
"kind": "3d",
|
|
554
|
+
"title": "Shield",
|
|
555
|
+
"summary": "A shield carrying a check. Security, privacy and verified states.",
|
|
556
|
+
"tags": [
|
|
557
|
+
"security",
|
|
558
|
+
"privacy",
|
|
559
|
+
"success"
|
|
560
|
+
],
|
|
561
|
+
"themeable": true,
|
|
562
|
+
"files": [
|
|
563
|
+
{
|
|
564
|
+
"path": "shield.glb",
|
|
565
|
+
"role": "source",
|
|
566
|
+
"bytes": 41784,
|
|
567
|
+
"integrity": "sha256-6f15gHhncGozTpcrwmG2U0KsEKw7K9uz6cgOfoUUsUA="
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
"path": "shield-poster.webp",
|
|
571
|
+
"role": "poster",
|
|
572
|
+
"bytes": 18298,
|
|
573
|
+
"integrity": "sha256-xtBgLYPOty5299iL7jCjV8qdsC5oVKi/LnYvubBpZMw="
|
|
574
|
+
}
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
}
|
package/registry/index.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "./schema/registry-index.schema.json",
|
|
3
3
|
"schemaVersion": 2,
|
|
4
4
|
"name": "mlola-ui",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.2",
|
|
6
6
|
"homepage": "https://ui.mlola.com",
|
|
7
7
|
"themeContract": {
|
|
8
8
|
"attribute": "data-theme",
|
|
@@ -179,8 +179,8 @@
|
|
|
179
179
|
},
|
|
180
180
|
"registryDependencies": [],
|
|
181
181
|
"engineDependencies": {
|
|
182
|
-
"@mlola-ui/behavior": "^1.0.
|
|
183
|
-
"@mlola-ui/icons": "^1.0.
|
|
182
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
183
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
184
184
|
},
|
|
185
185
|
"files": [
|
|
186
186
|
{
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
},
|
|
237
237
|
"registryDependencies": [],
|
|
238
238
|
"engineDependencies": {
|
|
239
|
-
"@mlola-ui/icons": "^1.0.
|
|
239
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
240
240
|
},
|
|
241
241
|
"files": [
|
|
242
242
|
{
|
|
@@ -352,7 +352,7 @@
|
|
|
352
352
|
},
|
|
353
353
|
"registryDependencies": [],
|
|
354
354
|
"engineDependencies": {
|
|
355
|
-
"@mlola-ui/icons": "^1.0.
|
|
355
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
356
356
|
},
|
|
357
357
|
"files": [
|
|
358
358
|
{
|
|
@@ -401,7 +401,7 @@
|
|
|
401
401
|
},
|
|
402
402
|
"registryDependencies": [],
|
|
403
403
|
"engineDependencies": {
|
|
404
|
-
"@mlola-ui/icons": "^1.0.
|
|
404
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
405
405
|
},
|
|
406
406
|
"files": [
|
|
407
407
|
{
|
|
@@ -463,7 +463,7 @@
|
|
|
463
463
|
},
|
|
464
464
|
"registryDependencies": [],
|
|
465
465
|
"engineDependencies": {
|
|
466
|
-
"@mlola-ui/motion": "^1.0.
|
|
466
|
+
"@mlola-ui/motion": "^1.0.2"
|
|
467
467
|
},
|
|
468
468
|
"files": [
|
|
469
469
|
{
|
|
@@ -567,8 +567,8 @@
|
|
|
567
567
|
},
|
|
568
568
|
"registryDependencies": [],
|
|
569
569
|
"engineDependencies": {
|
|
570
|
-
"@mlola-ui/behavior": "^1.0.
|
|
571
|
-
"@mlola-ui/icons": "^1.0.
|
|
570
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
571
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
572
572
|
},
|
|
573
573
|
"files": [
|
|
574
574
|
{
|
|
@@ -618,7 +618,7 @@
|
|
|
618
618
|
},
|
|
619
619
|
"registryDependencies": [],
|
|
620
620
|
"engineDependencies": {
|
|
621
|
-
"@mlola-ui/icons": "^1.0.
|
|
621
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
622
622
|
},
|
|
623
623
|
"files": [
|
|
624
624
|
{
|
|
@@ -631,7 +631,7 @@
|
|
|
631
631
|
"path": "packages/components/checkbox/checkbox.tsx",
|
|
632
632
|
"target": "{{aliases.components}}/checkbox.tsx",
|
|
633
633
|
"type": "registry:ui",
|
|
634
|
-
"integrity": "sha256-
|
|
634
|
+
"integrity": "sha256-cqTFwYwNPRxKiBnXXWkcFeDlJ6tpJ9GX4IdqrYRp9Fs="
|
|
635
635
|
}
|
|
636
636
|
],
|
|
637
637
|
"themeContract": {
|
|
@@ -670,7 +670,7 @@
|
|
|
670
670
|
"modal"
|
|
671
671
|
],
|
|
672
672
|
"engineDependencies": {
|
|
673
|
-
"@mlola-ui/icons": "^1.0.
|
|
673
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
674
674
|
},
|
|
675
675
|
"files": [
|
|
676
676
|
{
|
|
@@ -732,8 +732,8 @@
|
|
|
732
732
|
},
|
|
733
733
|
"registryDependencies": [],
|
|
734
734
|
"engineDependencies": {
|
|
735
|
-
"@mlola-ui/behavior": "^1.0.
|
|
736
|
-
"@mlola-ui/icons": "^1.0.
|
|
735
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
736
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
737
737
|
},
|
|
738
738
|
"files": [
|
|
739
739
|
{
|
|
@@ -784,7 +784,7 @@
|
|
|
784
784
|
"input"
|
|
785
785
|
],
|
|
786
786
|
"engineDependencies": {
|
|
787
|
-
"@mlola-ui/icons": "^1.0.
|
|
787
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
788
788
|
},
|
|
789
789
|
"files": [
|
|
790
790
|
{
|
|
@@ -980,8 +980,8 @@
|
|
|
980
980
|
},
|
|
981
981
|
"registryDependencies": [],
|
|
982
982
|
"engineDependencies": {
|
|
983
|
-
"@mlola-ui/behavior": "^1.0.
|
|
984
|
-
"@mlola-ui/icons": "^1.0.
|
|
983
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
984
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
985
985
|
},
|
|
986
986
|
"files": [
|
|
987
987
|
{
|
|
@@ -1086,7 +1086,7 @@
|
|
|
1086
1086
|
},
|
|
1087
1087
|
"registryDependencies": [],
|
|
1088
1088
|
"engineDependencies": {
|
|
1089
|
-
"@mlola-ui/icons": "^1.0.
|
|
1089
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
1090
1090
|
},
|
|
1091
1091
|
"files": [
|
|
1092
1092
|
{
|
|
@@ -1394,7 +1394,7 @@
|
|
|
1394
1394
|
},
|
|
1395
1395
|
"registryDependencies": [],
|
|
1396
1396
|
"engineDependencies": {
|
|
1397
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1397
|
+
"@mlola-ui/behavior": "^1.0.2"
|
|
1398
1398
|
},
|
|
1399
1399
|
"files": [
|
|
1400
1400
|
{
|
|
@@ -1448,8 +1448,8 @@
|
|
|
1448
1448
|
},
|
|
1449
1449
|
"registryDependencies": [],
|
|
1450
1450
|
"engineDependencies": {
|
|
1451
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1452
|
-
"@mlola-ui/icons": "^1.0.
|
|
1451
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
1452
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
1453
1453
|
},
|
|
1454
1454
|
"files": [
|
|
1455
1455
|
{
|
|
@@ -1520,8 +1520,8 @@
|
|
|
1520
1520
|
},
|
|
1521
1521
|
"registryDependencies": [],
|
|
1522
1522
|
"engineDependencies": {
|
|
1523
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1524
|
-
"@mlola-ui/icons": "^1.0.
|
|
1523
|
+
"@mlola-ui/behavior": "^1.0.2",
|
|
1524
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
1525
1525
|
},
|
|
1526
1526
|
"files": [
|
|
1527
1527
|
{
|
|
@@ -1628,7 +1628,7 @@
|
|
|
1628
1628
|
},
|
|
1629
1629
|
"registryDependencies": [],
|
|
1630
1630
|
"engineDependencies": {
|
|
1631
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1631
|
+
"@mlola-ui/behavior": "^1.0.2"
|
|
1632
1632
|
},
|
|
1633
1633
|
"files": [
|
|
1634
1634
|
{
|
|
@@ -1735,7 +1735,7 @@
|
|
|
1735
1735
|
},
|
|
1736
1736
|
"registryDependencies": [],
|
|
1737
1737
|
"engineDependencies": {
|
|
1738
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1738
|
+
"@mlola-ui/behavior": "^1.0.2"
|
|
1739
1739
|
},
|
|
1740
1740
|
"files": [
|
|
1741
1741
|
{
|
|
@@ -1837,7 +1837,7 @@
|
|
|
1837
1837
|
},
|
|
1838
1838
|
"registryDependencies": [],
|
|
1839
1839
|
"engineDependencies": {
|
|
1840
|
-
"@mlola-ui/icons": "^1.0.
|
|
1840
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
1841
1841
|
},
|
|
1842
1842
|
"files": [
|
|
1843
1843
|
{
|
|
@@ -1893,7 +1893,7 @@
|
|
|
1893
1893
|
},
|
|
1894
1894
|
"registryDependencies": [],
|
|
1895
1895
|
"engineDependencies": {
|
|
1896
|
-
"@mlola-ui/icons": "^1.0.
|
|
1896
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
1897
1897
|
},
|
|
1898
1898
|
"files": [
|
|
1899
1899
|
{
|
|
@@ -2102,7 +2102,7 @@
|
|
|
2102
2102
|
},
|
|
2103
2103
|
"registryDependencies": [],
|
|
2104
2104
|
"engineDependencies": {
|
|
2105
|
-
"@mlola-ui/icons": "^1.0.
|
|
2105
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2106
2106
|
},
|
|
2107
2107
|
"files": [
|
|
2108
2108
|
{
|
|
@@ -2161,7 +2161,7 @@
|
|
|
2161
2161
|
"popover"
|
|
2162
2162
|
],
|
|
2163
2163
|
"engineDependencies": {
|
|
2164
|
-
"@mlola-ui/icons": "^1.0.
|
|
2164
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2165
2165
|
},
|
|
2166
2166
|
"files": [
|
|
2167
2167
|
{
|
|
@@ -2219,7 +2219,7 @@
|
|
|
2219
2219
|
"popover"
|
|
2220
2220
|
],
|
|
2221
2221
|
"engineDependencies": {
|
|
2222
|
-
"@mlola-ui/icons": "^1.0.
|
|
2222
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2223
2223
|
},
|
|
2224
2224
|
"files": [
|
|
2225
2225
|
{
|
|
@@ -2383,7 +2383,7 @@
|
|
|
2383
2383
|
"input"
|
|
2384
2384
|
],
|
|
2385
2385
|
"engineDependencies": {
|
|
2386
|
-
"@mlola-ui/icons": "^1.0.
|
|
2386
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2387
2387
|
},
|
|
2388
2388
|
"files": [
|
|
2389
2389
|
{
|
|
@@ -2448,7 +2448,7 @@
|
|
|
2448
2448
|
"input"
|
|
2449
2449
|
],
|
|
2450
2450
|
"engineDependencies": {
|
|
2451
|
-
"@mlola-ui/icons": "^1.0.
|
|
2451
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2452
2452
|
},
|
|
2453
2453
|
"files": [
|
|
2454
2454
|
{
|
|
@@ -2500,7 +2500,7 @@
|
|
|
2500
2500
|
"input"
|
|
2501
2501
|
],
|
|
2502
2502
|
"engineDependencies": {
|
|
2503
|
-
"@mlola-ui/icons": "^1.0.
|
|
2503
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2504
2504
|
},
|
|
2505
2505
|
"files": [
|
|
2506
2506
|
{
|
|
@@ -2560,7 +2560,7 @@
|
|
|
2560
2560
|
"popover"
|
|
2561
2561
|
],
|
|
2562
2562
|
"engineDependencies": {
|
|
2563
|
-
"@mlola-ui/icons": "^1.0.
|
|
2563
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2564
2564
|
},
|
|
2565
2565
|
"files": [
|
|
2566
2566
|
{
|
|
@@ -2616,7 +2616,7 @@
|
|
|
2616
2616
|
},
|
|
2617
2617
|
"registryDependencies": [],
|
|
2618
2618
|
"engineDependencies": {
|
|
2619
|
-
"@mlola-ui/icons": "^1.0.
|
|
2619
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2620
2620
|
},
|
|
2621
2621
|
"files": [
|
|
2622
2622
|
{
|
|
@@ -2719,7 +2719,7 @@
|
|
|
2719
2719
|
},
|
|
2720
2720
|
"registryDependencies": [],
|
|
2721
2721
|
"engineDependencies": {
|
|
2722
|
-
"@mlola-ui/icons": "^1.0.
|
|
2722
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2723
2723
|
},
|
|
2724
2724
|
"files": [
|
|
2725
2725
|
{
|
|
@@ -2840,7 +2840,7 @@
|
|
|
2840
2840
|
},
|
|
2841
2841
|
"registryDependencies": [],
|
|
2842
2842
|
"engineDependencies": {
|
|
2843
|
-
"@mlola-ui/icons": "^1.0.
|
|
2843
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2844
2844
|
},
|
|
2845
2845
|
"files": [
|
|
2846
2846
|
{
|
|
@@ -2905,7 +2905,7 @@
|
|
|
2905
2905
|
"sheet"
|
|
2906
2906
|
],
|
|
2907
2907
|
"engineDependencies": {
|
|
2908
|
-
"@mlola-ui/icons": "^1.0.
|
|
2908
|
+
"@mlola-ui/icons": "^1.0.2"
|
|
2909
2909
|
},
|
|
2910
2910
|
"files": [
|
|
2911
2911
|
{
|
|
@@ -51,7 +51,9 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
51
51
|
<span className="ml-checkbox-copy">
|
|
52
52
|
{label ? (
|
|
53
53
|
<label htmlFor={inputId} className="ml-checkbox-label">
|
|
54
|
-
{
|
|
54
|
+
{/* One span, so a label with links in it reads as one sentence, not flex items. */}
|
|
55
|
+
<span className="ml-checkbox-text">{label}</span>
|
|
56
|
+
{required ? <span aria-hidden="true" className="ml-required-mark">*</span> : null}
|
|
55
57
|
</label>
|
|
56
58
|
) : null}
|
|
57
59
|
{description ? <span id={descriptionId} className="ml-checkbox-description">{description}</span> : null}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"packages/components/calendar/dates.ts": "sha256-mygYkoC70av2ZQ0vkxf885trwW97Wd10I4dptYQe+4A=",
|
|
19
19
|
"packages/components/card/card.tsx": "sha256-aMKbv5DWYYWq7GZAFR9O1fuYE0H61WCjkvEbRMOd894=",
|
|
20
20
|
"packages/components/carousel/carousel.tsx": "sha256-LAPKz9DG9vEBv/8jKjqgH7XiSEERkWWLr4n/Kve1omQ=",
|
|
21
|
-
"packages/components/checkbox/checkbox.tsx": "sha256-
|
|
21
|
+
"packages/components/checkbox/checkbox.tsx": "sha256-cqTFwYwNPRxKiBnXXWkcFeDlJ6tpJ9GX4IdqrYRp9Fs=",
|
|
22
22
|
"packages/components/color-picker/color-picker.tsx": "sha256-UziuULSI7dIGLfu4jjWIz6Cbh2/HiaY2KYXlfQ+6iQg=",
|
|
23
23
|
"packages/components/color-picker/color.ts": "sha256-3IO6DaelZ6TVn2aw+6o6pZCQGAQdeNRkN7sPypUzddE=",
|
|
24
24
|
"packages/components/combobox/combobox.tsx": "sha256-CnuJP01m0ZPMB4MGjoKbJCBQ7inI6bPf5aMDrq4m1qI=",
|
package/src/assets.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { targetRoot } from "./config.js";
|
|
5
|
+
import { BUNDLED_REGISTRY_ROOT, readJson } from "./registry.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 2D and 3D assets.
|
|
9
|
+
*
|
|
10
|
+
* Their files are not bundled with the CLI: a project wants three of them,
|
|
11
|
+
* not every model. The bundled index lists each file with its integrity; the
|
|
12
|
+
* files download from the site and are checked before anything is written.
|
|
13
|
+
*
|
|
14
|
+
* Static files (SVG, GLB, posters) land in the `assets` target, public/mlola
|
|
15
|
+
* by default, so a web app serves them as /mlola/2d/… and /mlola/3d/…. A 2D
|
|
16
|
+
* asset's React component lands beside your components, in illustrations/.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export function loadAssetIndex() {
|
|
20
|
+
const filename = path.join(BUNDLED_REGISTRY_ROOT, "assets.json");
|
|
21
|
+
if (!fs.existsSync(filename)) return { items: [] };
|
|
22
|
+
return readJson(filename);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const integrityOf = (bytes) => `sha256-${createHash("sha256").update(bytes).digest("base64")}`;
|
|
26
|
+
|
|
27
|
+
/** Where each of an asset's files goes in the project. */
|
|
28
|
+
export function assetTarget(config, item, file) {
|
|
29
|
+
if (file.role === "react") return path.join(targetRoot(config, "components"), "illustrations", file.path);
|
|
30
|
+
return path.join(targetRoot(config, "assets"), item.kind, file.path);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function addAssets(cwd, config, ids, { source, fetcher, overwrite = false }) {
|
|
34
|
+
const index = loadAssetIndex();
|
|
35
|
+
const known = new Map(index.items.map((item) => [item.id, item]));
|
|
36
|
+
const unknown = ids.filter((id) => !known.has(id));
|
|
37
|
+
if (unknown.length) {
|
|
38
|
+
throw new Error(`No asset named ${unknown.map((id) => `"${id}"`).join(", ")}. See them all with "npx mlola-ui list --kind asset".`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Download and verify everything first, so a failure writes nothing.
|
|
42
|
+
const planned = [];
|
|
43
|
+
for (const id of ids) {
|
|
44
|
+
const item = known.get(id);
|
|
45
|
+
for (const file of item.files) {
|
|
46
|
+
const url = `${source}/${item.kind}/${item.id}/${file.path}`;
|
|
47
|
+
let response;
|
|
48
|
+
try {
|
|
49
|
+
response = await fetcher(url);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
throw new Error(`Could not download ${url}: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
if (!response.ok) throw new Error(`Could not download ${url}: the server answered ${response.status}.`);
|
|
54
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
55
|
+
if (integrityOf(bytes) !== file.integrity) throw new Error(`${item.id}/${file.path} failed integrity validation; nothing was written.`);
|
|
56
|
+
planned.push({ item, file, bytes, relative: assetTarget(config, item, file) });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const result = { written: [], unchanged: [], conflicts: [], items: ids.map((id) => known.get(id)) };
|
|
61
|
+
for (const { bytes, relative } of planned) {
|
|
62
|
+
const filename = path.join(cwd, relative);
|
|
63
|
+
if (fs.existsSync(filename)) {
|
|
64
|
+
if (fs.readFileSync(filename).equals(bytes)) {
|
|
65
|
+
result.unchanged.push(relative);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (!overwrite) {
|
|
69
|
+
result.conflicts.push(relative);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
fs.mkdirSync(path.dirname(filename), { recursive: true });
|
|
74
|
+
fs.writeFileSync(filename, bytes);
|
|
75
|
+
result.written.push(relative);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A line on how to use each added asset. */
|
|
81
|
+
export function assetHint(config, item) {
|
|
82
|
+
const pascal = item.id.replace(/(^|-)([a-z0-9])/g, (_, __, letter) => letter.toUpperCase());
|
|
83
|
+
const assets = targetRoot(config, "assets");
|
|
84
|
+
const publicPath = assets.startsWith("public/") ? `/${assets.slice("public/".length)}` : `/${assets}`;
|
|
85
|
+
if (item.kind === "2d") {
|
|
86
|
+
const alias = (config.aliases?.components ?? "@/components/ui").replace(/\/$/, "");
|
|
87
|
+
return `${item.id}: import { ${pascal}Illustration } from "${alias}/illustrations/${item.id}"; it follows your theme. As a plain image: ${publicPath}/2d/${item.id}.svg`;
|
|
88
|
+
}
|
|
89
|
+
return `${item.id}: ${publicPath}/3d/${item.id}.glb, with its poster at ${publicPath}/3d/${item.id}-poster.webp. Materials are named primary, surface, accent, ink, neutral and metal, so a viewer can paint them from your theme.`;
|
|
90
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
targetRoot,
|
|
8
8
|
writeDefaultConfig,
|
|
9
9
|
} from "./config.js";
|
|
10
|
+
import { addAssets, assetHint, loadAssetIndex } from "./assets.js";
|
|
10
11
|
import { runDoctor } from "./doctor.js";
|
|
11
12
|
import { collectEngineDependencies, installItems } from "./installer.js";
|
|
12
13
|
import { loadCatalogNames, loadRegistry, resolveItems } from "./registry.js";
|
|
@@ -18,9 +19,10 @@ const HELP = `Mlola UI — source-copy components with Theme
|
|
|
18
19
|
Usage:
|
|
19
20
|
mlola-ui init [--force]
|
|
20
21
|
mlola-ui add <name...> [--overwrite] [--install|--yes]
|
|
22
|
+
mlola-ui add asset <id...> [--overwrite]
|
|
21
23
|
mlola-ui login <token> [--host <url>]
|
|
22
24
|
mlola-ui logout
|
|
23
|
-
mlola-ui list [--kind component|block|template] [--json]
|
|
25
|
+
mlola-ui list [--kind component|block|template|asset] [--json]
|
|
24
26
|
mlola-ui doctor
|
|
25
27
|
mlola-ui theme pull <theme-id | url> [--host <url>] [--overwrite]
|
|
26
28
|
|
|
@@ -29,6 +31,7 @@ Examples:
|
|
|
29
31
|
npx mlola-ui add button card
|
|
30
32
|
npx mlola-ui login mlp_… (Mlola Pro: a token from /account)
|
|
31
33
|
npx mlola-ui add conversation bot
|
|
34
|
+
npx mlola-ui add asset empty-inbox orb
|
|
32
35
|
npx mlola-ui list --kind block
|
|
33
36
|
npx mlola-ui theme pull https://ui.mlola.com/t/th-4k2x9qf7wz3m
|
|
34
37
|
`;
|
|
@@ -116,8 +119,22 @@ export async function run(argv, options = {}) {
|
|
|
116
119
|
if (command === "list") {
|
|
117
120
|
const registry = loadRegistry();
|
|
118
121
|
const kind = optionValue(args, "--kind");
|
|
119
|
-
if (kind && !["component", "block", "template"].includes(kind)) {
|
|
120
|
-
throw new Error(`--kind must be component, block, or
|
|
122
|
+
if (kind && !["component", "block", "template", "asset"].includes(kind)) {
|
|
123
|
+
throw new Error(`--kind must be component, block, template or asset (received "${kind}")`);
|
|
124
|
+
}
|
|
125
|
+
if (kind === "asset") {
|
|
126
|
+
const assets = loadAssetIndex().items;
|
|
127
|
+
if (hasFlag(args, "--json")) {
|
|
128
|
+
output.log(JSON.stringify(assets, null, 2));
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
for (const group of ["2d", "3d"]) {
|
|
132
|
+
const grouped = assets.filter((item) => item.kind === group);
|
|
133
|
+
if (!grouped.length) continue;
|
|
134
|
+
output.log(`${group === "2d" ? "Illustrations" : "3D models"} (${grouped.length})`);
|
|
135
|
+
for (const item of grouped) output.log(` ${item.id.padEnd(18)} ${item.summary}`);
|
|
136
|
+
}
|
|
137
|
+
return 0;
|
|
121
138
|
}
|
|
122
139
|
const items = kind
|
|
123
140
|
? registry.items.filter((item) => item.type === {
|
|
@@ -159,6 +176,23 @@ export async function run(argv, options = {}) {
|
|
|
159
176
|
return 0;
|
|
160
177
|
}
|
|
161
178
|
|
|
179
|
+
if (command === "add" && args[0] === "asset") {
|
|
180
|
+
const host = optionValue(args, "--host");
|
|
181
|
+
const ids = args.slice(1).filter((argument) => !argument.startsWith("-") && argument !== host);
|
|
182
|
+
if (!ids.length) throw new Error('Usage: mlola-ui add asset <id...>. See them with "npx mlola-ui list --kind asset".');
|
|
183
|
+
const config = loadConfig(cwd);
|
|
184
|
+
const source = env.MLOLA_ASSETS_URL?.replace(/\/$/, "") ?? `${hostFrom(env, host)}/asset-files`;
|
|
185
|
+
const result = await addAssets(cwd, config, ids, { source, fetcher, overwrite: hasFlag(args, "--overwrite") });
|
|
186
|
+
for (const filename of result.written) output.log(`✓ Added ${filename}`);
|
|
187
|
+
if (result.unchanged.length) output.log(`• ${result.unchanged.length} file(s) already up to date`);
|
|
188
|
+
if (result.conflicts.length) {
|
|
189
|
+
output.error(`✗ Refused to replace ${result.conflicts.length} modified file(s):\n ${result.conflicts.join("\n ")}\nRun again with --overwrite to replace them.`);
|
|
190
|
+
return 1;
|
|
191
|
+
}
|
|
192
|
+
for (const item of result.items) output.log(assetHint(config, item));
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
162
196
|
if (command === "add") {
|
|
163
197
|
const names = args.filter((argument) => !argument.startsWith("-"));
|
|
164
198
|
if (!names.length) throw new Error("Usage: mlola-ui add <name...>");
|
package/src/config.js
CHANGED
package/src/pro.js
CHANGED
|
@@ -66,7 +66,13 @@ async function request(fetcher, url, token, init = {}) {
|
|
|
66
66
|
|
|
67
67
|
/** Checks a token with the service before it is saved, so a typo fails at login rather than at add. */
|
|
68
68
|
export async function verifyToken(host, token, fetcher) {
|
|
69
|
-
if (!TOKEN_PATTERN.test(token))
|
|
69
|
+
if (!TOKEN_PATTERN.test(token)) {
|
|
70
|
+
// The account page lists tokens by their first characters only; the full token is shown once, when it is made.
|
|
71
|
+
if (/^mlp_[0-9a-z]*(…|\.\.\.)?$/.test(token) && token.length < 44) {
|
|
72
|
+
throw new Error(`That is only the start of a token, as the account page lists it. The full token (mlp_ and 40 characters) is shown once, when you create it: create a new one at ${host}/account and copy it whole.`);
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`That is not a Mlola Pro token. Tokens are mlp_ and 40 characters; create one at ${host}/account.`);
|
|
75
|
+
}
|
|
70
76
|
return request(fetcher, `${host}/api/pro/licence`, token);
|
|
71
77
|
}
|
|
72
78
|
|