@seyuna/postcss 1.0.0-canary.27 → 1.0.0-canary.29
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/CHANGELOG.md +14 -0
- package/README.md +171 -135
- package/dist/at-rules/config.d.ts +6 -0
- package/dist/at-rules/config.js +71 -0
- package/dist/at-rules/import.js +6 -11
- package/dist/at-rules/index.js +2 -0
- package/dist/config.d.ts +2 -2
- package/dist/config.js +29 -74
- package/dist/types.d.ts +0 -2
- package/package.json +1 -1
- package/src/at-rules/config.ts +78 -0
- package/src/at-rules/import.ts +6 -12
- package/src/at-rules/index.ts +2 -0
- package/src/config.ts +45 -86
- package/src/types.ts +0 -2
- package/tests/plugin.test.ts +138 -76
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.0.0-canary.29](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.28...v1.0.0-canary.29) (2026-01-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* allow mode-specific fixed color overrides in [@config](https://github.com/config) ([d41de2b](https://github.com/seyuna-corp/seyuna-postcss/commit/d41de2b4ef1f0d04ccd14584bcc150d21f9bbfcd))
|
|
7
|
+
|
|
8
|
+
# [1.0.0-canary.28](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.27...v1.0.0-canary.28) (2026-01-21)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* move configuration from JSON to in-CSS [@config](https://github.com/config) at-rule ([964eabd](https://github.com/seyuna-corp/seyuna-postcss/commit/964eabdef0b1f63d600d0d1f2171387c2932f0b2))
|
|
14
|
+
|
|
1
15
|
# [1.0.0-canary.27](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.26...v1.0.0-canary.27) (2026-01-20)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@seyuna/postcss)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
>
|
|
6
|
+
> Design once. Deploy everywhere. Light and dark, effortlessly.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Philosophy
|
|
11
11
|
|
|
12
|
-
Seyuna PostCSS is
|
|
12
|
+
Seyuna PostCSS is not just another CSS preprocessor. It's a design system compiler that embraces four core principles:
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
### 1. Design Once at 1080p, Deploy Everywhere
|
|
15
|
+
|
|
16
|
+
Traditional responsive design means designing the same component three or four times for different screen sizes. Seyuna takes a different approach: viewport-relative scaling.
|
|
15
17
|
|
|
16
18
|
```css
|
|
17
19
|
html {
|
|
@@ -19,150 +21,203 @@ html {
|
|
|
19
21
|
}
|
|
20
22
|
```
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
At 1920px viewport width, `0.833vw` equals exactly `16px`. On a 4K display, everything scales proportionally. Your 1080p design becomes a 4K design automatically. No breakpoints. No media queries. No redesigning.
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
### 2. Seamless Dark / Light Mode
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
Theme switching shouldn't require duplicating your entire stylesheet. With Seyuna, colors are defined once and adapt automatically:
|
|
27
29
|
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
+
```css
|
|
31
|
+
.button {
|
|
32
|
+
background: SeyunaStandardColor(primary);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
When the user switches from light to dark mode, every standard color updates its lightness and chroma automatically. No conditional classes. No theme-specific stylesheets.
|
|
37
|
+
|
|
38
|
+
### 3. Cleaner Codebase
|
|
39
|
+
|
|
40
|
+
CSS shouldn't be bloated with repetitive color definitions and hardcoded values. Seyuna keeps your stylesheets lean:
|
|
41
|
+
|
|
42
|
+
```css
|
|
43
|
+
/* Instead of this */
|
|
44
|
+
.card {
|
|
45
|
+
background: rgba(66, 133, 244, 0.5);
|
|
46
|
+
border: 1px solid rgba(66, 133, 244, 0.8);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Write this */
|
|
50
|
+
.card {
|
|
51
|
+
background: SeyunaAlpha(primary, 0.5);
|
|
52
|
+
border: 1px solid SeyunaAlpha(primary, 0.8);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Your color palette lives in `seyuna.json`. Your stylesheets reference it by name. Change the primary color once, and it updates everywhere.
|
|
57
|
+
|
|
58
|
+
### 4. Seamless Color Functions
|
|
59
|
+
|
|
60
|
+
Need a hover state that's slightly lighter? A disabled state that's more transparent? Seyuna provides color manipulation functions that work with your design tokens:
|
|
61
|
+
|
|
62
|
+
```css
|
|
63
|
+
.button {
|
|
64
|
+
background: SeyunaStandardColor(primary);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.button:hover {
|
|
68
|
+
background: SeyunaLighten(primary, 0.1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.button:disabled {
|
|
72
|
+
background: SeyunaAlpha(primary, 0.3);
|
|
73
|
+
}
|
|
30
74
|
```
|
|
31
75
|
|
|
76
|
+
These functions compile to pure CSS using `calc()` and CSS custom properties. No JavaScript runtime. No color processing at page load.
|
|
77
|
+
|
|
32
78
|
---
|
|
33
79
|
|
|
34
|
-
##
|
|
80
|
+
## Quick Start
|
|
81
|
+
|
|
82
|
+
### Installation
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install @seyuna/postcss postcss --save-dev
|
|
86
|
+
```
|
|
35
87
|
|
|
36
|
-
|
|
88
|
+
### PostCSS Configuration
|
|
37
89
|
|
|
38
90
|
```javascript
|
|
39
|
-
|
|
40
|
-
import
|
|
41
|
-
import postcssAdvancedVariables from 'postcss-advanced-variables';
|
|
42
|
-
import postcssPresetEnv from 'postcss-preset-env';
|
|
91
|
+
// postcss.config.js
|
|
92
|
+
import seyunaPostcss from "@seyuna/postcss";
|
|
43
93
|
|
|
44
94
|
export default {
|
|
45
95
|
plugins: [
|
|
46
96
|
seyunaPostcss({
|
|
47
|
-
|
|
48
|
-
modeAttribute: 'data-mode',
|
|
49
|
-
}),
|
|
50
|
-
postcssImport,
|
|
51
|
-
postcssAdvancedVariables,
|
|
52
|
-
postcssPresetEnv({
|
|
53
|
-
stage: 3,
|
|
54
|
-
features: {
|
|
55
|
-
'nesting-rules': true,
|
|
56
|
-
},
|
|
97
|
+
modeAttribute: "data-mode",
|
|
57
98
|
}),
|
|
58
99
|
],
|
|
59
100
|
};
|
|
60
101
|
```
|
|
61
102
|
|
|
62
|
-
|
|
103
|
+
### CSS Setup
|
|
104
|
+
|
|
105
|
+
Configure your design tokens directly in your CSS using the `@config "seyuna"` at-rule, then import the design system:
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
@config "seyuna" {
|
|
109
|
+
/* Define hues (0-360) */
|
|
110
|
+
--hue-primary: 240;
|
|
111
|
+
--hue-secondary: 30;
|
|
112
|
+
|
|
113
|
+
/* Define fixed colors (lightness chroma hue) */
|
|
114
|
+
--color-white: 1 0 0;
|
|
115
|
+
--color-black: 0 0 0;
|
|
116
|
+
|
|
117
|
+
/* Configure theme modes */
|
|
118
|
+
--light-lightness: 0.66;
|
|
119
|
+
--light-chroma: 0.26;
|
|
120
|
+
--light-background: 1 0 0;
|
|
121
|
+
--light-text: 0 0 0;
|
|
122
|
+
|
|
123
|
+
--dark-lightness: 0.66;
|
|
124
|
+
--dark-chroma: 0.26;
|
|
125
|
+
--dark-background: 0 0 0;
|
|
126
|
+
--dark-text: 1 0 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@import "seyuna";
|
|
130
|
+
|
|
131
|
+
/* Your styles here */
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `@config` rule is parsed and removed at build time. It populates:
|
|
135
|
+
|
|
136
|
+
- CSS custom properties for all your colors and hues
|
|
137
|
+
- Theme mode selectors (`[data-mode="light"]`, `[data-mode="dark"]`)
|
|
138
|
+
- System preference media queries
|
|
139
|
+
- A modern CSS reset with cascade layers
|
|
63
140
|
|
|
64
141
|
---
|
|
65
142
|
|
|
66
|
-
##
|
|
143
|
+
## Color System
|
|
67
144
|
|
|
68
|
-
Seyuna operates entirely in the OKLCH color space
|
|
145
|
+
Seyuna operates entirely in the **OKLCH color space**.
|
|
69
146
|
|
|
70
147
|
### Standard Colors
|
|
71
148
|
|
|
72
|
-
Standard colors
|
|
149
|
+
Standard colors define only a hue angle in the config and inherit theme lightness.
|
|
73
150
|
|
|
74
151
|
```css
|
|
75
|
-
|
|
76
|
-
|
|
152
|
+
@config "seyuna" {
|
|
153
|
+
--hue-primary: 240;
|
|
77
154
|
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Compiles to:
|
|
81
155
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
background: oklch(var(--lightness) var(--chroma) var(--primary-hue) / 1);
|
|
156
|
+
.badge {
|
|
157
|
+
background: SeyunaStandardColor(primary);
|
|
85
158
|
}
|
|
86
159
|
```
|
|
87
160
|
|
|
88
161
|
### Fixed Colors
|
|
89
162
|
|
|
90
|
-
Fixed colors
|
|
163
|
+
Fixed colors have explicit lightness, chroma, and hue values.
|
|
91
164
|
|
|
92
165
|
```css
|
|
93
|
-
|
|
94
|
-
|
|
166
|
+
@config "seyuna" {
|
|
167
|
+
--color-white: 1 0 0;
|
|
95
168
|
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Compiles to:
|
|
99
169
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
background: oklch(var(--white-lightness) var(--white-chroma) var(--white-hue) / 1);
|
|
170
|
+
.logo {
|
|
171
|
+
color: SeyunaFixedColor(white);
|
|
103
172
|
}
|
|
104
173
|
```
|
|
105
174
|
|
|
106
175
|
---
|
|
107
176
|
|
|
108
|
-
## Color
|
|
177
|
+
## Color Functions
|
|
109
178
|
|
|
110
|
-
|
|
179
|
+
| Function | Purpose | Example |
|
|
180
|
+
| :----------------------------- | :---------------------------------------- | :----------------------------- |
|
|
181
|
+
| `SeyunaStandardColor(name)` | Standard color with theme-aware lightness | `SeyunaStandardColor(primary)` |
|
|
182
|
+
| `SeyunaFixedColor(name)` | Fixed color with explicit values | `SeyunaFixedColor(white)` |
|
|
183
|
+
| `SeyunaAlpha(color, value)` | Adjusts opacity | `SeyunaAlpha(primary, 0.5)` |
|
|
184
|
+
| `SeyunaLighten(color, amount)` | Increases lightness | `SeyunaLighten(primary, 0.1)` |
|
|
185
|
+
| `SeyunaDarken(color, amount)` | Decreases lightness | `SeyunaDarken(primary, 0.1)` |
|
|
186
|
+
| `SeyunaContrast(color)` | Returns black or white for readability | `SeyunaContrast(surface)` |
|
|
111
187
|
|
|
112
|
-
|
|
113
|
-
|:----------------------|:-----------------------------------------|:----------------------------|
|
|
114
|
-
| `alpha(color, value)` | Adjusts opacity | `alpha(primary, 0.5)` |
|
|
115
|
-
| `lighten(color, amt)` | Increases lightness by `amt` | `lighten(primary, 0.1)` |
|
|
116
|
-
| `darken(color, amt)` | Decreases lightness by `amt` | `darken(primary, 0.1)` |
|
|
117
|
-
| `contrast(color)` | Returns black or white based on lightness| `color: contrast(surface);` |
|
|
118
|
-
|
|
119
|
-
The `contrast()` function uses a dynamic CSS calculation internally. It does not bake in a static value. If `--surface-lightness` changes at runtime, the contrast color updates with it.
|
|
188
|
+
The `SeyunaContrast()` function uses dynamic CSS calculations. If the underlying color changes at runtime, the contrast color updates automatically.
|
|
120
189
|
|
|
121
190
|
---
|
|
122
191
|
|
|
123
192
|
## Theme Switching
|
|
124
193
|
|
|
125
|
-
Seyuna supports three modes: `light`, `dark`, and `system`.
|
|
194
|
+
Seyuna supports three modes: `light`, `dark`, and `system`. Control the active mode via the `data-mode` attribute:
|
|
126
195
|
|
|
127
196
|
```html
|
|
128
|
-
<html data-mode="system">
|
|
197
|
+
<html data-mode="system"></html>
|
|
129
198
|
```
|
|
130
199
|
|
|
131
|
-
|
|
200
|
+
### In-CSS Theme Overrides
|
|
132
201
|
|
|
133
|
-
|
|
134
|
-
[data-mode="light"] {
|
|
135
|
-
--lightness: 0.66;
|
|
136
|
-
--chroma: 0.26;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@media (prefers-color-scheme: dark) {
|
|
140
|
-
[data-mode="system"] {
|
|
141
|
-
--lightness: 0.66;
|
|
142
|
-
--chroma: 0.26;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### In-CSS Overrides
|
|
148
|
-
|
|
149
|
-
Need a component to look different in dark mode? Use the `@dark` and `@light` at-rules directly in your stylesheet:
|
|
202
|
+
Need a component to look different in dark mode? Use the `@dark` and `@light` at-rules:
|
|
150
203
|
|
|
151
204
|
```css
|
|
152
205
|
.card {
|
|
153
|
-
background:
|
|
206
|
+
background: SeyunaFixedColor(white);
|
|
154
207
|
|
|
155
208
|
@dark {
|
|
156
|
-
background:
|
|
209
|
+
background: SeyunaFixedColor(black);
|
|
157
210
|
}
|
|
158
211
|
}
|
|
159
212
|
```
|
|
160
213
|
|
|
214
|
+
Compiles to rules that target both explicit mode selection and system preferences.
|
|
215
|
+
|
|
161
216
|
---
|
|
162
217
|
|
|
163
218
|
## Container Queries
|
|
164
219
|
|
|
165
|
-
Seyuna
|
|
220
|
+
Seyuna includes shorthand breakpoints that compile to CSS Container Queries:
|
|
166
221
|
|
|
167
222
|
```css
|
|
168
223
|
.grid {
|
|
@@ -179,95 +234,76 @@ Seyuna ships with shorthand breakpoints that compile to CSS Container Queries in
|
|
|
179
234
|
}
|
|
180
235
|
```
|
|
181
236
|
|
|
182
|
-
Available breakpoints:
|
|
183
|
-
|
|
184
237
|
| At-Rule | Container Width |
|
|
185
|
-
|
|
238
|
+
| :------ | :-------------- |
|
|
186
239
|
| `@xs` | 20rem |
|
|
187
|
-
| `@sm` |
|
|
240
|
+
| `@sm` | 40rem |
|
|
188
241
|
| `@md` | 48rem |
|
|
189
|
-
| `@lg` |
|
|
242
|
+
| `@lg` | 64rem |
|
|
190
243
|
| `@xl` | 80rem |
|
|
191
244
|
| `@2xl` | 96rem |
|
|
192
245
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
## Configuration Reference
|
|
196
|
-
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"ui": {
|
|
200
|
-
"theme": {
|
|
201
|
-
"hues": {
|
|
202
|
-
"primary": 240,
|
|
203
|
-
"secondary": 30,
|
|
204
|
-
"accent": 150
|
|
205
|
-
},
|
|
206
|
-
"colors": {
|
|
207
|
-
"white": { "lightness": 1, "chroma": 0, "hue": 0 },
|
|
208
|
-
"black": { "lightness": 0, "chroma": 0, "hue": 0 }
|
|
209
|
-
},
|
|
210
|
-
"light": {
|
|
211
|
-
"lightness": 0.66,
|
|
212
|
-
"chroma": 0.26,
|
|
213
|
-
"background": { "lightness": 1, "chroma": 0, "hue": 0 },
|
|
214
|
-
"text": { "lightness": 0, "chroma": 0, "hue": 0 }
|
|
215
|
-
},
|
|
216
|
-
"dark": {
|
|
217
|
-
"lightness": 0.66,
|
|
218
|
-
"chroma": 0.26,
|
|
219
|
-
"background": { "lightness": 0, "chroma": 0, "hue": 0 },
|
|
220
|
-
"text": { "lightness": 1, "chroma": 0, "hue": 0 }
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
"mode": "system",
|
|
224
|
-
"output_dir": "src/styles"
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
`hues` defines standard colors. Only the hue angle is specified because lightness and chroma come from the theme mode.
|
|
230
|
-
|
|
231
|
-
`colors` defines fixed colors with explicit lightness, chroma, and hue values.
|
|
232
|
-
|
|
233
|
-
`light` and `dark` set the global lightness and chroma for standard colors, plus any mode-specific fixed colors like background and text.
|
|
246
|
+
Components respond to their container size, not the viewport. True component-based responsive design.
|
|
234
247
|
|
|
235
248
|
---
|
|
236
249
|
|
|
237
250
|
## Palette Iteration
|
|
238
251
|
|
|
239
|
-
Generate utility classes by iterating over your
|
|
252
|
+
Generate utility classes by iterating over your color configuration:
|
|
240
253
|
|
|
241
254
|
```css
|
|
242
255
|
@each-standard-color {
|
|
243
256
|
.bg-{name} {
|
|
244
|
-
background-color:
|
|
257
|
+
background-color: SeyunaStandardColor({name});
|
|
245
258
|
}
|
|
246
259
|
}
|
|
247
260
|
|
|
248
261
|
@each-fixed-color {
|
|
249
262
|
.text-{name} {
|
|
250
|
-
color:
|
|
263
|
+
color: SeyunaFixedColor({name});
|
|
251
264
|
}
|
|
252
265
|
}
|
|
253
266
|
```
|
|
254
267
|
|
|
255
268
|
---
|
|
256
269
|
|
|
257
|
-
##
|
|
270
|
+
## Configuration Properties
|
|
271
|
+
|
|
272
|
+
Within the `@config "seyuna"` block, you can use the following property prefixes:
|
|
273
|
+
|
|
274
|
+
| Prefix | Description | Example |
|
|
275
|
+
| :---------- | :--------------------------------------------------------------- | :---------------------------- |
|
|
276
|
+
| `--hue-*` | Defines a hue angle for a standard color | `--hue-primary: 240;` |
|
|
277
|
+
| `--color-*` | Defines a fixed color (L C H) | `--color-brand: 0.6 0.2 120;` |
|
|
278
|
+
| `--light-*` | Configures the light theme (lightness, chroma, background, text) | `--light-lightness: 0.8;` |
|
|
279
|
+
| `--dark-*` | Configures the dark theme | `--dark-background: 0 0 0;` |
|
|
280
|
+
|
|
281
|
+
For colors and background/text, use a space-separated list of values: `lightness chroma hue`.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Plugin Options
|
|
258
286
|
|
|
259
|
-
|
|
287
|
+
```javascript
|
|
288
|
+
seyunaPostcss({
|
|
289
|
+
configPath: "seyuna.json", // Path to your config file
|
|
290
|
+
modeAttribute: "data-mode", // Attribute for theme switching
|
|
291
|
+
strict: false, // Throw errors for missing colors
|
|
292
|
+
});
|
|
293
|
+
```
|
|
260
294
|
|
|
261
|
-
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Accessing Config Values
|
|
298
|
+
|
|
299
|
+
Use `SeyunaTheme()` to access any value from your configuration:
|
|
262
300
|
|
|
263
301
|
```css
|
|
264
|
-
|
|
265
|
-
|
|
302
|
+
.container {
|
|
303
|
+
max-width: SeyunaTheme(ui.theme.breakpoints.lg);
|
|
266
304
|
}
|
|
267
305
|
```
|
|
268
306
|
|
|
269
|
-
At 1920px, the computed font size is 16px. At 2560px, it becomes roughly 21px. Every `rem` value in your stylesheet scales accordingly. Design at 1080p. Ship at any resolution.
|
|
270
|
-
|
|
271
307
|
---
|
|
272
308
|
|
|
273
309
|
## License
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler for @config "seyuna"
|
|
3
|
+
* Parses the configuration defined directly in CSS.
|
|
4
|
+
*/
|
|
5
|
+
export function handleConfig(atRule, context) {
|
|
6
|
+
const params = atRule.params.replace(/['"]/g, "");
|
|
7
|
+
if (params === "seyuna") {
|
|
8
|
+
const { config } = context;
|
|
9
|
+
if (!config.ui) {
|
|
10
|
+
config.ui = {
|
|
11
|
+
theme: {
|
|
12
|
+
hues: {},
|
|
13
|
+
colors: {},
|
|
14
|
+
light: {
|
|
15
|
+
chroma: 0,
|
|
16
|
+
lightness: 0,
|
|
17
|
+
background: { lightness: 0, chroma: 0, hue: 0 },
|
|
18
|
+
text: { lightness: 0, chroma: 0, hue: 0 },
|
|
19
|
+
colors: {},
|
|
20
|
+
},
|
|
21
|
+
dark: {
|
|
22
|
+
chroma: 0,
|
|
23
|
+
lightness: 0,
|
|
24
|
+
background: { lightness: 0, chroma: 0, hue: 0 },
|
|
25
|
+
text: { lightness: 0, chroma: 0, hue: 0 },
|
|
26
|
+
colors: {},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const theme = config.ui.theme;
|
|
32
|
+
atRule.walkDecls((decl) => {
|
|
33
|
+
const prop = decl.prop;
|
|
34
|
+
const value = decl.value;
|
|
35
|
+
// Hues: --hue-alpha: 0;
|
|
36
|
+
if (prop.startsWith("--hue-")) {
|
|
37
|
+
const name = prop.replace("--hue-", "");
|
|
38
|
+
theme.hues[name] = parseFloat(value);
|
|
39
|
+
}
|
|
40
|
+
// Fixed Colors: --color-primary: 0.66 0.26 240;
|
|
41
|
+
else if (prop.startsWith("--color-")) {
|
|
42
|
+
const name = prop.replace("--color-", "");
|
|
43
|
+
const [l, c, h] = value.split(/\s+/).map(parseFloat);
|
|
44
|
+
theme.colors[name] = { lightness: l, chroma: c, hue: h };
|
|
45
|
+
}
|
|
46
|
+
// Theme Palettes: --light-lightness: 0.66;
|
|
47
|
+
else if (prop.startsWith("--light-") || prop.startsWith("--dark-")) {
|
|
48
|
+
const isLight = prop.startsWith("--light-");
|
|
49
|
+
const palette = isLight ? theme.light : theme.dark;
|
|
50
|
+
const key = prop.replace(isLight ? "--light-" : "--dark-", "");
|
|
51
|
+
if (key === "lightness")
|
|
52
|
+
palette.lightness = parseFloat(value);
|
|
53
|
+
else if (key === "chroma")
|
|
54
|
+
palette.chroma = parseFloat(value);
|
|
55
|
+
else if (key === "background" || key === "text") {
|
|
56
|
+
const [l, c, h] = value.split(/\s+/).map(parseFloat);
|
|
57
|
+
palette[key] = { lightness: l, chroma: c, hue: h };
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Custom colors in palette: --light-surface: 1 0 0;
|
|
61
|
+
// Also supports overrides like --light-color-primary: 0.8 0.1 240;
|
|
62
|
+
const cleanKey = key.replace(/^color-/, "");
|
|
63
|
+
const [l, c, h] = value.split(/\s+/).map(parseFloat);
|
|
64
|
+
palette.colors[cleanKey] = { lightness: l, chroma: c, hue: h };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// Remove the at-rule from CSS output
|
|
69
|
+
atRule.remove();
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/at-rules/import.js
CHANGED
|
@@ -7,9 +7,6 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
import postcss from "postcss";
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
|
-
const STANDARD_HUES = [
|
|
11
|
-
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho', 'sigma', 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega'
|
|
12
|
-
];
|
|
13
10
|
/**
|
|
14
11
|
* Handler for @import "seyuna"
|
|
15
12
|
* Injects the core Seyuna Design System variables and base styles
|
|
@@ -48,14 +45,12 @@ export function handleImport(atRule, context) {
|
|
|
48
45
|
}
|
|
49
46
|
// 2. Global Hues and Base Colors (:root)
|
|
50
47
|
const rootRule = new Rule({ selector: ":root", source: atRule.source });
|
|
51
|
-
// Process all hues from config
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
rootRule.append(new Declaration({ prop: `--${name}-hue`, value: String(value) }));
|
|
58
|
-
});
|
|
48
|
+
// Process all hues from config
|
|
49
|
+
if (theme.hues) {
|
|
50
|
+
for (const [name, value] of Object.entries(theme.hues)) {
|
|
51
|
+
rootRule.append(new Declaration({ prop: `--${name}-hue`, value: String(value) }));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
59
54
|
// Add shared colors from theme.colors
|
|
60
55
|
if (theme.colors) {
|
|
61
56
|
for (const [name, color] of Object.entries(theme.colors)) {
|
package/dist/at-rules/index.js
CHANGED
|
@@ -3,8 +3,10 @@ import { eachStandardColor, eachFixedColor } from "./color.js";
|
|
|
3
3
|
import container from "./container.js";
|
|
4
4
|
import { light, dark } from "./color-scheme.js";
|
|
5
5
|
import { handleImport } from "./import.js";
|
|
6
|
+
import { handleConfig } from "./config.js";
|
|
6
7
|
// Ordered array ensures execution order
|
|
7
8
|
export const atRuleHandlers = [
|
|
9
|
+
{ name: "config", handler: handleConfig },
|
|
8
10
|
{ name: "import", handler: handleImport },
|
|
9
11
|
{ name: "each-standard-color", handler: eachStandardColor },
|
|
10
12
|
{ name: "each-fixed-color", handler: eachFixedColor },
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SeyunaConfig, PluginOptions } from
|
|
2
|
-
export type { PluginOptions, PluginContext, FunctionMap } from
|
|
1
|
+
import { SeyunaConfig, PluginOptions } from "./types.js";
|
|
2
|
+
export type { PluginOptions, PluginContext, FunctionMap } from "./types.js";
|
|
3
3
|
export declare function loadConfig(options?: PluginOptions): {
|
|
4
4
|
config: SeyunaConfig;
|
|
5
5
|
options: Required<PluginOptions>;
|