@poveste/plugin-tailwind 0.6.0 → 0.7.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/LICENSE +22 -0
- package/package.json +37 -14
- package/src/index.spec.ts +0 -41
- package/src/index.ts +0 -765
- package/tsconfig.json +0 -40
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Guillaume Chau (original "histoire" project)
|
|
4
|
+
Copyright (c) 2026 Sorin Gitlan (poveste fork)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poveste/plugin-tailwind",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"description": "Poveste plugin that renders a Tailwind design system as a story",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"homepage": "https://poveste.dev",
|
|
10
11
|
"repository": {
|
|
11
12
|
"url": "https://github.com/poveste-dev/poveste.git",
|
|
12
13
|
"type": "git",
|
|
13
14
|
"directory": "packages/poveste-plugin-tailwind"
|
|
14
15
|
},
|
|
16
|
+
"bugs": "https://github.com/poveste-dev/poveste/issues",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"poveste",
|
|
19
|
+
"histoire",
|
|
20
|
+
"storybook",
|
|
21
|
+
"component-playground",
|
|
22
|
+
"component-explorer",
|
|
23
|
+
"stories",
|
|
24
|
+
"styleguide",
|
|
25
|
+
"design-system",
|
|
26
|
+
"vite",
|
|
27
|
+
"tailwind",
|
|
28
|
+
"tailwindcss",
|
|
29
|
+
"design-tokens",
|
|
30
|
+
"plugin"
|
|
31
|
+
],
|
|
15
32
|
"publishConfig": {
|
|
16
33
|
"access": "public"
|
|
17
34
|
},
|
|
@@ -22,24 +39,30 @@
|
|
|
22
39
|
"main": "./dist/index.js",
|
|
23
40
|
"module": "./dist/index.js",
|
|
24
41
|
"types": "./dist/index.d.ts",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
30
47
|
},
|
|
31
48
|
"peerDependencies": {
|
|
32
|
-
"poveste": "
|
|
49
|
+
"poveste": "^0.7.0"
|
|
33
50
|
},
|
|
34
51
|
"dependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
52
|
+
"pathe": "^1.1.2",
|
|
53
|
+
"@poveste/shared": "0.7.0"
|
|
37
54
|
},
|
|
38
55
|
"devDependencies": {
|
|
39
56
|
"@types/node": "^22.10.1",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
57
|
+
"typescript": "5.6.3",
|
|
58
|
+
"vite": "^8.2.0",
|
|
59
|
+
"vitest": "^4.1.10",
|
|
60
|
+
"poveste": "0.7.0"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "rimraf dist && tsc -d",
|
|
64
|
+
"watch": "tsc -d -w --sourceMap",
|
|
65
|
+
"test": "vitest run",
|
|
66
|
+
"test:dev": "vitest"
|
|
44
67
|
}
|
|
45
|
-
}
|
|
68
|
+
}
|
package/src/index.spec.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { mkdtempSync, writeFileSync } from 'node:fs'
|
|
2
|
-
import { tmpdir } from 'node:os'
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
import { describe, expect, it } from 'vitest'
|
|
5
|
-
import { isTailwindEntry } from './index.js'
|
|
6
|
-
|
|
7
|
-
function cssFile(contents: string) {
|
|
8
|
-
const dir = mkdtempSync(join(tmpdir(), 'poveste-tw-'))
|
|
9
|
-
const file = join(dir, 'entry.css')
|
|
10
|
-
writeFileSync(file, contents)
|
|
11
|
-
return file
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('isTailwindEntry', () => {
|
|
15
|
-
it('accepts a Tailwind import', () => {
|
|
16
|
-
expect(isTailwindEntry(cssFile(`@import 'tailwindcss';`))).toBe(true)
|
|
17
|
-
expect(isTailwindEntry(cssFile(`@import "tailwindcss";`))).toBe(true)
|
|
18
|
-
expect(isTailwindEntry(cssFile(`@import 'tailwindcss/theme' layer(theme);`))).toBe(true)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('accepts a theme block', () => {
|
|
22
|
-
expect(isTailwindEntry(cssFile('@theme {\n --color-brand: red;\n}'))).toBe(true)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('rejects a stylesheet that merely imports something', () => {
|
|
26
|
-
// The case this exists for. `examples/sveltekit` has no Tailwind at all, and
|
|
27
|
-
// its `src/app.css` opens with a font import — enough to satisfy any test
|
|
28
|
-
// looser than this one, and it was getting a Design System group and a
|
|
29
|
-
// Tailwind story rendering Tailwind's own defaults.
|
|
30
|
-
expect(isTailwindEntry(cssFile(`@import '@fontsource/fira-mono';\n\n:root { --pure-white: #fff }`))).toBe(false)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('rejects a name that only looks like Tailwind', () => {
|
|
34
|
-
expect(isTailwindEntry(cssFile('.tailwindcss { color: red }'))).toBe(false)
|
|
35
|
-
expect(isTailwindEntry(cssFile('/* @import tailwindcss was here */'))).toBe(false)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('rejects a file it cannot read', () => {
|
|
39
|
-
expect(isTailwindEntry(join(tmpdir(), 'poveste-tw-does-not-exist.css'))).toBe(false)
|
|
40
|
-
})
|
|
41
|
-
})
|
package/src/index.ts
DELETED
|
@@ -1,765 +0,0 @@
|
|
|
1
|
-
import type { Plugin, PluginApiBase } from '@poveste/shared'
|
|
2
|
-
import fs from 'node:fs'
|
|
3
|
-
import path from 'pathe'
|
|
4
|
-
import { getInjectedImport } from 'poveste'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The first of `fileNames` that exists and satisfies `accept`, searching `cwd`
|
|
8
|
-
* and then upwards.
|
|
9
|
-
*
|
|
10
|
-
* `accept` is not a convenience: every name below is an ordinary one, so a
|
|
11
|
-
* near-miss in the same directory would otherwise shadow the real entrypoint
|
|
12
|
-
* sitting behind it in the list.
|
|
13
|
-
*/
|
|
14
|
-
function findUp(cwd: string, fileNames: string[], accept: (filePath: string) => boolean): string | null {
|
|
15
|
-
let { root } = path.parse(cwd)
|
|
16
|
-
let dir = cwd
|
|
17
|
-
|
|
18
|
-
// On Windows this is `C:` and needs the trailing slash to terminate.
|
|
19
|
-
if (root[1] === ':' && root[2] === undefined) {
|
|
20
|
-
root += '/'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
while (dir !== root) {
|
|
24
|
-
for (const fileName of fileNames) {
|
|
25
|
-
const searchPath = path.join(dir, fileName)
|
|
26
|
-
|
|
27
|
-
if (fs.existsSync(searchPath) && accept(searchPath)) {
|
|
28
|
-
return searchPath
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
dir = path.dirname(dir)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return null
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TailwindTokensOptions {
|
|
39
|
-
/**
|
|
40
|
-
* Path to the CSS entrypoint that imports Tailwind and declares `@theme`.
|
|
41
|
-
* Tailwind v4 is CSS-first, so the design tokens are read from CSS rather
|
|
42
|
-
* than from a JS config. Auto-detected when omitted.
|
|
43
|
-
*/
|
|
44
|
-
cssFile?: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const CSS_ENTRY_CANDIDATES = [
|
|
48
|
-
'src/style.css',
|
|
49
|
-
'src/styles.css',
|
|
50
|
-
'src/main.css',
|
|
51
|
-
'src/index.css',
|
|
52
|
-
'src/app.css',
|
|
53
|
-
'src/assets/main.css',
|
|
54
|
-
'src/assets/style.css',
|
|
55
|
-
'src/assets/css/main.css',
|
|
56
|
-
// Nuxt conventions
|
|
57
|
-
'app/assets/css/main.css',
|
|
58
|
-
'assets/css/main.css',
|
|
59
|
-
// Next.js conventions
|
|
60
|
-
'styles/globals.css',
|
|
61
|
-
'app/globals.css',
|
|
62
|
-
'style.css',
|
|
63
|
-
'styles.css',
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Whether a stylesheet is a Tailwind entrypoint, rather than merely a file with
|
|
68
|
-
* one of the names Tailwind entrypoints tend to have.
|
|
69
|
-
*
|
|
70
|
-
* Every name in `CSS_ENTRY_CANDIDATES` is an ordinary one — `src/app.css`,
|
|
71
|
-
* `styles.css` — so matching on the name alone hands the whole feature to
|
|
72
|
-
* projects that have never used Tailwind: a `Design System` group inserted into
|
|
73
|
-
* their tree, and a story rendering Tailwind's own defaults as if it were their
|
|
74
|
-
* design system.
|
|
75
|
-
*
|
|
76
|
-
* Both markers are Tailwind v4, which is what this plugin reads: the theme comes
|
|
77
|
-
* from CSS custom properties, so a v3 project using `@tailwind base` would be
|
|
78
|
-
* accepted here and then produce nothing.
|
|
79
|
-
*/
|
|
80
|
-
export function isTailwindEntry(filePath: string) {
|
|
81
|
-
let source: string
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
source = fs.readFileSync(filePath, 'utf8')
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
return false
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// `@import 'tailwindcss'`, `"tailwindcss/theme"`, and the `layer(…)` and
|
|
91
|
-
// `source(…)` forms that follow the specifier. Deliberately not a bare
|
|
92
|
-
// `@import` test — the file that prompted this imports a font.
|
|
93
|
-
return /@import\s+["']tailwindcss(?:\/[^"']*)?["']/.test(source)
|
|
94
|
-
|| /@theme\b/.test(source)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function HstTailwind(options: TailwindTokensOptions = {}): Plugin {
|
|
98
|
-
// An explicit `cssFile` is the caller saying so, and is taken at their word.
|
|
99
|
-
const tailwindCssFile = options.cssFile ?? findUp(process.cwd(), CSS_ENTRY_CANDIDATES, isTailwindEntry)
|
|
100
|
-
|
|
101
|
-
async function generate(api: PluginApiBase) {
|
|
102
|
-
try {
|
|
103
|
-
await api.fs.ensureDir(api.pluginTempDir)
|
|
104
|
-
await api.fs.emptyDir(api.pluginTempDir)
|
|
105
|
-
api.moduleLoader.clearCache()
|
|
106
|
-
await api.fs.writeFile(api.path.resolve(api.pluginTempDir, 'style.css'), css)
|
|
107
|
-
const theme = await loadTailwindTheme(api, tailwindCssFile)
|
|
108
|
-
const storyFile = api.path.resolve(api.pluginTempDir, 'Tailwind.story.js')
|
|
109
|
-
await api.fs.writeFile(storyFile, storyTemplate({ theme }))
|
|
110
|
-
api.addStoryFile(storyFile)
|
|
111
|
-
}
|
|
112
|
-
catch (e) {
|
|
113
|
-
api.error(e.stack ?? e.message)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
name: 'tailwind-tokens',
|
|
119
|
-
|
|
120
|
-
config(config) {
|
|
121
|
-
if (tailwindCssFile) {
|
|
122
|
-
// Add 'design-system' group
|
|
123
|
-
if (!config.tree) {
|
|
124
|
-
config.tree = {}
|
|
125
|
-
}
|
|
126
|
-
if (!config.tree.groups) {
|
|
127
|
-
config.tree.groups = []
|
|
128
|
-
}
|
|
129
|
-
if (!config.tree.groups.some(g => g.id === 'design-system')) {
|
|
130
|
-
let index = 0
|
|
131
|
-
// After 'top' group
|
|
132
|
-
const topIndex = config.tree.groups.findIndex(g => g.id === 'top')
|
|
133
|
-
if (topIndex > -1) {
|
|
134
|
-
index = topIndex + 1
|
|
135
|
-
}
|
|
136
|
-
// Insert group
|
|
137
|
-
config.tree.groups.splice(index, 0, {
|
|
138
|
-
id: 'design-system',
|
|
139
|
-
title: 'Design System',
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
async onDev(api, onCleanup) {
|
|
146
|
-
if (tailwindCssFile) {
|
|
147
|
-
await generate(api)
|
|
148
|
-
|
|
149
|
-
const watcher = api.watcher.watch(tailwindCssFile)
|
|
150
|
-
.on('change', () => generate(api))
|
|
151
|
-
.on('add', () => generate(api))
|
|
152
|
-
onCleanup(() => {
|
|
153
|
-
watcher.close()
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
async onBuild(api) {
|
|
159
|
-
if (tailwindCssFile) {
|
|
160
|
-
await generate(api)
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Tailwind v4 keeps its theme as flat CSS custom properties rather than a
|
|
168
|
-
* resolved JS config (`resolveConfig` is gone). Load the design system from the
|
|
169
|
-
* project's CSS entrypoint and reshape its variables into the grouped structure
|
|
170
|
-
* the story template renders.
|
|
171
|
-
*/
|
|
172
|
-
/**
|
|
173
|
-
* Resolve a stylesheet referenced from CSS. A bare package specifier resolves
|
|
174
|
-
* to the JS entry, so its `style` field is used instead — that is how
|
|
175
|
-
* `@import 'tailwindcss'` reaches `tailwindcss/index.css`.
|
|
176
|
-
*/
|
|
177
|
-
async function resolveStylesheet(api: PluginApiBase, id: string, importBase: string) {
|
|
178
|
-
const { createRequire } = await import('node:module')
|
|
179
|
-
const require = createRequire(`${importBase}/`)
|
|
180
|
-
|
|
181
|
-
if (id.startsWith('.')) {
|
|
182
|
-
return api.path.resolve(importBase, id)
|
|
183
|
-
}
|
|
184
|
-
if (id.endsWith('.css')) {
|
|
185
|
-
return require.resolve(id)
|
|
186
|
-
}
|
|
187
|
-
const packageJsonPath = require.resolve(`${id}/package.json`)
|
|
188
|
-
const packageJson = JSON.parse(await api.fs.readFile(packageJsonPath, 'utf8'))
|
|
189
|
-
return api.path.resolve(api.path.dirname(packageJsonPath), packageJson.style ?? 'index.css')
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
async function loadTailwindTheme(api: PluginApiBase, cssFile: string) {
|
|
193
|
-
const { __unstable__loadDesignSystem } = await import('tailwindcss')
|
|
194
|
-
|
|
195
|
-
const base = api.path.dirname(cssFile)
|
|
196
|
-
const designSystem = await __unstable__loadDesignSystem(
|
|
197
|
-
await api.fs.readFile(cssFile, 'utf8'),
|
|
198
|
-
{
|
|
199
|
-
base,
|
|
200
|
-
loadStylesheet: async (id: string, importBase: string) => {
|
|
201
|
-
const resolved = await resolveStylesheet(api, id, importBase)
|
|
202
|
-
return {
|
|
203
|
-
path: resolved,
|
|
204
|
-
base: api.path.dirname(resolved),
|
|
205
|
-
content: await api.fs.readFile(resolved, 'utf8'),
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
const vars = new Map<string, string>(
|
|
212
|
-
[...designSystem.theme.entries()].map(([key, entry]: [string, any]) => [key, entry.value]),
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
/** All values in a `--namespace-*` group, keyed by their remainder. */
|
|
216
|
-
function group(namespace: string, exclude?: RegExp) {
|
|
217
|
-
const out: Record<string, string> = {}
|
|
218
|
-
const prefix = `${namespace}-`
|
|
219
|
-
for (const [key, value] of vars) {
|
|
220
|
-
if (!key.startsWith(prefix)) continue
|
|
221
|
-
if (exclude?.test(key)) continue
|
|
222
|
-
out[key.slice(prefix.length)] = value
|
|
223
|
-
}
|
|
224
|
-
return out
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/** Colours are rendered as shade sets: `red-500` -> `{ red: { 500: … } }`. */
|
|
228
|
-
function colors() {
|
|
229
|
-
const out: Record<string, any> = {}
|
|
230
|
-
for (const [key, value] of Object.entries(group('--color'))) {
|
|
231
|
-
const match = key.match(/^(.*)-(\d+)$/)
|
|
232
|
-
if (match) {
|
|
233
|
-
out[match[1]] ??= {}
|
|
234
|
-
out[match[1]][match[2]] = value
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
out[key] = value
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return out
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// v4 generates the spacing scale on demand from a single `--spacing` base,
|
|
244
|
-
// so the conventional steps are reconstructed here for display.
|
|
245
|
-
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]
|
|
246
|
-
function spacing() {
|
|
247
|
-
const unit = vars.get('--spacing') ?? '0.25rem'
|
|
248
|
-
// Multiply out rather than emitting `calc(0.25rem * 4)`, so the story shows
|
|
249
|
-
// the resolved length the way the v3 resolved config did.
|
|
250
|
-
const [, rawAmount, cssUnit] = unit.trim().match(/^([\d.]+)([a-z%]*)$/i) ?? []
|
|
251
|
-
const amount = Number(rawAmount)
|
|
252
|
-
const out: Record<string, string> = {}
|
|
253
|
-
for (const step of SPACING_STEPS) {
|
|
254
|
-
if (step === 0) {
|
|
255
|
-
out['0'] = '0px'
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
out[String(step)] = Number.isFinite(amount)
|
|
259
|
-
? `${Number((amount * step).toFixed(4))}${cssUnit}`
|
|
260
|
-
: `calc(${unit} * ${step})`
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return out
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Fractions and keywords have no theme variables in v4 — they are static
|
|
267
|
-
// utilities — but they belong in the sizing scales the story lists.
|
|
268
|
-
const SIZING_EXTRAS: Record<string, string> = {
|
|
269
|
-
'auto': 'auto',
|
|
270
|
-
'full': '100%',
|
|
271
|
-
'min': 'min-content',
|
|
272
|
-
'max': 'max-content',
|
|
273
|
-
'fit': 'fit-content',
|
|
274
|
-
'px': '1px',
|
|
275
|
-
'1/2': '50%',
|
|
276
|
-
'1/3': '33.333333%',
|
|
277
|
-
'2/3': '66.666667%',
|
|
278
|
-
'1/4': '25%',
|
|
279
|
-
'3/4': '75%',
|
|
280
|
-
'1/5': '20%',
|
|
281
|
-
'2/5': '40%',
|
|
282
|
-
'3/5': '60%',
|
|
283
|
-
'4/5': '80%',
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const palette = colors()
|
|
287
|
-
const scale = spacing()
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
backgroundColor: palette,
|
|
291
|
-
textColor: palette,
|
|
292
|
-
borderColor: palette,
|
|
293
|
-
padding: scale,
|
|
294
|
-
margin: scale,
|
|
295
|
-
width: { ...scale, ...SIZING_EXTRAS, screen: '100vw' },
|
|
296
|
-
height: { ...scale, ...SIZING_EXTRAS, screen: '100vh' },
|
|
297
|
-
fontSize: group('--text', /--line-height$|--letter-spacing$|--font-weight$/),
|
|
298
|
-
fontWeight: group('--font-weight'),
|
|
299
|
-
fontFamily: group('--font', /^--font-weight-/),
|
|
300
|
-
letterSpacing: group('--tracking'),
|
|
301
|
-
lineHeight: group('--leading'),
|
|
302
|
-
dropShadow: group('--drop-shadow'),
|
|
303
|
-
borderRadius: group('--radius'),
|
|
304
|
-
// v4 has no border-width namespace; these are the built-in static utilities.
|
|
305
|
-
borderWidth: { DEFAULT: '1px', 0: '0px', 2: '2px', 4: '4px', 8: '8px' },
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// No `import 'poveste-style'`: the story renders in a sandbox realm, where the
|
|
310
|
-
// app stylesheet is @scope'd away from story markup anyway — it only added
|
|
311
|
-
// ~100 KB of chrome CSS to every sandbox of every book using this plugin (#219).
|
|
312
|
-
// The swatches style themselves from the local stylesheet below.
|
|
313
|
-
function storyTemplate(tailwindConfig: any) {
|
|
314
|
-
return `
|
|
315
|
-
import './style.css'
|
|
316
|
-
import { createApp, h, markRaw, ref } from ${getInjectedImport('@poveste/vendors/vue')}
|
|
317
|
-
import {
|
|
318
|
-
HstColorShades,
|
|
319
|
-
HstTokenList,
|
|
320
|
-
HstTokenGrid,
|
|
321
|
-
HstText,
|
|
322
|
-
HstTextarea,
|
|
323
|
-
HstNumber,
|
|
324
|
-
} from ${getInjectedImport('@poveste/controls')}
|
|
325
|
-
|
|
326
|
-
const config = markRaw(${JSON.stringify(tailwindConfig, null, 2)})
|
|
327
|
-
const search = ref('')
|
|
328
|
-
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')
|
|
329
|
-
const fontSize = ref(16)
|
|
330
|
-
|
|
331
|
-
function mountApp ({ el, state, onUnmount }, render) {
|
|
332
|
-
Object.assign(state, {
|
|
333
|
-
search,
|
|
334
|
-
sampleText,
|
|
335
|
-
fontSize,
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
const app = createApp({
|
|
339
|
-
render,
|
|
340
|
-
})
|
|
341
|
-
app.mount(el)
|
|
342
|
-
|
|
343
|
-
onUnmount(() => {
|
|
344
|
-
app.unmount()
|
|
345
|
-
})
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
export default {
|
|
349
|
-
id: 'tailwind',
|
|
350
|
-
title: 'Tailwind',
|
|
351
|
-
group: 'design-system',
|
|
352
|
-
icon: 'mdi:tailwind',
|
|
353
|
-
responsiveDisabled: true,
|
|
354
|
-
layout: { type: 'single', iframe: false },
|
|
355
|
-
variants: [
|
|
356
|
-
{
|
|
357
|
-
id: 'background-color',
|
|
358
|
-
title: 'Background Color',
|
|
359
|
-
icon: 'carbon:color-palette',
|
|
360
|
-
onMount: (api) => mountApp(api, () => Object.entries(config.theme.backgroundColor).map(([key, shades]) => h(HstColorShades, {
|
|
361
|
-
key,
|
|
362
|
-
shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
|
|
363
|
-
getName: shade => '' + (shade === 'DEFAULT' ? \`bg-\${key}\` : \`bg-\${key}-\${shade}\`),
|
|
364
|
-
search: search.value,
|
|
365
|
-
}, ({ color}) => h('div', {
|
|
366
|
-
class: '__pvt-shade',
|
|
367
|
-
style: {
|
|
368
|
-
backgroundColor: color.replace('<alpha-value>', 1),
|
|
369
|
-
},
|
|
370
|
-
})))),
|
|
371
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
372
|
-
h(HstText, {
|
|
373
|
-
title: 'Filter...',
|
|
374
|
-
modelValue: search.value,
|
|
375
|
-
'onUpdate:modelValue': value => { search.value = value },
|
|
376
|
-
}),
|
|
377
|
-
]),
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
id: 'text-color',
|
|
381
|
-
title: 'Text Color',
|
|
382
|
-
icon: 'carbon:text-color',
|
|
383
|
-
onMount: (api) => mountApp(api, () => Object.entries(config.theme.textColor).map(([key, shades]) => h(HstColorShades, {
|
|
384
|
-
key,
|
|
385
|
-
shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
|
|
386
|
-
getName: shade => '' + (shade === 'DEFAULT' ? \`text-\${key}\` : \`text-\${key}-\${shade}\`),
|
|
387
|
-
search: search.value,
|
|
388
|
-
}, ({ color}) => h('div', {
|
|
389
|
-
class: '__pvt-shade __pvt-text',
|
|
390
|
-
style: {
|
|
391
|
-
color: color.replace('<alpha-value>', 1),
|
|
392
|
-
},
|
|
393
|
-
}, 'Aa')))),
|
|
394
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
395
|
-
h(HstText, {
|
|
396
|
-
title: 'Filter...',
|
|
397
|
-
modelValue: search.value,
|
|
398
|
-
'onUpdate:modelValue': value => { search.value = value },
|
|
399
|
-
}),
|
|
400
|
-
]),
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
id: 'border-color',
|
|
404
|
-
title: 'Border Color',
|
|
405
|
-
icon: 'carbon:color-palette',
|
|
406
|
-
onMount: (api) => mountApp(api, () => Object.entries(config.theme.borderColor).map(([key, shades]) => h(HstColorShades, {
|
|
407
|
-
key,
|
|
408
|
-
shades: typeof shades === 'object' ? shades : { DEFAULT: shades },
|
|
409
|
-
getName: shade => '' + (shade === 'DEFAULT' ? \`border-\${key}\` : \`border-\${key}-\${shade}\`),
|
|
410
|
-
search: search.value,
|
|
411
|
-
}, ({ color}) => h('div', {
|
|
412
|
-
class: '__pvt-shade __pvt-border',
|
|
413
|
-
style: {
|
|
414
|
-
borderColor: color.replace('<alpha-value>', 1),
|
|
415
|
-
},
|
|
416
|
-
})))),
|
|
417
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
418
|
-
h(HstText, {
|
|
419
|
-
title: 'Filter...',
|
|
420
|
-
modelValue: search.value,
|
|
421
|
-
'onUpdate:modelValue': value => { search.value = value },
|
|
422
|
-
}),
|
|
423
|
-
]),
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
id: 'padding',
|
|
427
|
-
title: 'Padding',
|
|
428
|
-
icon: 'carbon:area',
|
|
429
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
430
|
-
tokens: config.theme.padding,
|
|
431
|
-
getName: key => \`p-\${key}\`,
|
|
432
|
-
}, ({ token }) => h('div', {
|
|
433
|
-
class: '__pvt-padding',
|
|
434
|
-
style: {
|
|
435
|
-
padding: token.value,
|
|
436
|
-
},
|
|
437
|
-
}, [
|
|
438
|
-
h('div', {
|
|
439
|
-
class: '__pvt-padding-box',
|
|
440
|
-
}),
|
|
441
|
-
]))),
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
id: 'margin',
|
|
445
|
-
title: 'Margin',
|
|
446
|
-
icon: 'carbon:area',
|
|
447
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
448
|
-
tokens: config.theme.margin,
|
|
449
|
-
getName: key => \`m-\${key}\`,
|
|
450
|
-
}, ({ token }) => h('div', {
|
|
451
|
-
class: '__pvt-margin',
|
|
452
|
-
}, [
|
|
453
|
-
h('div', {
|
|
454
|
-
class: '__pvt-margin-box',
|
|
455
|
-
style: {
|
|
456
|
-
margin: token.value,
|
|
457
|
-
},
|
|
458
|
-
}),
|
|
459
|
-
]))),
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
id: 'font-size',
|
|
463
|
-
title: 'Font Size',
|
|
464
|
-
icon: 'carbon:text-font',
|
|
465
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
466
|
-
tokens: config.theme.fontSize,
|
|
467
|
-
getName: key => \`text-\${key}\`,
|
|
468
|
-
}, ({ token }) => h('div', {
|
|
469
|
-
class: '__pvt-truncate',
|
|
470
|
-
style: {
|
|
471
|
-
fontSize: Array.isArray(token.value) ? token.value[0] : token.value,
|
|
472
|
-
...(Array.isArray(token.value) && typeof token.value[1] === "object" ? token.value[1] : { lineHeight: token.value[1] })
|
|
473
|
-
},
|
|
474
|
-
}, sampleText.value))),
|
|
475
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
476
|
-
h(HstTextarea, {
|
|
477
|
-
title: 'Sample text',
|
|
478
|
-
modelValue: sampleText.value,
|
|
479
|
-
'onUpdate:modelValue': value => { sampleText.value = value },
|
|
480
|
-
rows: 5,
|
|
481
|
-
}),
|
|
482
|
-
]),
|
|
483
|
-
},
|
|
484
|
-
{
|
|
485
|
-
id: 'font-weight',
|
|
486
|
-
title: 'Font Weight',
|
|
487
|
-
icon: 'carbon:text-font',
|
|
488
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
489
|
-
tokens: config.theme.fontWeight,
|
|
490
|
-
getName: key => \`font-\${key}\`,
|
|
491
|
-
}, ({ token }) => h('div', {
|
|
492
|
-
class: '__pvt-truncate',
|
|
493
|
-
style: {
|
|
494
|
-
fontWeight: token.value,
|
|
495
|
-
fontSize: \`\${fontSize.value}px\`,
|
|
496
|
-
},
|
|
497
|
-
}, sampleText.value))),
|
|
498
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
499
|
-
h(HstTextarea, {
|
|
500
|
-
title: 'Sample text',
|
|
501
|
-
modelValue: sampleText.value,
|
|
502
|
-
'onUpdate:modelValue': value => { sampleText.value = value },
|
|
503
|
-
rows: 5,
|
|
504
|
-
}),
|
|
505
|
-
h(HstNumber, {
|
|
506
|
-
title: 'Font size',
|
|
507
|
-
modelValue: fontSize.value,
|
|
508
|
-
'onUpdate:modelValue': value => { fontSize.value = value },
|
|
509
|
-
min: 1,
|
|
510
|
-
}),
|
|
511
|
-
]),
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
id: 'font-family',
|
|
515
|
-
title: 'Font Family',
|
|
516
|
-
icon: 'carbon:text-font',
|
|
517
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
518
|
-
tokens: config.theme.fontFamily,
|
|
519
|
-
getName: key => \`font-\${key}\`,
|
|
520
|
-
}, ({ token }) => h('div', {
|
|
521
|
-
class: '__pvt-truncate',
|
|
522
|
-
style: {
|
|
523
|
-
fontFamily: token.value,
|
|
524
|
-
fontSize: \`\${fontSize.value}px\`,
|
|
525
|
-
},
|
|
526
|
-
}, sampleText.value))),
|
|
527
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
528
|
-
h(HstTextarea, {
|
|
529
|
-
title: 'Sample text',
|
|
530
|
-
modelValue: sampleText.value,
|
|
531
|
-
'onUpdate:modelValue': value => { sampleText.value = value },
|
|
532
|
-
rows: 5,
|
|
533
|
-
}),
|
|
534
|
-
h(HstNumber, {
|
|
535
|
-
title: 'Font size',
|
|
536
|
-
modelValue: fontSize.value,
|
|
537
|
-
'onUpdate:modelValue': value => { fontSize.value = value },
|
|
538
|
-
min: 1,
|
|
539
|
-
}),
|
|
540
|
-
]),
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
id: 'letter-spacing',
|
|
544
|
-
title: 'Letter Spacing',
|
|
545
|
-
icon: 'carbon:text-font',
|
|
546
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
547
|
-
tokens: config.theme.letterSpacing,
|
|
548
|
-
getName: key => \`tracking-\${key}\`,
|
|
549
|
-
}, ({ token }) => h('div', {
|
|
550
|
-
class: '__pvt-truncate',
|
|
551
|
-
style: {
|
|
552
|
-
letterSpacing: token.value,
|
|
553
|
-
fontSize: \`\${fontSize.value}px\`,
|
|
554
|
-
},
|
|
555
|
-
}, sampleText.value))),
|
|
556
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
557
|
-
h(HstTextarea, {
|
|
558
|
-
title: 'Sample text',
|
|
559
|
-
modelValue: sampleText.value,
|
|
560
|
-
'onUpdate:modelValue': value => { sampleText.value = value },
|
|
561
|
-
rows: 5,
|
|
562
|
-
}),
|
|
563
|
-
h(HstNumber, {
|
|
564
|
-
title: 'Font size',
|
|
565
|
-
modelValue: fontSize.value,
|
|
566
|
-
'onUpdate:modelValue': value => { fontSize.value = value },
|
|
567
|
-
min: 1,
|
|
568
|
-
}),
|
|
569
|
-
]),
|
|
570
|
-
},
|
|
571
|
-
{
|
|
572
|
-
id: 'line-height',
|
|
573
|
-
title: 'Line Height',
|
|
574
|
-
icon: 'carbon:text-font',
|
|
575
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
576
|
-
tokens: config.theme.lineHeight,
|
|
577
|
-
getName: key => \`leading-\${key}\`,
|
|
578
|
-
}, ({ token }) => h('div', {
|
|
579
|
-
style: {
|
|
580
|
-
lineHeight: token.value,
|
|
581
|
-
},
|
|
582
|
-
}, sampleText.value))),
|
|
583
|
-
onMountControls: (api) => mountApp(api, () => [
|
|
584
|
-
h(HstTextarea, {
|
|
585
|
-
title: 'Sample text',
|
|
586
|
-
modelValue: sampleText.value,
|
|
587
|
-
'onUpdate:modelValue': value => { sampleText.value = value },
|
|
588
|
-
rows: 5,
|
|
589
|
-
}),
|
|
590
|
-
// @TODO select font size
|
|
591
|
-
]),
|
|
592
|
-
},
|
|
593
|
-
{
|
|
594
|
-
id: 'drop-shadow',
|
|
595
|
-
title: 'Drop Shadow',
|
|
596
|
-
icon: 'carbon:shape-except',
|
|
597
|
-
onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
|
|
598
|
-
tokens: config.theme.dropShadow,
|
|
599
|
-
getName: key => '' + (key === 'DEFAULT' ? 'drop-shadow' : \`drop-shadow-\${key}\`),
|
|
600
|
-
colSize: 180,
|
|
601
|
-
}, ({ token }) => h('div', {
|
|
602
|
-
class: '__pvt-drop-shadow',
|
|
603
|
-
style: {
|
|
604
|
-
filter: \`\${(Array.isArray(token.value) ? token.value : [token.value]).map(v => \`drop-shadow(\${v})\`).join(' ')}\`,
|
|
605
|
-
},
|
|
606
|
-
}))),
|
|
607
|
-
},
|
|
608
|
-
{
|
|
609
|
-
id: 'border-radius',
|
|
610
|
-
title: 'Border Radius',
|
|
611
|
-
icon: 'carbon:condition-wait-point',
|
|
612
|
-
onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
|
|
613
|
-
tokens: config.theme.borderRadius,
|
|
614
|
-
getName: key => '' + (key === 'DEFAULT' ? 'rounded' : \`rounded-\${key}\`),
|
|
615
|
-
colSize: 180,
|
|
616
|
-
}, ({ token }) => h('div', {
|
|
617
|
-
class: '__pvt-border-radius',
|
|
618
|
-
style: {
|
|
619
|
-
borderRadius: token.value,
|
|
620
|
-
},
|
|
621
|
-
}))),
|
|
622
|
-
},
|
|
623
|
-
{
|
|
624
|
-
id: 'border-width',
|
|
625
|
-
title: 'Border Width',
|
|
626
|
-
icon: 'carbon:checkbox',
|
|
627
|
-
onMount: (api) => mountApp(api, () => h(HstTokenGrid, {
|
|
628
|
-
tokens: config.theme.borderWidth,
|
|
629
|
-
getName: key => '' + (key === 'DEFAULT' ? 'border' : \`border-\${key}\`),
|
|
630
|
-
colSize: 180,
|
|
631
|
-
}, ({ token }) => h('div', {
|
|
632
|
-
class: '__pvt-border-width',
|
|
633
|
-
style: {
|
|
634
|
-
borderWidth: token.value,
|
|
635
|
-
},
|
|
636
|
-
}))),
|
|
637
|
-
},
|
|
638
|
-
{
|
|
639
|
-
id: 'width',
|
|
640
|
-
title: 'Width',
|
|
641
|
-
icon: 'carbon:pan-horizontal',
|
|
642
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
643
|
-
tokens: config.theme.width,
|
|
644
|
-
getName: key => '' + (key === 'DEFAULT' ? 'w' : \`w-\${key}\`),
|
|
645
|
-
}, ({ token }) => h('div', {
|
|
646
|
-
class: '__pvt-width',
|
|
647
|
-
}, [
|
|
648
|
-
h('div', {
|
|
649
|
-
class: '__pvt-width-box',
|
|
650
|
-
style: {
|
|
651
|
-
width: token.value,
|
|
652
|
-
},
|
|
653
|
-
}),
|
|
654
|
-
]))),
|
|
655
|
-
},
|
|
656
|
-
{
|
|
657
|
-
id: 'height',
|
|
658
|
-
title: 'Height',
|
|
659
|
-
icon: 'carbon:pan-vertical',
|
|
660
|
-
onMount: (api) => mountApp(api, () => h(HstTokenList, {
|
|
661
|
-
tokens: config.theme.height,
|
|
662
|
-
getName: key => '' + (key === 'DEFAULT' ? 'h' : \`h-\${key}\`),
|
|
663
|
-
}, ({ token }) => h('div', {
|
|
664
|
-
class: '__pvt-height',
|
|
665
|
-
style: {
|
|
666
|
-
height: token.value,
|
|
667
|
-
},
|
|
668
|
-
}))),
|
|
669
|
-
},
|
|
670
|
-
{
|
|
671
|
-
id: 'full-config',
|
|
672
|
-
title: 'Full Config',
|
|
673
|
-
icon: 'carbon:code',
|
|
674
|
-
onMount: (api) => mountApp(api, () => h('pre', JSON.stringify(config, null, 2))),
|
|
675
|
-
},
|
|
676
|
-
],
|
|
677
|
-
}`
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
const css = `.__pvt-shade {
|
|
681
|
-
height: 80px;
|
|
682
|
-
border-radius: 4px;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
.__pvt-text {
|
|
686
|
-
font-size: 4rem;
|
|
687
|
-
display: flex;
|
|
688
|
-
align-items: flex-end;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
.__pvt-border {
|
|
692
|
-
border-style: solid;
|
|
693
|
-
border-width: 2px;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
.__pvt-padding {
|
|
697
|
-
background-color: rgb(113 113 122 / 0.1);
|
|
698
|
-
width: min-content;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
.__pvt-margin {
|
|
702
|
-
border: dashed 1px rgb(113 113 122 / 0.5);
|
|
703
|
-
width: min-content;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
.__pvt-padding-box,
|
|
707
|
-
.__pvt-margin-box {
|
|
708
|
-
width: 5rem;
|
|
709
|
-
height: 5rem;
|
|
710
|
-
background-color: rgb(113 113 122 / 0.5);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
.__pvt-padding,
|
|
714
|
-
.__pvt-padding-box,
|
|
715
|
-
.__pvt-margin,
|
|
716
|
-
.__pvt-margin-box,
|
|
717
|
-
.__pvt-drop-shadow {
|
|
718
|
-
border-radius: 4px;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
.__pvt-truncate {
|
|
722
|
-
overflow: hidden;
|
|
723
|
-
text-overflow: ellipsis;
|
|
724
|
-
white-space: nowrap;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
.__pvt-drop-shadow {
|
|
728
|
-
width: 8rem;
|
|
729
|
-
height: 8rem;
|
|
730
|
-
background: white;
|
|
731
|
-
margin-bottom: 0.5rem;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
.__pvt-drop-shadow {
|
|
735
|
-
background: #4e4e57;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
.__pvt-border-radius {
|
|
739
|
-
width: 8rem;
|
|
740
|
-
height: 8rem;
|
|
741
|
-
background-color: rgb(113 113 122 / 0.5);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
.__pvt-border-width {
|
|
745
|
-
width: 8rem;
|
|
746
|
-
height: 8rem;
|
|
747
|
-
border-color: rgb(113 113 122 / 0.5);
|
|
748
|
-
background-color: rgb(113 113 122 / 0.1);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
.__pvt-width {
|
|
752
|
-
background-color: rgb(113 113 122 / 0.1);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
.__pvt-width-box,
|
|
756
|
-
.__pvt-height {
|
|
757
|
-
background-color: rgb(113 113 122 / 0.5);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
.__pvt-width-box {
|
|
761
|
-
height: 5rem;
|
|
762
|
-
}`
|
|
763
|
-
|
|
764
|
-
/** @deprecated Use `HstTailwind`. Kept for books that named the old builtin. */
|
|
765
|
-
export const tailwindTokens = HstTailwind
|
package/tsconfig.json
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
// Volar
|
|
5
|
-
"jsx": "preserve",
|
|
6
|
-
"lib": [
|
|
7
|
-
"ESNext",
|
|
8
|
-
"DOM"
|
|
9
|
-
],
|
|
10
|
-
"rootDir": "src",
|
|
11
|
-
"module": "ESNext",
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"types": [
|
|
15
|
-
"node"
|
|
16
|
-
],
|
|
17
|
-
"strictBindCallApply": true,
|
|
18
|
-
"strictFunctionTypes": true,
|
|
19
|
-
"alwaysStrict": true,
|
|
20
|
-
// Strict
|
|
21
|
-
"noImplicitAny": false,
|
|
22
|
-
"noImplicitThis": true,
|
|
23
|
-
"outDir": "dist",
|
|
24
|
-
"removeComments": false,
|
|
25
|
-
"sourceMap": false,
|
|
26
|
-
"allowSyntheticDefaultImports": true,
|
|
27
|
-
"esModuleInterop": true,
|
|
28
|
-
"skipLibCheck": true,
|
|
29
|
-
"preserveWatchOutput": true
|
|
30
|
-
},
|
|
31
|
-
"include": [
|
|
32
|
-
"src"
|
|
33
|
-
],
|
|
34
|
-
"exclude": [
|
|
35
|
-
"node_modules",
|
|
36
|
-
"generated/**/*",
|
|
37
|
-
"dist/**/*",
|
|
38
|
-
"src/**/*.spec.ts"
|
|
39
|
-
]
|
|
40
|
-
}
|