poveste 0.5.3 → 0.6.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.
Files changed (50) hide show
  1. package/dist/node/bin.js +1 -1
  2. package/dist/node/build.d.ts.map +1 -1
  3. package/dist/node/build.js +31 -0
  4. package/dist/node/builtin-plugins/pinceau-tokens.js +2 -2
  5. package/dist/node/commands/port.d.ts +8 -0
  6. package/dist/node/commands/port.d.ts.map +1 -1
  7. package/dist/node/commands/port.js +11 -0
  8. package/dist/node/config.d.ts.map +1 -1
  9. package/dist/node/config.js +9 -2
  10. package/dist/node/index.d.ts +1 -0
  11. package/dist/node/index.d.ts.map +1 -1
  12. package/dist/node/index.js +3 -0
  13. package/dist/node/markdown.d.ts.map +1 -1
  14. package/dist/node/markdown.js +2 -10
  15. package/dist/node/server.d.ts.map +1 -1
  16. package/dist/node/server.js +16 -1
  17. package/dist/node/stories.d.ts.map +1 -1
  18. package/dist/node/stories.js +2 -10
  19. package/dist/node/util/watch-ignore.d.ts +3 -0
  20. package/dist/node/util/watch-ignore.d.ts.map +1 -0
  21. package/dist/node/util/watch-ignore.js +12 -0
  22. package/dist/node/virtual/resolved-generated-global-setup.d.ts.map +1 -1
  23. package/dist/node/virtual/resolved-generated-global-setup.js +13 -5
  24. package/dist/node/virtual/util.d.ts +11 -0
  25. package/dist/node/virtual/util.d.ts.map +1 -1
  26. package/dist/node/virtual/util.js +13 -0
  27. package/dist/node/vite.d.ts.map +1 -1
  28. package/dist/node/vite.js +12 -2
  29. package/package.json +5 -5
  30. package/src/node/__tests__/config.spec.ts +25 -0
  31. package/src/node/__tests__/port.spec.ts +33 -1
  32. package/src/node/__tests__/virtual-setup.spec.ts +13 -3
  33. package/src/node/__tests__/watch-ignore.spec.ts +33 -0
  34. package/src/node/bin.ts +1 -1
  35. package/src/node/build.ts +34 -0
  36. package/src/node/builtin-plugins/pinceau-tokens.ts +2 -2
  37. package/src/node/commands/port.ts +12 -0
  38. package/src/node/config.ts +10 -2
  39. package/src/node/index.ts +3 -0
  40. package/src/node/markdown.ts +2 -11
  41. package/src/node/server.ts +17 -1
  42. package/src/node/stories.ts +2 -11
  43. package/src/node/util/watch-ignore.ts +13 -0
  44. package/src/node/virtual/resolved-generated-global-setup.ts +13 -5
  45. package/src/node/virtual/util.ts +14 -0
  46. package/src/node/vite.ts +12 -1
  47. package/dist/node/builtin-plugins/tailwind-tokens.d.ts +0 -11
  48. package/dist/node/builtin-plugins/tailwind-tokens.d.ts.map +0 -1
  49. package/dist/node/builtin-plugins/tailwind-tokens.js +0 -660
  50. package/src/node/builtin-plugins/tailwind-tokens.ts +0 -694
