esm-styles 0.1.12 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +336 -87
- package/dist/lib/build.js +26 -9
- package/dist/lib/utils/content.js +7 -3
- package/doc/ai-guide.md +221 -0
- package/doc/api-reference.md +262 -0
- package/doc/css-variables.md +32 -0
- package/doc/translation.md +710 -0
- package/doc/usage-guide.md +600 -0
- package/package.json +10 -3
package/doc/ai-guide.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# ESM Styles AI Reference
|
|
2
|
+
|
|
3
|
+
## Core Patterns
|
|
4
|
+
|
|
5
|
+
### Basic Style Object to CSS
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
// Input
|
|
9
|
+
{
|
|
10
|
+
button: {
|
|
11
|
+
backgroundColor: 'blue',
|
|
12
|
+
color: 'white',
|
|
13
|
+
padding: '10px 20px'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Output CSS
|
|
18
|
+
button {
|
|
19
|
+
background-color: blue;
|
|
20
|
+
color: white;
|
|
21
|
+
padding: 10px 20px;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### HTML Tags vs Class Selectors
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
// Tags are recognized directly
|
|
29
|
+
{
|
|
30
|
+
div: { margin: '0' }, // -> div { margin: 0; }
|
|
31
|
+
p: { fontSize: '16px' }, // -> p { font-size: 16px; }
|
|
32
|
+
|
|
33
|
+
// Non-HTML tags become class selectors
|
|
34
|
+
header: { display: 'flex' }, // -> .header { display: flex; }
|
|
35
|
+
card: { padding: '20px' } // -> .card { padding: 20px; }
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Nesting
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
{
|
|
43
|
+
nav: {
|
|
44
|
+
backgroundColor: '#333',
|
|
45
|
+
|
|
46
|
+
ul: {
|
|
47
|
+
display: 'flex',
|
|
48
|
+
|
|
49
|
+
li: {
|
|
50
|
+
margin: '0 10px',
|
|
51
|
+
|
|
52
|
+
a: {
|
|
53
|
+
color: 'white'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Output: Proper nested selectors
|
|
61
|
+
// nav { background-color: #333; }
|
|
62
|
+
// nav ul { display: flex; }
|
|
63
|
+
// nav ul li { margin: 0 10px; }
|
|
64
|
+
// nav ul li a { color: white; }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Underscore Conventions
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
{
|
|
71
|
+
div: {
|
|
72
|
+
// Single underscore: force class selector for tag name
|
|
73
|
+
_p: { fontWeight: 'bold' }, // -> div.p { font-weight: bold; }
|
|
74
|
+
|
|
75
|
+
// Double underscore: descendant selector
|
|
76
|
+
__icon: { width: '20px' } // -> div .icon { width: 20px; }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Pseudo-Classes and Special Selectors
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
{
|
|
85
|
+
button: {
|
|
86
|
+
':hover': { opacity: 0.9 }, // -> button:hover { opacity: 0.9; }
|
|
87
|
+
'::before': { content: '"→"' }, // -> button::before { content: "→"; }
|
|
88
|
+
'> span': { marginLeft: '5px' }, // -> button > span { margin-left: 5px; }
|
|
89
|
+
'[disabled]': { cursor: 'not-allowed' } // -> button[disabled] { cursor: not-allowed; }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Multiple Selectors
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
{
|
|
98
|
+
'h1, h2, h3': {
|
|
99
|
+
margin: '0 0 1rem'
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
'input[type="text"], input[type="email"]': {
|
|
103
|
+
padding: '8px'
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Media Queries
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
{
|
|
112
|
+
container: {
|
|
113
|
+
maxWidth: '1200px',
|
|
114
|
+
|
|
115
|
+
'@media (max-width: 768px)': {
|
|
116
|
+
maxWidth: '100%'
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
'@tablet': { // Uses named query from config
|
|
120
|
+
padding: '0 20px'
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Theme Variants
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
{
|
|
130
|
+
button: {
|
|
131
|
+
backgroundColor: 'white',
|
|
132
|
+
|
|
133
|
+
'@dark': { // Applies to :root.dark selector
|
|
134
|
+
backgroundColor: '#222'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Using CSS Variables
|
|
141
|
+
|
|
142
|
+
### CSS Variable Module Pattern
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
// Import module generated by build process
|
|
146
|
+
import $theme from './$theme.mjs'
|
|
147
|
+
|
|
148
|
+
export default {
|
|
149
|
+
button: {
|
|
150
|
+
// Use variable references - gets converted to var(--color-primary)
|
|
151
|
+
backgroundColor: $theme.color.primary,
|
|
152
|
+
color: $theme.color.textOnPrimary,
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### CSS Variable Objects
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
// All objects with `var` property are treated as CSS variable references
|
|
161
|
+
{
|
|
162
|
+
button: {
|
|
163
|
+
backgroundColor: { var: '--color-primary' }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// -> button { background-color: var(--color-primary); }
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## CLI Usage
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Build with default config
|
|
173
|
+
npx esm-styles build
|
|
174
|
+
|
|
175
|
+
# Build with custom config
|
|
176
|
+
npx esm-styles build path/to/config.js
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Config Pattern
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
// Essential config pattern
|
|
183
|
+
export default {
|
|
184
|
+
basePath: './src/styles',
|
|
185
|
+
sourcePath: 'source',
|
|
186
|
+
outputPath: 'css',
|
|
187
|
+
layers: ['base', 'components', 'utilities'],
|
|
188
|
+
mainCssFile: 'styles.css',
|
|
189
|
+
|
|
190
|
+
// Media shorthand definitions
|
|
191
|
+
mediaQueries: {
|
|
192
|
+
mobile: '(max-width: 767px)',
|
|
193
|
+
tablet: '(min-width: 768px) and (max-width: 1024px)',
|
|
194
|
+
desktop: '(min-width: 1025px)',
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
// Theme setup
|
|
198
|
+
media: {
|
|
199
|
+
theme: ['light', 'dark'],
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
mediaSelectors: {
|
|
203
|
+
theme: {
|
|
204
|
+
light: [
|
|
205
|
+
{ selector: '.light' },
|
|
206
|
+
{
|
|
207
|
+
selector: '.auto',
|
|
208
|
+
mediaQuery: 'screen and (prefers-color-scheme: light)',
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
dark: [
|
|
212
|
+
{ selector: '.dark' },
|
|
213
|
+
{
|
|
214
|
+
selector: '.auto',
|
|
215
|
+
mediaQuery: 'screen and (prefers-color-scheme: dark)',
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
}
|
|
221
|
+
```
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# ESM Styles API Reference
|
|
2
|
+
|
|
3
|
+
This document provides a comprehensive overview of the API for ESM Styles, detailing the core functionality and configuration options.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Core API](#core-api)
|
|
8
|
+
- [getCss](#getcss)
|
|
9
|
+
- [Configuration](#configuration)
|
|
10
|
+
- [Configuration Object](#configuration-object)
|
|
11
|
+
- [Media Selectors](#media-selectors)
|
|
12
|
+
- [Media Queries](#media-queries)
|
|
13
|
+
- [CLI Commands](#cli-commands)
|
|
14
|
+
- [build](#build)
|
|
15
|
+
|
|
16
|
+
## Core API
|
|
17
|
+
|
|
18
|
+
### getCss
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
function getCss(styles: CssJsObject, options?: GetCssOptions): CssString
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The main function that converts a JavaScript/TypeScript object into a CSS string.
|
|
25
|
+
|
|
26
|
+
#### Parameters
|
|
27
|
+
|
|
28
|
+
- `styles`: A JavaScript object representing CSS styles.
|
|
29
|
+
- `options`: (Optional) Configuration options for CSS generation.
|
|
30
|
+
|
|
31
|
+
#### Returns
|
|
32
|
+
|
|
33
|
+
A string containing the generated CSS.
|
|
34
|
+
|
|
35
|
+
#### Example
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { getCss } from 'esm-styles'
|
|
39
|
+
|
|
40
|
+
const styles = {
|
|
41
|
+
button: {
|
|
42
|
+
backgroundColor: '#4285f4',
|
|
43
|
+
color: 'white',
|
|
44
|
+
padding: '10px 20px',
|
|
45
|
+
|
|
46
|
+
':hover': {
|
|
47
|
+
backgroundColor: '#3367d6',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const css = getCss(styles)
|
|
53
|
+
console.log(css)
|
|
54
|
+
// Outputs: button { background-color: #4285f4; color: white; padding: 10px 20px; } button:hover { background-color: #3367d6; }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Types
|
|
58
|
+
|
|
59
|
+
#### CssJsObject
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
type CssJsObject = {
|
|
63
|
+
[key: string]:
|
|
64
|
+
| CssJsObject
|
|
65
|
+
| string
|
|
66
|
+
| number
|
|
67
|
+
| boolean
|
|
68
|
+
| null
|
|
69
|
+
| undefined
|
|
70
|
+
| { var: string }
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Represents a JavaScript object structure that can be converted to CSS.
|
|
75
|
+
|
|
76
|
+
#### GetCssOptions
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
interface GetCssOptions {
|
|
80
|
+
globalRootSelector?: string
|
|
81
|
+
mediaQueries?: Record<string, string>
|
|
82
|
+
selectorShorthands?: Record<
|
|
83
|
+
string,
|
|
84
|
+
Array<{
|
|
85
|
+
selector?: string
|
|
86
|
+
mediaQuery?: string
|
|
87
|
+
}>
|
|
88
|
+
>
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Configuration options for the CSS generation process:
|
|
93
|
+
|
|
94
|
+
- `globalRootSelector`: Root selector for variables (default: ':root')
|
|
95
|
+
- `mediaQueries`: Map of named media query shorthands
|
|
96
|
+
- `selectorShorthands`: Map of named selector shorthands
|
|
97
|
+
|
|
98
|
+
#### CssString
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
type CssString = string
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
A string containing valid CSS.
|
|
105
|
+
|
|
106
|
+
#### CssRuleObject
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface CssRuleObject {
|
|
110
|
+
[key: string]: string | number
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Represents a set of CSS property declarations.
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
### Configuration Object
|
|
119
|
+
|
|
120
|
+
The `esm-styles.config.js` file exports a configuration object with the following structure:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
interface ESMStylesConfig {
|
|
124
|
+
// Paths
|
|
125
|
+
basePath: string
|
|
126
|
+
sourcePath: string
|
|
127
|
+
outputPath: string
|
|
128
|
+
sourceFilesSuffix?: string
|
|
129
|
+
|
|
130
|
+
// Input
|
|
131
|
+
layers: string[]
|
|
132
|
+
|
|
133
|
+
// Output
|
|
134
|
+
mainCssFile: string
|
|
135
|
+
|
|
136
|
+
// Variables
|
|
137
|
+
globalVariables?: string
|
|
138
|
+
globalRootSelector?: string
|
|
139
|
+
|
|
140
|
+
// Media
|
|
141
|
+
media?: Record<string, string[]>
|
|
142
|
+
mediaSelectors?: Record<string, Record<string, Array<MediaSelectorConfig>>>
|
|
143
|
+
mediaQueries?: Record<string, string>
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Properties
|
|
148
|
+
|
|
149
|
+
| Property | Type | Description | Default |
|
|
150
|
+
| -------------------- | -------- | ----------------------------- | ------------- |
|
|
151
|
+
| `basePath` | string | Base directory for styles | - |
|
|
152
|
+
| `sourcePath` | string | Source files directory | - |
|
|
153
|
+
| `outputPath` | string | Output CSS directory | - |
|
|
154
|
+
| `sourceFilesSuffix` | string | Suffix for source files | '.styles.mjs' |
|
|
155
|
+
| `layers` | string[] | Array of layer names | - |
|
|
156
|
+
| `mainCssFile` | string | Output CSS file name | - |
|
|
157
|
+
| `globalVariables` | string | Global variables file name | - |
|
|
158
|
+
| `globalRootSelector` | string | Root selector for variables | ':root' |
|
|
159
|
+
| `media` | object | Media types and variables | - |
|
|
160
|
+
| `mediaSelectors` | object | Media selector configurations | - |
|
|
161
|
+
| `mediaQueries` | object | Named media query shorthands | - |
|
|
162
|
+
|
|
163
|
+
### Media Selectors
|
|
164
|
+
|
|
165
|
+
The `mediaSelectors` configuration defines how variables should be applied in different contexts:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
interface MediaSelectorConfig {
|
|
169
|
+
selector?: string
|
|
170
|
+
mediaQuery?: string
|
|
171
|
+
prefix?: string
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### Properties
|
|
176
|
+
|
|
177
|
+
| Property | Type | Description |
|
|
178
|
+
| ------------ | ------ | --------------------------------------- |
|
|
179
|
+
| `selector` | string | CSS selector to append to root selector |
|
|
180
|
+
| `mediaQuery` | string | Media query for conditional application |
|
|
181
|
+
| `prefix` | string | Prefix for generated CSS file names |
|
|
182
|
+
|
|
183
|
+
#### Example
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
mediaSelectors: {
|
|
187
|
+
theme: {
|
|
188
|
+
dark: [
|
|
189
|
+
// Applied when .dark class is present
|
|
190
|
+
{
|
|
191
|
+
selector: '.dark',
|
|
192
|
+
},
|
|
193
|
+
// Applied in dark mode when .auto class is present
|
|
194
|
+
{
|
|
195
|
+
selector: '.auto',
|
|
196
|
+
mediaQuery: 'screen and (prefers-color-scheme: dark)',
|
|
197
|
+
prefix: 'auto',
|
|
198
|
+
},
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Media Queries
|
|
205
|
+
|
|
206
|
+
The `mediaQueries` configuration provides shorthands for commonly used media queries:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
mediaQueries: {
|
|
210
|
+
'mobile': '(max-width: 767px)',
|
|
211
|
+
'tablet': '(min-width: 768px) and (max-width: 1024px)',
|
|
212
|
+
'desktop': '(min-width: 1025px)'
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
These shorthands can be used directly in style objects:
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
{
|
|
220
|
+
container: {
|
|
221
|
+
maxWidth: '1200px',
|
|
222
|
+
|
|
223
|
+
'@mobile': {
|
|
224
|
+
maxWidth: '100%',
|
|
225
|
+
padding: '0 16px'
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## CLI Commands
|
|
232
|
+
|
|
233
|
+
### build
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
npx esm-styles build [configPath]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Builds CSS files from JavaScript/TypeScript source files according to the configuration.
|
|
240
|
+
|
|
241
|
+
#### Parameters
|
|
242
|
+
|
|
243
|
+
- `configPath`: (Optional) Path to the configuration file. Defaults to `esm-styles.config.js` in the current directory.
|
|
244
|
+
|
|
245
|
+
#### Process
|
|
246
|
+
|
|
247
|
+
1. Loads the configuration file
|
|
248
|
+
2. Processes each layer file
|
|
249
|
+
3. Converts styles to CSS
|
|
250
|
+
4. Generates theme/device variable files
|
|
251
|
+
5. Creates supporting modules
|
|
252
|
+
6. Outputs all files to the specified directory
|
|
253
|
+
|
|
254
|
+
#### Example
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Use default config
|
|
258
|
+
npx esm-styles build
|
|
259
|
+
|
|
260
|
+
# Use custom config
|
|
261
|
+
npx esm-styles build ./configs/my-esm-styles.config.js
|
|
262
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# JS to CSS variables translation
|
|
2
|
+
|
|
3
|
+
Source object:
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
{
|
|
7
|
+
colors: {
|
|
8
|
+
paper: {
|
|
9
|
+
normal: '#212121',
|
|
10
|
+
tinted: '#323232',
|
|
11
|
+
bright: '#000000',
|
|
12
|
+
},
|
|
13
|
+
ink: {
|
|
14
|
+
normal: '#cccccc',
|
|
15
|
+
tinted: '#999999',
|
|
16
|
+
bright: { white: '#ffffff', yellow: '#ffff00' },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Output CSS:
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
--colors-paper-normal: #212121;
|
|
26
|
+
--colors-paper-tinted: #323232;
|
|
27
|
+
--colors-paper-bright: #000000;
|
|
28
|
+
--colors-ink-normal: #cccccc;
|
|
29
|
+
--colors-ink-tinted: #999999;
|
|
30
|
+
--colors-ink-bright-white: #ffffff;
|
|
31
|
+
--colors-ink-bright-yellow: #ffff00;
|
|
32
|
+
```
|