@presetter/preset-web 9.0.1
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 +21 -0
- package/README.md +545 -0
- package/lib/eslint/override.d.ts +4 -0
- package/lib/eslint/override.d.ts.map +1 -0
- package/lib/eslint/override.js +31 -0
- package/lib/eslint/template.d.ts +6 -0
- package/lib/eslint/template.d.ts.map +1 -0
- package/lib/eslint/template.js +29 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +39 -0
- package/lib/module.d.ts +9 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +12 -0
- package/lib/tailwind/config.d.ts +7 -0
- package/lib/tailwind/config.d.ts.map +1 -0
- package/lib/tailwind/config.js +22 -0
- package/lib/tailwind/entry.d.ts +7 -0
- package/lib/tailwind/entry.d.ts.map +1 -0
- package/lib/tailwind/entry.js +134 -0
- package/lib/tailwind/index.d.ts +3 -0
- package/lib/tailwind/index.d.ts.map +1 -0
- package/lib/tailwind/index.js +4 -0
- package/overrides/tsconfig.yaml +6 -0
- package/package.json +59 -0
- package/templates/image.d.ts +48 -0
- package/templates/style.d.ts +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Alvis HT Tang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
# 🚀 @presetter/preset-web
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/alvis/presetter/master/assets/logo.svg" alt="Presetter logo" height="128">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
[](https://github.com/alvis/presetter/releases)
|
|
10
|
+
[](https://github.com/alvis/presetter/actions)
|
|
11
|
+
[](https://codeclimate.com/github/alvis/presetter/maintainability)
|
|
12
|
+
[](https://codeclimate.com/github/alvis/presetter/test_coverage)
|
|
13
|
+
[](https://sonarcloud.io/summary/new_code?id=presetter)
|
|
14
|
+
[](https://libraries.io/npm/@presetter/preset-web)
|
|
15
|
+
|
|
16
|
+
Modern web development — TailwindCSS, Storybook, browser-optimized TypeScript
|
|
17
|
+
|
|
18
|
+
• [Usage](#-usage) • [Configuration](#-configuration-details) • [Comparison](#-comparison) • [FAQ](#-faq) •
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
**This is a configuration extension that works with [Presetter](https://github.com/alvis/presetter/blob/main/packages/presetter), the configuration management tool.**
|
|
25
|
+
|
|
26
|
+
## ⚡ TL;DR / Quick Start
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Install web preset alongside a base preset
|
|
30
|
+
npm i -D presetter @presetter/preset-essentials @presetter/preset-web
|
|
31
|
+
|
|
32
|
+
# Create presetter.config.ts
|
|
33
|
+
cat > presetter.config.ts << 'EOF'
|
|
34
|
+
import { preset } from 'presetter';
|
|
35
|
+
import essentials from '@presetter/preset-essentials';
|
|
36
|
+
import web from '@presetter/preset-web';
|
|
37
|
+
|
|
38
|
+
export default preset('my-web-app', {
|
|
39
|
+
extends: [essentials, web],
|
|
40
|
+
});
|
|
41
|
+
EOF
|
|
42
|
+
|
|
43
|
+
# Bootstrap your project
|
|
44
|
+
npx presetter bootstrap
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Your project now has **modern web development tooling** — TailwindCSS 4, Storybook 9, browser-optimized TypeScript, and intelligent CSS workflows!
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## ✨ Modern Web Development Stack
|
|
52
|
+
|
|
53
|
+
### Need comprehensive web tooling?
|
|
54
|
+
|
|
55
|
+
Modern web development requires an intricate stack: CSS frameworks, component libraries, browser compatibility, styling workflows, and visual development tools. Setting these up manually is time-consuming and error-prone.
|
|
56
|
+
|
|
57
|
+
**What if you could get the complete modern web stack instantly?**
|
|
58
|
+
|
|
59
|
+
### The modern web development challenge
|
|
60
|
+
|
|
61
|
+
| Web Development Need | Manual Setup | With preset-web |
|
|
62
|
+
| ------------------------- | --------------------------- | ------------------------------------ |
|
|
63
|
+
| **CSS Framework** | ⚠️ Manual TailwindCSS setup | ✅ TailwindCSS 4 auto-configured |
|
|
64
|
+
| **Component Development** | ❌ No visual development | ✅ Storybook 9 with addons |
|
|
65
|
+
| **Browser Compatibility** | ⚠️ Manual TypeScript config | ✅ DOM/Browser types included |
|
|
66
|
+
| **Styling Workflow** | ❌ Basic CSS processing | ✅ PostCSS + Autoprefixer + Prettier |
|
|
67
|
+
| **CSS Linting** | ❌ No CSS-specific rules | ✅ TailwindCSS conflict detection |
|
|
68
|
+
| **Development Tools** | ⚠️ Fragmented tooling | ✅ Integrated accessibility testing |
|
|
69
|
+
|
|
70
|
+
### What you get instead
|
|
71
|
+
|
|
72
|
+
**@presetter/preset-web is a configuration extension that adds comprehensive modern web development tooling to any base preset.**
|
|
73
|
+
|
|
74
|
+
When used with [Presetter](https://github.com/alvis/presetter/blob/main/packages/presetter) (the configuration management tool), this preset extends your chosen base preset with the complete modern web development stack, including TailwindCSS 4, Storybook 9, browser-optimized TypeScript, and intelligent styling workflows.
|
|
75
|
+
|
|
76
|
+
- 💨 **TailwindCSS 4**: Latest utility-first CSS framework with intelligent auto-discovery
|
|
77
|
+
- 📚 **Storybook 9**: Component-driven development with accessibility testing
|
|
78
|
+
- 🎨 **PostCSS Pipeline**: Advanced CSS processing with autoprefixer
|
|
79
|
+
- 🌐 **Browser-Optimized**: TypeScript configured for DOM and modern browser APIs
|
|
80
|
+
- 🔍 **Smart Linting**: TailwindCSS conflict detection and auto-formatting
|
|
81
|
+
- 🚀 **Zero Config**: Intelligent discovery of project structure and entry points
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🎯 Modern Web Without the Configuration
|
|
86
|
+
|
|
87
|
+
### The modern web tooling setup problem
|
|
88
|
+
|
|
89
|
+
Modern web development requires coordinating multiple complex tools:
|
|
90
|
+
|
|
91
|
+
- **TailwindCSS setup**: Configuration, purging, entry points, plugin integration
|
|
92
|
+
- **Storybook configuration**: Stories, addons, accessibility testing, Vitest integration
|
|
93
|
+
- **Browser TypeScript**: DOM types, modern JavaScript features, web-specific APIs
|
|
94
|
+
- **CSS workflow**: PostCSS, autoprefixer, formatting, conflict detection
|
|
95
|
+
- **Development environment**: Hot reloading, visual development, testing integration
|
|
96
|
+
|
|
97
|
+
**Getting it right requires deep knowledge of each tool's configuration and how they interact.**
|
|
98
|
+
|
|
99
|
+
### From fragmented tooling to integrated web stack
|
|
100
|
+
|
|
101
|
+
```diff
|
|
102
|
+
# Before: Manual web development setup
|
|
103
|
+
my-web-app/
|
|
104
|
+
├── tsconfig.json ← Missing DOM types, browser APIs
|
|
105
|
+
├── tailwind.config.js ← Manual configuration, no auto-discovery
|
|
106
|
+
├── postcss.config.js ← Basic setup, missing optimizations
|
|
107
|
+
├── .storybook/ ← Complex manual setup
|
|
108
|
+
│ ├── main.js ← Missing modern addons
|
|
109
|
+
│ └── preview.js ← No accessibility testing
|
|
110
|
+
├── src/
|
|
111
|
+
│ ├── styles/
|
|
112
|
+
│ │ └── globals.css ← No auto-discovery
|
|
113
|
+
│ └── components/
|
|
114
|
+
- └── Button.tsx ← No component development environment
|
|
115
|
+
|
|
116
|
+
# After: Extended with modern web stack
|
|
117
|
+
my-web-app/
|
|
118
|
+
+├── presetter.config.ts ← Base preset + web extension
|
|
119
|
+
├── tsconfig.json ← Enhanced with DOM, browser types
|
|
120
|
+
├── eslint.config.ts ← Enhanced with TailwindCSS linting
|
|
121
|
+
├── .prettierrc ← Enhanced with TailwindCSS formatting
|
|
122
|
+
+├── All web dev tools ← Generated with intelligent discovery
|
|
123
|
+
├── src/
|
|
124
|
+
│ ├── styles/
|
|
125
|
+
│ │ └── globals.css ← Auto-discovered for TailwindCSS
|
|
126
|
+
│ └── components/
|
|
127
|
+
+ └── Button.tsx ← Storybook-ready component development
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### How modern web stack integration works
|
|
131
|
+
|
|
132
|
+
1. **Intelligent Discovery** — Auto-detects TailwindCSS entry points, config files, project structure
|
|
133
|
+
2. **Browser Optimization** — TypeScript configured with DOM, DOM.Iterable, and ESNext libraries
|
|
134
|
+
3. **Styling Workflow** — PostCSS + TailwindCSS + Prettier integration with conflict detection
|
|
135
|
+
4. **Component Development** — Storybook 9 with accessibility, testing, and pseudo-state addons
|
|
136
|
+
|
|
137
|
+
### Why this solves the real problem
|
|
138
|
+
|
|
139
|
+
- **Complete modern stack**: Everything needed for professional web development
|
|
140
|
+
- **Intelligent auto-configuration**: Discovers project structure automatically
|
|
141
|
+
- **Component-driven development**: Visual development environment with testing
|
|
142
|
+
- **Professional styling**: Advanced CSS workflows with conflict detection
|
|
143
|
+
- **Browser compatibility**: Properly configured for modern web APIs
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 🔍 Understanding Presetter vs This Extension
|
|
148
|
+
|
|
149
|
+
**Important distinction:**
|
|
150
|
+
|
|
151
|
+
| Component | Role | What it does |
|
|
152
|
+
| -------------------------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------------------------- |
|
|
153
|
+
| **[Presetter](https://github.com/alvis/presetter/blob/main/packages/presetter)** | Configuration management tool | CLI that processes presets, generates config files, executes scripts |
|
|
154
|
+
| **Base Preset** | Core development template | Provides TypeScript, testing, building capabilities (essentials, esm, cjs, etc.) |
|
|
155
|
+
| **@presetter/preset-web** | Web development extension | Adds TailwindCSS, Storybook, browser optimization, CSS workflows |
|
|
156
|
+
|
|
157
|
+
**Think of it like:**
|
|
158
|
+
|
|
159
|
+
- **Presetter** = The engine that builds houses
|
|
160
|
+
- **Base preset** = The blueprint for a functional house
|
|
161
|
+
- **This extension** = The modern kitchen, smart home systems, and designer finishes
|
|
162
|
+
|
|
163
|
+
This preset **extends** any base preset with modern web development capabilities. For advanced usage, customization, and troubleshooting, **[visit the main Presetter documentation](https://github.com/alvis/presetter/blob/main/packages/presetter)**.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 🚀 Usage
|
|
168
|
+
|
|
169
|
+
### 🟢 Basic Modern Web Setup
|
|
170
|
+
|
|
171
|
+
#### Step 1: Install Extension with Base Preset
|
|
172
|
+
|
|
173
|
+
```jsonc
|
|
174
|
+
// package.json
|
|
175
|
+
{
|
|
176
|
+
"scripts": {
|
|
177
|
+
"build": "run build",
|
|
178
|
+
"test": "run test",
|
|
179
|
+
"storybook": "storybook dev -p 6006",
|
|
180
|
+
"build-storybook": "storybook build",
|
|
181
|
+
},
|
|
182
|
+
"devDependencies": {
|
|
183
|
+
"presetter": "latest",
|
|
184
|
+
"@presetter/preset-essentials": "latest",
|
|
185
|
+
"@presetter/preset-web": "latest",
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// presetter.config.ts
|
|
192
|
+
import { preset } from 'presetter';
|
|
193
|
+
import essentials from '@presetter/preset-essentials';
|
|
194
|
+
import web from '@presetter/preset-web';
|
|
195
|
+
|
|
196
|
+
export default preset('my-web-app', {
|
|
197
|
+
extends: [essentials, web], // Base preset + web extension
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### Step 2: Bootstrap & Develop
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npm install
|
|
205
|
+
# Modern web development stack generated automatically
|
|
206
|
+
# TailwindCSS, Storybook, and browser optimization ready!
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
That's it! Start developing with the complete modern web stack.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### 🧑🔬 Advanced Usage: Custom Web Optimizations
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// presetter.config.ts
|
|
217
|
+
import { preset } from 'presetter';
|
|
218
|
+
import essentials from '@presetter/preset-essentials';
|
|
219
|
+
import web from '@presetter/preset-web';
|
|
220
|
+
|
|
221
|
+
export default preset('advanced-web-app', {
|
|
222
|
+
extends: [essentials, web],
|
|
223
|
+
override: {
|
|
224
|
+
assets: {
|
|
225
|
+
'tsconfig.json': {
|
|
226
|
+
compilerOptions: {
|
|
227
|
+
lib: ['DOM', 'DOM.Iterable', 'ES2023'], // Latest features
|
|
228
|
+
target: 'ES2024', // Modern browser target
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
'eslint.config.ts': {
|
|
232
|
+
rules: {
|
|
233
|
+
// Custom TailwindCSS rules
|
|
234
|
+
'tailwindcss/no-custom-classname': 'warn',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
> **Need more customization options?** Check the [main Presetter documentation](https://github.com/alvis/presetter/blob/main/packages/presetter) for complete guides on overrides, extensions, and advanced configurations.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 📖 API Reference
|
|
247
|
+
|
|
248
|
+
### Core Web Development Extension
|
|
249
|
+
|
|
250
|
+
This preset extends any base preset with modern web development capabilities:
|
|
251
|
+
|
|
252
|
+
| Enhancement | Purpose | Web Features |
|
|
253
|
+
| ---------------------- | --------------------- | -------------------------------------------------------- |
|
|
254
|
+
| **TailwindCSS 4** | Utility-first CSS | Auto-discovery, conflict detection, formatting |
|
|
255
|
+
| **Storybook 9** | Component development | Accessibility testing, Vitest integration, pseudo-states |
|
|
256
|
+
| **Browser TypeScript** | Web APIs | DOM types, modern JavaScript features |
|
|
257
|
+
| **CSS Workflow** | Styling pipeline | PostCSS, autoprefixer, intelligent formatting |
|
|
258
|
+
|
|
259
|
+
### TailwindCSS Integration
|
|
260
|
+
|
|
261
|
+
#### Auto-Discovery Features
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// Automatically discovers entry files in:
|
|
265
|
+
const searchDirectories = [
|
|
266
|
+
'source',
|
|
267
|
+
'src',
|
|
268
|
+
'app',
|
|
269
|
+
'styles',
|
|
270
|
+
'assets',
|
|
271
|
+
'public',
|
|
272
|
+
'static',
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
const entryFiles = [
|
|
276
|
+
'globals.css',
|
|
277
|
+
'global.css',
|
|
278
|
+
'index.css',
|
|
279
|
+
'main.css',
|
|
280
|
+
'styles.css',
|
|
281
|
+
];
|
|
282
|
+
|
|
283
|
+
// Scans for @import "tailwindcss" directives
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### Enhanced Linting
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// eslint-plugin-better-tailwindcss
|
|
290
|
+
'tailwindcss/classnames-order': 'warn', // Consistent ordering
|
|
291
|
+
'tailwindcss/enforces-negative-arbitrary-values': 'warn', // Proper syntax
|
|
292
|
+
'tailwindcss/no-contradicting-classname': 'error', // Conflict detection
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Storybook Configuration
|
|
296
|
+
|
|
297
|
+
#### Core Addons Included
|
|
298
|
+
|
|
299
|
+
- **@storybook/addon-a11y**: Accessibility testing and guidelines
|
|
300
|
+
- **@storybook/addon-vitest**: Seamless Vitest integration for component testing
|
|
301
|
+
- **storybook-addon-pseudo-states**: CSS pseudo-state visualization (hover, focus, etc.)
|
|
302
|
+
- **storybook-addon-test-codegen**: Automatic test code generation from stories
|
|
303
|
+
|
|
304
|
+
#### Browser Environment
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// Enhanced TypeScript configuration
|
|
308
|
+
compilerOptions: {
|
|
309
|
+
lib: ['DOM', 'DOM.Iterable', 'ESNext'], // Complete browser API support
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Configuration Variables
|
|
314
|
+
|
|
315
|
+
Inherited from base preset with web-specific enhancements:
|
|
316
|
+
|
|
317
|
+
| Variable | Default | Description |
|
|
318
|
+
| --------------------- | --------------- | --------------------------------------- |
|
|
319
|
+
| Base preset variables | Inherited | All variables from chosen base preset |
|
|
320
|
+
| TailwindCSS entry | Auto-discovered | Automatically found CSS entry points |
|
|
321
|
+
| Config files | Auto-discovered | Automatically found configuration files |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 🔧 Configuration Details
|
|
326
|
+
|
|
327
|
+
### Intelligent TailwindCSS Discovery
|
|
328
|
+
|
|
329
|
+
#### Entry Point Detection
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// Searches common directories for CSS files
|
|
333
|
+
const directories = ['src', 'app', 'styles', 'assets'];
|
|
334
|
+
const filenames = ['globals.css', 'index.css', 'main.css'];
|
|
335
|
+
|
|
336
|
+
// Scans file contents for TailwindCSS imports
|
|
337
|
+
const tailwindImports = /@import\s+["']tailwindcss/;
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Config File Detection
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// Automatically finds configuration files
|
|
344
|
+
const configPatterns = [
|
|
345
|
+
'tailwind.config.ts',
|
|
346
|
+
'tailwind.config.js',
|
|
347
|
+
'tailwind.config.mjs',
|
|
348
|
+
'tailwind.config.cjs',
|
|
349
|
+
];
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Enhanced ESLint Configuration
|
|
353
|
+
|
|
354
|
+
#### Web-Specific Plugins
|
|
355
|
+
|
|
356
|
+
- **eslint-plugin-better-tailwindcss**: Advanced TailwindCSS linting
|
|
357
|
+
- **eslint-plugin-storybook**: Storybook-specific rules
|
|
358
|
+
- **globals**: Browser environment variables
|
|
359
|
+
|
|
360
|
+
#### Browser Globals
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
globals: {
|
|
364
|
+
window: 'readonly',
|
|
365
|
+
document: 'readonly',
|
|
366
|
+
navigator: 'readonly',
|
|
367
|
+
// ... all browser globals
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### TypeScript Browser Optimization
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
# tsconfig.json override
|
|
375
|
+
compilerOptions:
|
|
376
|
+
lib:
|
|
377
|
+
- DOM # Browser DOM APIs
|
|
378
|
+
- DOM.Iterable # Iterable DOM elements
|
|
379
|
+
- ESNext # Latest JavaScript features
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 🏎️ Performance
|
|
385
|
+
|
|
386
|
+
| Metric | Standard Preset | With preset-web |
|
|
387
|
+
| ---------------------- | -------------------- | --------------------------------- |
|
|
388
|
+
| Component development | Manual setup | **Storybook visual environment** |
|
|
389
|
+
| CSS workflow | Basic | **Advanced PostCSS pipeline** |
|
|
390
|
+
| Browser compatibility | Manual configuration | **Auto-optimized TypeScript** |
|
|
391
|
+
| Styling conflicts | Manual detection | **Automated TailwindCSS linting** |
|
|
392
|
+
| Development experience | Fragmented tools | **Integrated modern stack** |
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## 🌐 Compatibility
|
|
397
|
+
|
|
398
|
+
| Environment | Support |
|
|
399
|
+
| ------------ | --------------------------------------- |
|
|
400
|
+
| Base Presets | Works with essentials, esm, cjs, hybrid |
|
|
401
|
+
| Browsers | Modern browsers (ES2024+) |
|
|
402
|
+
| Node.js | ≥ 18 |
|
|
403
|
+
| TypeScript | ≥ 5.0 |
|
|
404
|
+
|
|
405
|
+
### Works With All Base Presets
|
|
406
|
+
|
|
407
|
+
- [`@presetter/preset-essentials`](../preset-essentials) + web development
|
|
408
|
+
- [`@presetter/preset-esm`](../preset-esm) + web development
|
|
409
|
+
- [`@presetter/preset-cjs`](../preset-cjs) + web development
|
|
410
|
+
- [`@presetter/preset-hybrid`](../preset-hybrid) + web development
|
|
411
|
+
|
|
412
|
+
### Can Be Combined With
|
|
413
|
+
|
|
414
|
+
- [`@presetter/preset-react`](../preset-react) - React + modern web stack
|
|
415
|
+
- [`@presetter/preset-strict`](../preset-strict) - Web development + strict quality
|
|
416
|
+
|
|
417
|
+
### Extended By
|
|
418
|
+
|
|
419
|
+
- [`@presetter/preset-react`](../preset-react) - Adds React-specific features to web stack
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## 🆚 Comparison
|
|
424
|
+
|
|
425
|
+
| Feature | Standard Presets | With preset-web |
|
|
426
|
+
| ------------------------- | ---------------- | ----------------------------- |
|
|
427
|
+
| **CSS Framework** | None | ✅ TailwindCSS 4 |
|
|
428
|
+
| **Component Development** | Basic | ✅ Storybook 9 environment |
|
|
429
|
+
| **Browser Optimization** | Manual | ✅ Auto-configured TypeScript |
|
|
430
|
+
| **CSS Workflow** | Basic | ✅ PostCSS + Autoprefixer |
|
|
431
|
+
| **Visual Development** | CLI only | ✅ Component playground |
|
|
432
|
+
| **Accessibility Testing** | Manual | ✅ Automated Storybook addon |
|
|
433
|
+
|
|
434
|
+
### When to Use
|
|
435
|
+
|
|
436
|
+
✅ **Use preset-web when:**
|
|
437
|
+
|
|
438
|
+
- Building web applications or component libraries
|
|
439
|
+
- Need modern CSS workflows (TailwindCSS)
|
|
440
|
+
- Want visual component development (Storybook)
|
|
441
|
+
- Developing for browser environments
|
|
442
|
+
- Need accessibility testing integration
|
|
443
|
+
- Want professional styling workflows
|
|
444
|
+
|
|
445
|
+
❌ **Consider alternatives when:**
|
|
446
|
+
|
|
447
|
+
- Building Node.js applications or CLIs
|
|
448
|
+
- No visual UI components needed
|
|
449
|
+
- Basic styling requirements only
|
|
450
|
+
- Minimal web development needs
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## 🛠️ Troubleshooting
|
|
455
|
+
|
|
456
|
+
> **General Presetter issues?** See the [main troubleshooting guide](https://github.com/alvis/presetter/blob/main/README.md#troubleshooting) for common Presetter problems and solutions.
|
|
457
|
+
|
|
458
|
+
### Web Development Specific Issues
|
|
459
|
+
|
|
460
|
+
| Issue | Symptoms | Solution |
|
|
461
|
+
| ----------------------------------- | --------------------------------- | -------------------------------------------------------------- |
|
|
462
|
+
| **TailwindCSS not auto-discovered** | No CSS framework integration | Ensure CSS files are in common directories (`src/`, `styles/`) |
|
|
463
|
+
| **Storybook not starting** | Component development unavailable | Check that base preset provides build tooling |
|
|
464
|
+
| **Browser types missing** | TypeScript errors with DOM APIs | Ensure TypeScript override is applied correctly |
|
|
465
|
+
| **CSS conflicts undetected** | TailwindCSS class conflicts | Check ESLint TailwindCSS plugin configuration |
|
|
466
|
+
|
|
467
|
+
> **Need help with Presetter CLI commands?** Check the [CLI reference](https://github.com/alvis/presetter/blob/main/README.md#cli-reference) in the main documentation.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## ❓ FAQ
|
|
472
|
+
|
|
473
|
+
> **General Presetter questions?** Check the [main FAQ](https://github.com/alvis/presetter/blob/main/README.md#faq) for general usage, configuration, and customization questions.
|
|
474
|
+
|
|
475
|
+
### Web Development Specific FAQs
|
|
476
|
+
|
|
477
|
+
#### Do I need a base preset?
|
|
478
|
+
|
|
479
|
+
Yes! preset-web is an **extension preset** that adds web tooling to base functionality:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
// ❌ Wrong - web alone doesn't provide TypeScript tooling
|
|
483
|
+
extends: [web]
|
|
484
|
+
|
|
485
|
+
// ✅ Correct - base preset + web extension
|
|
486
|
+
extends: [essentials, web]
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
#### How does TailwindCSS auto-discovery work?
|
|
490
|
+
|
|
491
|
+
The preset intelligently scans your project:
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
// Searches these directories for CSS files
|
|
495
|
+
['src', 'app', 'styles', 'assets', 'public', 'static']
|
|
496
|
+
|
|
497
|
+
// Looks for these common CSS file names
|
|
498
|
+
['globals.css', 'global.css', 'index.css', 'main.css', 'styles.css']
|
|
499
|
+
|
|
500
|
+
// Scans file contents for TailwindCSS imports
|
|
501
|
+
/@import\s+["']tailwindcss/
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
#### What Storybook addons are included?
|
|
505
|
+
|
|
506
|
+
Professional component development addons:
|
|
507
|
+
|
|
508
|
+
- **Accessibility testing** (`@storybook/addon-a11y`)
|
|
509
|
+
- **Vitest integration** (`@storybook/addon-vitest`)
|
|
510
|
+
- **Pseudo-state testing** (`storybook-addon-pseudo-states`)
|
|
511
|
+
- **Test code generation** (`storybook-addon-test-codegen`)
|
|
512
|
+
|
|
513
|
+
#### Can I use this without TailwindCSS?
|
|
514
|
+
|
|
515
|
+
Yes! The preset provides value beyond TailwindCSS:
|
|
516
|
+
|
|
517
|
+
- Storybook for component development
|
|
518
|
+
- Browser-optimized TypeScript
|
|
519
|
+
- PostCSS workflow
|
|
520
|
+
- Enhanced ESLint for web development
|
|
521
|
+
|
|
522
|
+
#### Is this compatible with React?
|
|
523
|
+
|
|
524
|
+
Absolutely! Use with [`@presetter/preset-react`](../preset-react):
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
extends: [essentials, web, react] // Full React + web stack
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## 🤝 Contributing
|
|
533
|
+
|
|
534
|
+
We'd love your ideas and contributions!
|
|
535
|
+
Submit issues or suggestions via [GitHub Issues](https://github.com/alvis/presetter/issues).
|
|
536
|
+
See the [Contribution Guide](https://github.com/alvis/presetter/blob/main/CONTRIBUTING.md) for more details.
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## 📄 License
|
|
541
|
+
|
|
542
|
+
Released under the [MIT License](https://github.com/alvis/presetter/blob/main/LICENSE).
|
|
543
|
+
© 2020, [Alvis Tang](https://github.com/alvis).
|
|
544
|
+
|
|
545
|
+
[](https://github.com/alvis/presetter/blob/main/LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"override.d.ts","sourceRoot":"","sources":["../../src/eslint/override.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;wBAmChC,MAAM,CAAC,MAAM,EAAE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import tailwind from 'eslint-plugin-better-tailwindcss';
|
|
2
|
+
import { getDefaultSelectors } from 'eslint-plugin-better-tailwindcss/api/defaults';
|
|
3
|
+
const selectors = [
|
|
4
|
+
...getDefaultSelectors(),
|
|
5
|
+
{
|
|
6
|
+
kind: 'callee',
|
|
7
|
+
name: 'classnames',
|
|
8
|
+
},
|
|
9
|
+
];
|
|
10
|
+
export default [
|
|
11
|
+
{
|
|
12
|
+
name: '@presetter/preset-web:override:tailwindcss',
|
|
13
|
+
plugins: {
|
|
14
|
+
'better-tailwindcss': tailwind,
|
|
15
|
+
},
|
|
16
|
+
settings: {
|
|
17
|
+
'better-tailwindcss': {
|
|
18
|
+
selectors,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
rules: {
|
|
22
|
+
...tailwind.configs['recommended-warn'].rules,
|
|
23
|
+
'better-tailwindcss/no-conflicting-classes': 'warn',
|
|
24
|
+
'better-tailwindcss/no-unknown-classes': [
|
|
25
|
+
'warn',
|
|
26
|
+
{ detectComponentClasses: true },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcnJpZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXNsaW50L292ZXJyaWRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3hELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBU3BGLE1BQU0sU0FBUyxHQUFHO0lBQ2hCLEdBQUcsbUJBQW1CLEVBQUU7SUFDeEI7UUFDRSxJQUFJLEVBQUUsUUFBK0I7UUFDckMsSUFBSSxFQUFFLFlBQVk7S0FDTTtDQUNOLENBQUM7QUFFdkIsZUFBZTtJQUNiO1FBQ0UsSUFBSSxFQUFFLDRDQUE0QztRQUNsRCxPQUFPLEVBQUU7WUFDUCxvQkFBb0IsRUFBRSxRQUFRO1NBQy9CO1FBQ0QsUUFBUSxFQUFFO1lBQ1Isb0JBQW9CLEVBQUU7Z0JBQ3BCLFNBQVM7YUFDVjtTQUNGO1FBQ0QsS0FBSyxFQUFFO1lBQ0wsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsS0FBSztZQUM3QywyQ0FBMkMsRUFBRSxNQUFNO1lBQ25ELHVDQUF1QyxFQUFFO2dCQUN2QyxNQUFNO2dCQUNOLEVBQUUsc0JBQXNCLEVBQUUsSUFBSSxFQUFFO2FBQ2pDO1NBQ0Y7S0FDRjtDQUNpQixDQUFDIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/eslint/template.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;aAEL,MAAM,CAAC,MAAM,EAAE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
import { asset } from 'presetter';
|
|
3
|
+
import { locateTailwindConfigFile, locateTailwindEntryFile } from '#tailwind';
|
|
4
|
+
export default asset(async (current, { projectRoot }) => {
|
|
5
|
+
const entryPoint = await locateTailwindEntryFile(projectRoot);
|
|
6
|
+
const tailwindConfig = await locateTailwindConfigFile(projectRoot);
|
|
7
|
+
return {
|
|
8
|
+
default: [
|
|
9
|
+
...(current?.default ?? []),
|
|
10
|
+
{
|
|
11
|
+
name: '@presetter/preset-web',
|
|
12
|
+
languageOptions: {
|
|
13
|
+
globals: globals.browser,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
...(entryPoint
|
|
17
|
+
? [
|
|
18
|
+
{
|
|
19
|
+
name: '@presetter/preset-web:tailwindcss',
|
|
20
|
+
settings: {
|
|
21
|
+
'better-tailwindcss': { entryPoint, tailwindConfig },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
: []),
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXNsaW50L3RlbXBsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWxDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUk5RSxlQUFlLEtBQUssQ0FDbEIsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUU7SUFDakMsTUFBTSxVQUFVLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5RCxNQUFNLGNBQWMsR0FBRyxNQUFNLHdCQUF3QixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBRW5FLE9BQU87UUFDTCxPQUFPLEVBQUU7WUFDUCxHQUFHLENBQUMsT0FBTyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDM0I7Z0JBQ0UsSUFBSSxFQUFFLHVCQUF1QjtnQkFDN0IsZUFBZSxFQUFFO29CQUNmLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTztpQkFDekI7YUFDRjtZQUNELEdBQUcsQ0FBQyxVQUFVO2dCQUNaLENBQUMsQ0FBQztvQkFDRTt3QkFDRSxJQUFJLEVBQUUsbUNBQW1DO3dCQUN6QyxRQUFRLEVBQUU7NEJBQ1Isb0JBQW9CLEVBQUUsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFO3lCQUNyRDtxQkFDRjtpQkFDRjtnQkFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ1I7S0FDRixDQUFDO0FBQ0osQ0FBQyxDQUNGLENBQUMifQ==
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** list of configurable variables */
|
|
2
|
+
export interface Variables {
|
|
3
|
+
/** the directory containing all extra typing files (default: types) */
|
|
4
|
+
types: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const DEFAULT_VARIABLES: {
|
|
7
|
+
types: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* get the list of templates provided by this preset
|
|
11
|
+
* @returns list of preset templates
|
|
12
|
+
*/
|
|
13
|
+
declare const _default: import("presetter").Preset;
|
|
14
|
+
export default _default;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,qCAAqC;AACrC,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,iBAAiB;;CAET,CAAC;AAKtB;;;GAGG"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { preset } from '@presetter/types';
|
|
4
|
+
import * as eslintOverride from './eslint/override.js';
|
|
5
|
+
import eslintTemplate from './eslint/template.js';
|
|
6
|
+
const DIR = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
// paths to the template directories
|
|
8
|
+
const TEMPLATES = resolve(DIR, '..', 'templates');
|
|
9
|
+
const OVERRIDES = resolve(DIR, '..', 'overrides');
|
|
10
|
+
export const DEFAULT_VARIABLES = {
|
|
11
|
+
types: 'types',
|
|
12
|
+
};
|
|
13
|
+
const IMAGE_TYPE = 'image.d.ts';
|
|
14
|
+
const STYLE_TYPE = 'style.d.ts';
|
|
15
|
+
/**
|
|
16
|
+
* get the list of templates provided by this preset
|
|
17
|
+
* @returns list of preset templates
|
|
18
|
+
*/
|
|
19
|
+
export default preset('@presetter/preset-web', {
|
|
20
|
+
root: resolve(import.meta.dirname, '..'),
|
|
21
|
+
variables: DEFAULT_VARIABLES,
|
|
22
|
+
assets: ({ variables }) => ({
|
|
23
|
+
'.gitignore': (current) => [
|
|
24
|
+
...(current ?? []),
|
|
25
|
+
`/${variables.types}/${IMAGE_TYPE}`,
|
|
26
|
+
`/${variables.types}/${STYLE_TYPE}`,
|
|
27
|
+
],
|
|
28
|
+
'eslint.config.ts': eslintTemplate,
|
|
29
|
+
[`${variables.types}/${IMAGE_TYPE}`]: resolve(TEMPLATES, IMAGE_TYPE),
|
|
30
|
+
[`${variables.types}/${STYLE_TYPE}`]: resolve(TEMPLATES, STYLE_TYPE),
|
|
31
|
+
}),
|
|
32
|
+
override: {
|
|
33
|
+
assets: {
|
|
34
|
+
'tsconfig.json': resolve(OVERRIDES, 'tsconfig.yaml'),
|
|
35
|
+
'eslint.config.ts': eslintOverride,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUV6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUMsT0FBTyxLQUFLLGNBQWMsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLGNBQWMsTUFBTSxtQkFBbUIsQ0FBQztBQUUvQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFFcEQsb0NBQW9DO0FBQ3BDLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ2xELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBUWxELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHO0lBQy9CLEtBQUssRUFBRSxPQUFPO0NBQ0ssQ0FBQztBQUV0QixNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUM7QUFDaEMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBRWhDOzs7R0FHRztBQUNILGVBQWUsTUFBTSxDQUFDLHVCQUF1QixFQUFFO0lBQzdDLElBQUksRUFBRSxPQUFPLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQztJQUN4QyxTQUFTLEVBQUUsaUJBQWlCO0lBQzVCLE1BQU0sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDMUIsWUFBWSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUN6QixHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNsQixJQUFJLFNBQVMsQ0FBQyxLQUFNLElBQUksVUFBVSxFQUFFO1lBQ3BDLElBQUksU0FBUyxDQUFDLEtBQU0sSUFBSSxVQUFVLEVBQUU7U0FDckM7UUFDRCxrQkFBa0IsRUFBRSxjQUFjO1FBQ2xDLENBQUMsR0FBRyxTQUFTLENBQUMsS0FBTSxJQUFJLFVBQVUsRUFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FDNUQsU0FBUyxFQUNULFVBQVUsQ0FDWDtRQUNELENBQUMsR0FBRyxTQUFTLENBQUMsS0FBTSxJQUFJLFVBQVUsRUFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FDNUQsU0FBUyxFQUNULFVBQVUsQ0FDWDtLQUNGLENBQUM7SUFDRixRQUFRLEVBQUU7UUFDUixNQUFNLEVBQUU7WUFDTixlQUFlLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUM7WUFDcEQsa0JBQWtCLEVBQUUsY0FBYztTQUNuQztLQUNGO0NBQ0YsQ0FBQyxDQUFDIn0=
|
package/lib/module.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resolves a module specifier to its full path using the native import.meta.resolve
|
|
3
|
+
* @param specifier module specifier to resolve (e.g., package name or relative path)
|
|
4
|
+
* @param parent parent URL or path to resolve from
|
|
5
|
+
* @returns The resolved module path
|
|
6
|
+
* @see https://github.com/vitest-dev/vitest/issues/6953#issuecomment-2765228116
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveModule(specifier: string, parent?: string | URL): string;
|
|
9
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,GACpB,MAAM,CAER"}
|
package/lib/module.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* v8 ignore file -- @preserve */
|
|
2
|
+
/**
|
|
3
|
+
* resolves a module specifier to its full path using the native import.meta.resolve
|
|
4
|
+
* @param specifier module specifier to resolve (e.g., package name or relative path)
|
|
5
|
+
* @param parent parent URL or path to resolve from
|
|
6
|
+
* @returns The resolved module path
|
|
7
|
+
* @see https://github.com/vitest-dev/vitest/issues/6953#issuecomment-2765228116
|
|
8
|
+
*/
|
|
9
|
+
export function resolveModule(specifier, parent) {
|
|
10
|
+
return import.meta.resolve(specifier, parent);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxpQ0FBaUM7QUFFakM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsU0FBaUIsRUFDakIsTUFBcUI7SUFFckIsT0FBTyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2hELENBQUMifQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* locates the tailwind css config file under the root directory
|
|
3
|
+
* @param rootDirectory the root directory to search for tailwindcss config file
|
|
4
|
+
* @returns path to the tailwindcss config file
|
|
5
|
+
*/
|
|
6
|
+
export declare function locateTailwindConfigFile(rootDirectory: string): Promise<string | undefined>;
|
|
7
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/tailwind/config.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAc7B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* locates the tailwind css config file under the root directory
|
|
5
|
+
* @param rootDirectory the root directory to search for tailwindcss config file
|
|
6
|
+
* @returns path to the tailwindcss config file
|
|
7
|
+
*/
|
|
8
|
+
export async function locateTailwindConfigFile(rootDirectory) {
|
|
9
|
+
try {
|
|
10
|
+
const files = await readdir(rootDirectory);
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
if (file.startsWith('tailwind.config')) {
|
|
13
|
+
return resolve(rootDirectory, file);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// directory can't be read
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RhaWx3aW5kL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVwQzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsYUFBcUI7SUFFckIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFM0MsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxPQUFPLE9BQU8sQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdEMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsMEJBQTBCO0lBQzVCLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDIn0=
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* locates the main css file that contains the tailwind css import directive
|
|
3
|
+
* @param rootDirectory the root directory to search for css files
|
|
4
|
+
* @returns path to the css file containing `@import "tailwindcss"`
|
|
5
|
+
*/
|
|
6
|
+
export declare function locateTailwindEntryFile(rootDirectory: string): Promise<string | undefined>;
|
|
7
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/tailwind/entry.ts"],"names":[],"mappings":"AA+CA;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { resolveModule } from '#module';
|
|
4
|
+
/**
|
|
5
|
+
* resolves an import path to an absolute file path
|
|
6
|
+
* @param importPath the import path from CSS `@import` statement
|
|
7
|
+
* @param currentFilePath the path of the current file being processed
|
|
8
|
+
* @returns resolved absolute file path
|
|
9
|
+
*/
|
|
10
|
+
function resolveImportPath(importPath, currentFilePath) {
|
|
11
|
+
return importPath.startsWith('.')
|
|
12
|
+
? // resolve relative imports
|
|
13
|
+
resolve(dirname(currentFilePath), importPath)
|
|
14
|
+
: // resolve module imports using import.meta.resolve
|
|
15
|
+
resolveModule(importPath, `file://${currentFilePath}`).replace('file://', '');
|
|
16
|
+
}
|
|
17
|
+
/** common source directories where css files are typically located */
|
|
18
|
+
const commonSourceDirectories = [
|
|
19
|
+
'.storybook',
|
|
20
|
+
'source',
|
|
21
|
+
'src',
|
|
22
|
+
'app',
|
|
23
|
+
'src/app',
|
|
24
|
+
'styles',
|
|
25
|
+
'assets',
|
|
26
|
+
'public',
|
|
27
|
+
'static',
|
|
28
|
+
];
|
|
29
|
+
/** common css file names prioritized during search */
|
|
30
|
+
const commonStyleFileNames = [
|
|
31
|
+
'globals.css',
|
|
32
|
+
'global.css',
|
|
33
|
+
'index.css',
|
|
34
|
+
'main.css',
|
|
35
|
+
'styles.css',
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* locates the main css file that contains the tailwind css import directive
|
|
39
|
+
* @param rootDirectory the root directory to search for css files
|
|
40
|
+
* @returns path to the css file containing `@import "tailwindcss"`
|
|
41
|
+
*/
|
|
42
|
+
export async function locateTailwindEntryFile(rootDirectory) {
|
|
43
|
+
// search in common source directories
|
|
44
|
+
for (const sourceDirectory of commonSourceDirectories) {
|
|
45
|
+
const directoryPath = resolve(rootDirectory, sourceDirectory);
|
|
46
|
+
const result = await findTailwindEntryInDirectory(directoryPath);
|
|
47
|
+
if (result) {
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// search in root directory
|
|
52
|
+
return findTailwindEntryInDirectory(rootDirectory);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* searches for tailwind css entry file in a specific directory
|
|
56
|
+
* @param directoryPath the directory path to search in
|
|
57
|
+
* @returns path to the css file containing `@import "tailwindcss"` or undefined
|
|
58
|
+
*/
|
|
59
|
+
async function findTailwindEntryInDirectory(directoryPath) {
|
|
60
|
+
try {
|
|
61
|
+
const files = await readdir(directoryPath);
|
|
62
|
+
// create a prioritized list of files to check
|
|
63
|
+
const filesToCheck = [
|
|
64
|
+
// common style files first (if they exist)
|
|
65
|
+
...commonStyleFileNames.filter((name) => files.includes(name)),
|
|
66
|
+
// then all other CSS files
|
|
67
|
+
...files.filter((file) => file.endsWith('.css') && !commonStyleFileNames.includes(file)),
|
|
68
|
+
];
|
|
69
|
+
// check each file for tailwind import
|
|
70
|
+
for (const file of filesToCheck) {
|
|
71
|
+
const filePath = resolve(directoryPath, file);
|
|
72
|
+
if (await hasTailwindImport(filePath)) {
|
|
73
|
+
return filePath;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// directory doesn't exist or can't be read
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* checks if a css file contains tailwind import directive, following local imports recursively
|
|
84
|
+
* @param path the path to the css file to check
|
|
85
|
+
* @returns true if the file contains `@import "tailwindcss"` directly or indirectly
|
|
86
|
+
*/
|
|
87
|
+
async function hasTailwindImport(path) {
|
|
88
|
+
return checkTailwindImportRecursively(path, new Set());
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* internal recursive helper for hasTailwindImport
|
|
92
|
+
* @param path the path to the css file to check
|
|
93
|
+
* @param visited set of already visited files to prevent infinite loops
|
|
94
|
+
* @returns true if the file contains `@import "tailwindcss"` directly or indirectly
|
|
95
|
+
*/
|
|
96
|
+
async function checkTailwindImportRecursively(path, visited) {
|
|
97
|
+
try {
|
|
98
|
+
if (visited.has(path)) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
visited.add(path);
|
|
102
|
+
const content = await readFile(path, 'utf-8');
|
|
103
|
+
// check for direct tailwind import
|
|
104
|
+
if (/@import\s+["']tailwindcss/.exec(content) !== null) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
// find all CSS imports and check them recursively
|
|
108
|
+
const importRegex = /@import\s+["']([^"']+)["']/g;
|
|
109
|
+
let match;
|
|
110
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
111
|
+
const importPath = match[1];
|
|
112
|
+
// skip URL imports (http/https)
|
|
113
|
+
if (/^https?:\/\//.test(importPath)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const resolvedImportPath = resolveImportPath(importPath, path);
|
|
118
|
+
// recursively check the imported file
|
|
119
|
+
if (await checkTailwindImportRecursively(resolvedImportPath, visited)) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// if import resolution fails, skip this import
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFpbHdpbmQvZW50cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRXhDOzs7OztHQUtHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FDeEIsVUFBa0IsRUFDbEIsZUFBdUI7SUFFdkIsT0FBTyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUMvQixDQUFDLENBQUMsMkJBQTJCO1lBQzNCLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLEVBQUUsVUFBVSxDQUFDO1FBQy9DLENBQUMsQ0FBQyxtREFBbUQ7WUFDbkQsYUFBYSxDQUFDLFVBQVUsRUFBRSxVQUFVLGVBQWUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUM1RCxTQUFTLEVBQ1QsRUFBRSxDQUNILENBQUM7QUFDUixDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLE1BQU0sdUJBQXVCLEdBQUc7SUFDOUIsWUFBWTtJQUNaLFFBQVE7SUFDUixLQUFLO0lBQ0wsS0FBSztJQUNMLFNBQVM7SUFDVCxRQUFRO0lBQ1IsUUFBUTtJQUNSLFFBQVE7SUFDUixRQUFRO0NBQ1QsQ0FBQztBQUVGLHNEQUFzRDtBQUN0RCxNQUFNLG9CQUFvQixHQUFHO0lBQzNCLGFBQWE7SUFDYixZQUFZO0lBQ1osV0FBVztJQUNYLFVBQVU7SUFDVixZQUFZO0NBQ2IsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHVCQUF1QixDQUMzQyxhQUFxQjtJQUVyQixzQ0FBc0M7SUFDdEMsS0FBSyxNQUFNLGVBQWUsSUFBSSx1QkFBdUIsRUFBRSxDQUFDO1FBQ3RELE1B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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tailwind/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/* v8 ignore start */
|
|
2
|
+
export { locateTailwindConfigFile } from './config.js';
|
|
3
|
+
export { locateTailwindEntryFile } from './entry.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFpbHdpbmQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEscUJBQXFCO0FBRXJCLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNwRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxTQUFTLENBQUMifQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@presetter/preset-web",
|
|
3
|
+
"version": "9.0.1",
|
|
4
|
+
"description": "An opinionated presetter preset for a web project",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"presetter",
|
|
7
|
+
"preset"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/alvis/presetter#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/alvis/presetter/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/alvis/presetter.git"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "Alvis HT Tang <alvis@hilbert.space>",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"imports": {
|
|
21
|
+
"#*": "./lib/*.js",
|
|
22
|
+
"#tailwind": "./lib/tailwind/index.js"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./lib/index.js"
|
|
26
|
+
},
|
|
27
|
+
"main": "lib/index.js",
|
|
28
|
+
"types": "lib/index.d.ts",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@presetter/types": "9.0.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@presetter/preset-essentials": "9.0.1",
|
|
34
|
+
"presetter": "9.0.1"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"autoprefixer": "^10.0.0",
|
|
38
|
+
"eslint-plugin-better-tailwindcss": "^4.0.0",
|
|
39
|
+
"globals": "^17.0.0",
|
|
40
|
+
"postcss": "^8.0.0",
|
|
41
|
+
"tailwindcss": "^4.0.0",
|
|
42
|
+
"vitest": "^4.0.0",
|
|
43
|
+
"presetter": "9.0.1"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "run build",
|
|
53
|
+
"lint": "run lint --",
|
|
54
|
+
"test": "run test --",
|
|
55
|
+
"test:coverage": "run test:coverage --",
|
|
56
|
+
"test:watch": "run test:watch --",
|
|
57
|
+
"typecheck": "run typecheck --"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/// <reference types="react-dom" />
|
|
3
|
+
|
|
4
|
+
declare module '*.avif' {
|
|
5
|
+
const src: string;
|
|
6
|
+
export default src;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module '*.bmp' {
|
|
10
|
+
const src: string;
|
|
11
|
+
export default src;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module '*.gif' {
|
|
15
|
+
const src: string;
|
|
16
|
+
export default src;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module '*.jpg' {
|
|
20
|
+
const src: string;
|
|
21
|
+
export default src;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare module '*.jpeg' {
|
|
25
|
+
const src: string;
|
|
26
|
+
export default src;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '*.png' {
|
|
30
|
+
const src: string;
|
|
31
|
+
export default src;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare module '*.webp' {
|
|
35
|
+
const src: string;
|
|
36
|
+
export default src;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare module '*.svg' {
|
|
40
|
+
import * as React from 'react';
|
|
41
|
+
|
|
42
|
+
export const ReactComponent: React.FunctionComponent<
|
|
43
|
+
React.SVGProps<SVGSVGElement> & { title?: string }
|
|
44
|
+
>;
|
|
45
|
+
|
|
46
|
+
const src: string;
|
|
47
|
+
export default src;
|
|
48
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare module '*.css' {
|
|
2
|
+
const classes: { readonly [key: string]: string };
|
|
3
|
+
export default classes;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare module '*.less' {
|
|
7
|
+
const classes: { readonly [key: string]: string };
|
|
8
|
+
export default classes;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare module '*.scss' {
|
|
12
|
+
const classes: { readonly [key: string]: string };
|
|
13
|
+
export default classes;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare module '*.sass' {
|
|
17
|
+
const classes: { readonly [key: string]: string };
|
|
18
|
+
export default classes;
|
|
19
|
+
}
|