@@ -1,694 +0,0 @@
1
- import type { Plugin, PluginApiBase } from '@poveste/shared'
2
- import { findUp } from '../util/find-up.js'
3
- import { getInjectedImport } from '../util/vendors.js'
4
-
5
- export interface TailwindTokensOptions {
6
- /**
7
- * Path to the CSS entrypoint that imports Tailwind and declares `@theme`.
8
- * Tailwind v4 is CSS-first, so the design tokens are read from CSS rather
9
- * than from a JS config. Auto-detected when omitted.
10
- */
11
- cssFile?: string
12
- }
13
-
14
- const CSS_ENTRY_CANDIDATES = [
15
- 'src/style.css',
16
- 'src/styles.css',
17
- 'src/main.css',
18
- 'src/index.css',
19
- 'src/app.css',
20
- 'src/assets/main.css',
21
- 'src/assets/style.css',
22
- 'src/assets/css/main.css',
23
- // Nuxt conventions
24
- 'app/assets/css/main.css',
25
- 'assets/css/main.css',
26
- // Next.js conventions
27
- 'styles/globals.css',
28
- 'app/globals.css',
29
- 'style.css',
30
- 'styles.css',
31
- ]
32
-
33
- export function tailwindTokens(options: TailwindTokensOptions = {}): Plugin {
34
- const tailwindCssFile = options.cssFile ?? findUp(process.cwd(), CSS_ENTRY_CANDIDATES)
35
-
36
- async function generate(api: PluginApiBase) {
37
- try {
38
- await api.fs.ensureDir(api.pluginTempDir)
39
- await api.fs.emptyDir(api.pluginTempDir)
40
- api.moduleLoader.clearCache()
41
- await api.fs.writeFile(api.path.resolve(api.pluginTempDir, 'style.css'), css)
42
- const theme = await loadTailwindTheme(api, tailwindCssFile)
43
- const storyFile = api.path.resolve(api.pluginTempDir, 'Tailwind.story.js')
44
- await api.fs.writeFile(storyFile, storyTemplate({ theme }))
45
- api.addStoryFile(storyFile)
46
- }
47
- catch (e) {
48
- api.error(e.stack ?? e.message)
49
- }
50
- }
51
-
52
- return {
53
- name: 'builtin:tailwind-tokens',
54
-
55
- config(config) {
56
- if (tailwindCssFile) {
57
- // Add 'design-system' group
58
- if (!config.tree) {
59
- config.tree = {}
60
- }
61
- if (!config.tree.groups) {
62
- config.tree.groups = []
63
- }
64
- if (!config.tree.groups.some(g => g.id === 'design-system')) {
65
- let index = 0
66
- // After 'top' group
67
- const topIndex = config.tree.groups.findIndex(g => g.id === 'top')
68
- if (topIndex > -1) {
69
- index = topIndex + 1
70
- }
71
- // Insert group
72
- config.tree.groups.splice(index, 0, {
73
- id: 'design-system',
74
- title: 'Design System',
75
- })
76
- }
77
- }
78
- },
79
-
80
- async onDev(api, onCleanup) {
81
- if (tailwindCssFile) {
82
- await generate(api)
83
-
84
- const watcher = api.watcher.watch(tailwindCssFile)
85
- .on('change', () => generate(api))
86
- .on('add', () => generate(api))
87
- onCleanup(() => {
88
- watcher.close()
89
- })
90
- }
91
- },
92
-
93
- async onBuild(api) {
94
- if (tailwindCssFile) {
95
- await generate(api)
96
- }
97
- },
98
- }
99
- }
100
-
101
- /**
102
- * Tailwind v4 keeps its theme as flat CSS custom properties rather than a
103
- * resolved JS config (`resolveConfig` is gone). Load the design system from the
104
- * project's CSS entrypoint and reshape its variables into the grouped structure
105
- * the story template renders.
106
- */
107
- /**
108
- * Resolve a stylesheet referenced from CSS. A bare package specifier resolves
109
- * to the JS entry, so its `style` field is used instead — that is how
110
- * `@import 'tailwindcss'` reaches `tailwindcss/index.css`.
111
- */
112
- async function resolveStylesheet(api: PluginApiBase, id: string, importBase: string) {
113
- const { createRequire } = await import('node:module')
114
- const require = createRequire(`${importBase}/`)
115
-
116
- if (id.startsWith('.')) {
117
- return api.path.resolve(importBase, id)
118
- }
119
- if (id.endsWith('.css')) {
120
- return require.resolve(id)
121
- }
122
- const packageJsonPath = require.resolve(`${id}/package.json`)
123
- const packageJson = JSON.parse(await api.fs.readFile(packageJsonPath, 'utf8'))
124
- return api.path.resolve(api.path.dirname(packageJsonPath), packageJson.style ?? 'index.css')
125
- }
126
-
127
- async function loadTailwindTheme(api: PluginApiBase, cssFile: string) {
128
- const { __unstable__loadDesignSystem } = await import('tailwindcss')
129
-
130
- const base = api.path.dirname(cssFile)
131
- const designSystem = await __unstable__loadDesignSystem(
132
- await api.fs.readFile(cssFile, 'utf8'),
133
- {
134
- base,
135
- loadStylesheet: async (id: string, importBase: string) => {
136
- const resolved = await resolveStylesheet(api, id, importBase)
137
- return {
138
- path: resolved,
139
- base: api.path.dirname(resolved),
140
- content: await api.fs.readFile(resolved, 'utf8'),
141
- }
142
- },
143
- },
144
- )
145
-
146
- const vars = new Map<string, string>(
147
- [...designSystem.theme.entries()].map(([key, entry]: [string, any]) => [key, entry.value]),
148
- )
149
-
150
- /** All values in a `--namespace-*` group, keyed by their remainder. */
151
- function group(namespace: string, exclude?: RegExp) {
152
- const out: Record<string, string> = {}
153
- const prefix = `${namespace}-`
154
- for (const [key, value] of vars) {
155
- if (!key.startsWith(prefix)) continue
156
- if (exclude?.test(key)) continue
157
- out[key.slice(prefix.length)] = value
158
- }
159
- return out
160
- }
161
-
162
- /** Colours are rendered as shade sets: `red-500` -> `{ red: { 500: … } }`. */
163
- function colors() {
164
- const out: Record<string, any> = {}
165
- for (const [key, value] of Object.entries(group('--color'))) {
166
- const match = key.match(/^(.*)-(\d+)$/)
167
- if (match) {
168
- out[match[1]] ??= {}
169
- out[match[1]][match[2]] = value
170
- }
171
- else {
172
- out[key] = value
173
- }
174
- }
175
- return out
176
- }
177
-
178
- // v4 generates the spacing scale on demand from a single `--spacing` base,
179
- // so the conventional steps are reconstructed here for display.
180
- const SPACING_STEPS = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96]
181
- function spacing() {
182
- const unit = vars.get('--spacing') ?? '0.25rem'
183
- // Multiply out rather than emitting `calc(0.25rem * 4)`, so the story shows
184
- // the resolved length the way the v3 resolved config did.
185
- const [, rawAmount, cssUnit] = unit.trim().match(/^([\d.]+)([a-z%]*)$/i) ?? []
186
- const amount = Number(rawAmount)
187
- const out: Record<string, string> = {}
188
- for (const step of SPACING_STEPS) {
189
- if (step === 0) {
190
- out['0'] = '0px'
191
- }
192
- else {
193
- out[String(step)] = Number.isFinite(amount)
194
- ? `${Number((amount * step).toFixed(4))}${cssUnit}`
195
- : `calc(${unit} * ${step})`
196
- }
197
- }
198
- return out
199
- }
200
-
201
- // Fractions and keywords have no theme variables in v4 — they are static
202
- // utilities — but they belong in the sizing scales the story lists.
203
- const SIZING_EXTRAS: Record<string, string> = {
204
- 'auto': 'auto',
205
- 'full': '100%',
206
- 'min': 'min-content',
207
- 'max': 'max-content',
208
- 'fit': 'fit-content',
209
- 'px': '1px',
210
- '1/2': '50%',
211
- '1/3': '33.333333%',
212
- '2/3': '66.666667%',
213
- '1/4': '25%',
214
- '3/4': '75%',
215
- '1/5': '20%',
216
- '2/5': '40%',
217
- '3/5': '60%',
218
- '4/5': '80%',
219
- }
220
-
221
- const palette = colors()
222
- const scale = spacing()
223
-
224
- return {
225
- backgroundColor: palette,
226
- textColor: palette,
227
- borderColor: palette,
228
- padding: scale,
229
- margin: scale,
230
- width: { ...scale, ...SIZING_EXTRAS, screen: '100vw' },
231
- height: { ...scale, ...SIZING_EXTRAS, screen: '100vh' },
232
- fontSize: group('--text', /--line-height$|--letter-spacing$|--font-weight$/),
233
- fontWeight: group('--font-weight'),
234
- fontFamily: group('--font', /^--font-weight-/),
235
- letterSpacing: group('--tracking'),
236
- lineHeight: group('--leading'),
237
- dropShadow: group('--drop-shadow'),
238
- borderRadius: group('--radius'),
239
- // v4 has no border-width namespace; these are the built-in static utilities.
240
- borderWidth: { DEFAULT: '1px', 0: '0px', 2: '2px', 4: '4px', 8: '8px' },
241
- }
242
- }
243
-
244
- function storyTemplate(tailwindConfig: any) {
245
- return `
246
- import 'poveste-style'
247
- import './style.css'
248
- import { createApp, h, markRaw, ref } from ${getInjectedImport('@poveste/vendors/vue')}
249
- import {
250
- HstColorShades,
251
- HstTokenList,
252
- HstTokenGrid,
253
- HstText,
254
- HstTextarea,
255
- HstNumber,
256
- } from ${getInjectedImport('@poveste/controls')}
257
-
258
- const config = markRaw(${JSON.stringify(tailwindConfig, null, 2)})
259
- const search = ref('')
260
- const sampleText = ref('Cat sit like bread eat prawns daintily with a claw then lick paws clean wash down prawns with a lap of carnation milk then retire to the warmest spot on the couch to claw at the fabric before taking a catnap mrow cat cat moo moo lick ears lick paws')
261
- const fontSize = ref(16)
262
-
263
- function mountApp ({ el, state, onUnmount }, render) {
264
- Object.assign(state, {
265
- search,
266
- sampleText,
267
- fontSize,
268
- })
269
-
270
- const app = createApp({
271
- render,
272
- })
273
- app.mount(el)
274
-
275
- onUnmount(() => {
276
- app.unmount()
277
- })
278
- }
279
-
280
- export default {
281
- id: 'tailwind',
282
- title: 'Tailwind',
283
- group: 'design-system',
284
- icon: 'mdi:tailwind',
285
- responsiveDisabled: true,
286
- layout: { type: 'single', iframe: false },
287
- variants: [
288
- {
289
- id: 'background-color',
290
- title: 'Background Color',
291
- icon: 'carbon:color-palette',
292
- onMount: (api) => mountApp(api, () => Object.entries(config.theme.backgroundColor).map(([key, shades]) => h(HstColorShades, {
293
- key,
294
- shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
295
- getName: shade => '' + (shade === 'DEFAULT' ? \`bg-\${key}\` : \`bg-\${key}-\${shade}\`),
296
- search: search.value,
297
- }, ({ color}) => h('div', {
298
- class: '__pvt-shade',
299
- style: {
300
- backgroundColor: color.replace('<alpha-value>', 1),
301
- },
302
- })))),
303
- onMountControls: (api) => mountApp(api, () => [
304
- h(HstText, {
305
- title: 'Filter...',
306
- modelValue: search.value,
307
- 'onUpdate:modelValue': value => { search.value = value },
308
- }),
309
- ]),
310
- },
311
- {
312
- id: 'text-color',
313
- title: 'Text Color',
314
- icon: 'carbon:text-color',
315
- onMount: (api) => mountApp(api, () => Object.entries(config.theme.textColor).map(([key, shades]) => h(HstColorShades, {
316
- key,
317
- shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
318
- getName: shade => '' + (shade === 'DEFAULT' ? \`text-\${key}\` : \`text-\${key}-\${shade}\`),
319
- search: search.value,
320
- }, ({ color}) => h('div', {
321
- class: '__pvt-shade __pvt-text',
322
- style: {
323
- color: color.replace('<alpha-value>', 1),
324
- },
325
- }, 'Aa')))),
326
- onMountControls: (api) => mountApp(api, () => [
327
- h(HstText, {
328
- title: 'Filter...',
329
- modelValue: search.value,
330
- 'onUpdate:modelValue': value => { search.value = value },
331
- }),
332
- ]),
333
- },
334
- {
335
- id: 'border-color',
336
- title: 'Border Color',
337
- icon: 'carbon:color-palette',
338
- onMount: (api) => mountApp(api, () => Object.entries(config.theme.borderColor).map(([key, shades]) => h(HstColorShades, {
339
- key,
340
- shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
341
- getName: shade => '' + (shade === 'DEFAULT' ? \`border-\${key}\` : \`border-\${key}-\${shade}\`),
342
- search: search.value,
343
- }, ({ color}) => h('div', {
344
- class: '__pvt-shade __pvt-border',
345
- style: {
346
- borderColor: color.replace('<alpha-value>', 1),
347
- },
348
- })))),
349
- onMountControls: (api) => mountApp(api, () => [
350
- h(HstText, {
351
- title: 'Filter...',
352
- modelValue: search.value,
353
- 'onUpdate:modelValue': value => { search.value = value },
354
- }),
355
- ]),
356
- },
357
- {
358
- id: 'padding',
359
- title: 'Padding',
360
- icon: 'carbon:area',
361
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
362
- tokens: config.theme.padding,
363
- getName: key => \`p-\${key}\`,
364
- }, ({ token }) => h('div', {
365
- class: '__pvt-padding',
366
- style: {
367
- padding: token.value,
368
- },
369
- }, [
370
- h('div', {
371
- class: '__pvt-padding-box',
372
- }),
373
- ]))),
374
- },
375
- {
376
- id: 'margin',
377
- title: 'Margin',
378
- icon: 'carbon:area',
379
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
380
- tokens: config.theme.margin,
381
- getName: key => \`m-\${key}\`,
382
- }, ({ token }) => h('div', {
383
- class: '__pvt-margin',
384
- }, [
385
- h('div', {
386
- class: '__pvt-margin-box',
387
- style: {
388
- margin: token.value,
389
- },
390
- }),
391
- ]))),
392
- },
393
- {
394
- id: 'font-size',
395
- title: 'Font Size',
396
- icon: 'carbon:text-font',
397
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
398
- tokens: config.theme.fontSize,
399
- getName: key => \`text-\${key}\`,
400
- }, ({ token }) => h('div', {
401
- class: '__pvt-truncate',
402
- style: {
403
- fontSize: Array.isArray(token.value) ? token.value[0] : token.value,
404
- ...(Array.isArray(token.value) && typeof token.value[1] === "object" ? token.value[1] : { lineHeight: token.value[1] })
405
- },
406
- }, sampleText.value))),
407
- onMountControls: (api) => mountApp(api, () => [
408
- h(HstTextarea, {
409
- title: 'Sample text',
410
- modelValue: sampleText.value,
411
- 'onUpdate:modelValue': value => { sampleText.value = value },
412
- rows: 5,
413
- }),
414
- ]),
415
- },
416
- {
417
- id: 'font-weight',
418
- title: 'Font Weight',
419
- icon: 'carbon:text-font',
420
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
421
- tokens: config.theme.fontWeight,
422
- getName: key => \`font-\${key}\`,
423
- }, ({ token }) => h('div', {
424
- class: '__pvt-truncate',
425
- style: {
426
- fontWeight: token.value,
427
- fontSize: \`\${fontSize.value}px\`,
428
- },
429
- }, sampleText.value))),
430
- onMountControls: (api) => mountApp(api, () => [
431
- h(HstTextarea, {
432
- title: 'Sample text',
433
- modelValue: sampleText.value,
434
- 'onUpdate:modelValue': value => { sampleText.value = value },
435
- rows: 5,
436
- }),
437
- h(HstNumber, {
438
- title: 'Font size',
439
- modelValue: fontSize.value,
440
- 'onUpdate:modelValue': value => { fontSize.value = value },
441
- min: 1,
442
- }),
443
- ]),
444
- },
445
- {
446
- id: 'font-family',
447
- title: 'Font Family',
448
- icon: 'carbon:text-font',
449
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
450
- tokens: config.theme.fontFamily,
451
- getName: key => \`font-\${key}\`,
452
- }, ({ token }) => h('div', {
453
- class: '__pvt-truncate',
454
- style: {
455
- fontFamily: token.value,
456
- fontSize: \`\${fontSize.value}px\`,
457
- },
458
- }, sampleText.value))),
459
- onMountControls: (api) => mountApp(api, () => [
460
- h(HstTextarea, {
461
- title: 'Sample text',
462
- modelValue: sampleText.value,
463
- 'onUpdate:modelValue': value => { sampleText.value = value },
464
- rows: 5,
465
- }),
466
- h(HstNumber, {
467
- title: 'Font size',
468
- modelValue: fontSize.value,
469
- 'onUpdate:modelValue': value => { fontSize.value = value },
470
- min: 1,
471
- }),
472
- ]),
473
- },
474
- {
475
- id: 'letter-spacing',
476
- title: 'Letter Spacing',
477
- icon: 'carbon:text-font',
478
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
479
- tokens: config.theme.letterSpacing,
480
- getName: key => \`tracking-\${key}\`,
481
- }, ({ token }) => h('div', {
482
- class: '__pvt-truncate',
483
- style: {
484
- letterSpacing: token.value,
485
- fontSize: \`\${fontSize.value}px\`,
486
- },
487
- }, sampleText.value))),
488
- onMountControls: (api) => mountApp(api, () => [
489
- h(HstTextarea, {
490
- title: 'Sample text',
491
- modelValue: sampleText.value,
492
- 'onUpdate:modelValue': value => { sampleText.value = value },
493
- rows: 5,
494
- }),
495
- h(HstNumber, {
496
- title: 'Font size',
497
- modelValue: fontSize.value,
498
- 'onUpdate:modelValue': value => { fontSize.value = value },
499
- min: 1,
500
- }),
501
- ]),
502
- },
503
- {
504
- id: 'line-height',
505
- title: 'Line Height',
506
- icon: 'carbon:text-font',
507
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
508
- tokens: config.theme.lineHeight,
509
- getName: key => \`leading-\${key}\`,
510
- }, ({ token }) => h('div', {
511
- style: {
512
- lineHeight: token.value,
513
- },
514
- }, sampleText.value))),
515
- onMountControls: (api) => mountApp(api, () => [
516
- h(HstTextarea, {
517
- title: 'Sample text',
518
- modelValue: sampleText.value,
519
- 'onUpdate:modelValue': value => { sampleText.value = value },
520
- rows: 5,
521
- }),
522
- // @TODO select font size
523
- ]),
524
- },
525
- {
526
- id: 'drop-shadow',
527
- title: 'Drop Shadow',
528
- icon: 'carbon:shape-except',
529
- onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
530
- tokens: config.theme.dropShadow,
531
- getName: key => '' + (key === 'DEFAULT' ? 'drop-shadow' : \`drop-shadow-\${key}\`),
532
- colSize: 180,
533
- }, ({ token }) => h('div', {
534
- class: '__pvt-drop-shadow',
535
- style: {
536
- filter: \`\${(Array.isArray(token.value) ? token.value : [token.value]).map(v => \`drop-shadow(\${v})\`).join(' ')}\`,
537
- },
538
- }))),
539
- },
540
- {
541
- id: 'border-radius',
542
- title: 'Border Radius',
543
- icon: 'carbon:condition-wait-point',
544
- onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
545
- tokens: config.theme.borderRadius,
546
- getName: key => '' + (key === 'DEFAULT' ? 'rounded' : \`rounded-\${key}\`),
547
- colSize: 180,
548
- }, ({ token }) => h('div', {
549
- class: '__pvt-border-radius',
550
- style: {
551
- borderRadius: token.value,
552
- },
553
- }))),
554
- },
555
- {
556
- id: 'border-width',
557
- title: 'Border Width',
558
- icon: 'carbon:checkbox',
559
- onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
560
- tokens: config.theme.borderWidth,
561
- getName: key => '' + (key === 'DEFAULT' ? 'border' : \`border-\${key}\`),
562
- colSize: 180,
563
- }, ({ token }) => h('div', {
564
- class: '__pvt-border-width',
565
- style: {
566
- borderWidth: token.value,
567
- },
568
- }))),
569
- },
570
- {
571
- id: 'width',
572
- title: 'Width',
573
- icon: 'carbon:pan-horizontal',
574
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
575
- tokens: config.theme.width,
576
- getName: key => '' + (key === 'DEFAULT' ? 'w' : \`w-\${key}\`),
577
- }, ({ token }) => h('div', {
578
- class: '__pvt-width',
579
- }, [
580
- h('div', {
581
- class: '__pvt-width-box',
582
- style: {
583
- width: token.value,
584
- },
585
- }),
586
- ]))),
587
- },
588
- {
589
- id: 'height',
590
- title: 'Height',
591
- icon: 'carbon:pan-vertical',
592
- onMount: (api) => mountApp(api, () => h(HstTokenList, {
593
- tokens: config.theme.height,
594
- getName: key => '' + (key === 'DEFAULT' ? 'h' : \`h-\${key}\`),
595
- }, ({ token }) => h('div', {
596
- class: '__pvt-height',
597
- style: {
598
- height: token.value,
599
- },
600
- }))),
601
- },
602
- {
603
- id: 'full-config',
604
- title: 'Full Config',
605
- icon: 'carbon:code',
606
- onMount: (api) => mountApp(api, () => h('pre', JSON.stringify(config, null, 2))),
607
- },
608
- ],
609
- }`
610
- }
611
-
612
- const css = `.__pvt-shade {
613
- height: 80px;
614
- border-radius: 4px;
615
- }
616
-
617
- .__pvt-text {
618
- font-size: 4rem;
619
- display: flex;
620
- align-items: flex-end;
621
- }
622
-
623
- .__pvt-border {
624
- border-style: solid;
625
- border-width: 2px;
626
- }
627
-
628
- .__pvt-padding {
629
- background-color: rgb(113 113 122 / 0.1);
630
- width: min-content;
631
- }
632
-
633
- .__pvt-margin {
634
- border: dashed 1px rgb(113 113 122 / 0.5);
635
- width: min-content;
636
- }
637
-
638
- .__pvt-padding-box,
639
- .__pvt-margin-box {
640
- width: 5rem;
641
- height: 5rem;
642
- background-color: rgb(113 113 122 / 0.5);
643
- }
644
-
645
- .__pvt-padding,
646
- .__pvt-padding-box,
647
- .__pvt-margin,
648
- .__pvt-margin-box,
649
- .__pvt-drop-shadow {
650
- border-radius: 4px;
651
- }
652
-
653
- .__pvt-truncate {
654
- overflow: hidden;
655
- text-overflow: ellipsis;
656
- white-space: nowrap;
657
- }
658
-
659
- .__pvt-drop-shadow {
660
- width: 8rem;
661
- height: 8rem;
662
- background: white;
663
- margin-bottom: 0.5rem;
664
- }
665
-
666
- .__pvt-drop-shadow {
667
- background: #4e4e57;
668
- }
669
-
670
- .__pvt-border-radius {
671
- width: 8rem;
672
- height: 8rem;
673
- background-color: rgb(113 113 122 / 0.5);
674
- }
675
-
676
- .__pvt-border-width {
677
- width: 8rem;
678
- height: 8rem;
679
- border-color: rgb(113 113 122 / 0.5);
680
- background-color: rgb(113 113 122 / 0.1);
681
- }
682
-
683
- .__pvt-width {
684
- background-color: rgb(113 113 122 / 0.1);
685
- }
686
-
687
- .__pvt-width-box,
688
- .__pvt-height {
689
- background-color: rgb(113 113 122 / 0.5);
690
- }
691
-
692
- .__pvt-width-box {
693
- height: 5rem;
694
- }`