@salty-css/core 0.2.2-refactor-vite-8.5 → 0.2.2-refactor-vite-8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +535 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,535 @@
1
+ ![Salty CSS Banner](https://salty-css.dev/assets/banners/dvd.svg)
2
+
3
+ # Salty CSS — CSS-in-JS that compiles away
4
+
5
+ Salty CSS is a build-time, type-safe CSS-in-JS library. You author styles in `.css.ts` files; the compiler emits real CSS, your runtime ships zero styling logic.
6
+
7
+ [Get started](#get-started) · [API index](#api-index) · [Docs](https://salty-css.dev/docs) · [Discord](https://discord.gg/R6kr4KxMhP) · [GitHub](https://github.com/margarita-form/salty-css) · [NPM](https://www.npmjs.com/package/@salty-css/core)
8
+
9
+ ## Features
10
+
11
+ - **Build-time compilation** — no runtime style injection, no FOUC, no client bundle cost.
12
+ - **Framework support** — Next.js (App + Pages, React Server Components, Webpack & Turbopack), React + Vite, React + Webpack, Astro.
13
+ - **Type safety** — TypeScript-first authoring, generated token types, an [ESLint plugin](https://www.npmjs.com/package/@salty-css/eslint-plugin-core).
14
+ - **Design tokens & theming** — static, responsive (media-bound), and conditional (data-attribute / class-bound) variables in one place.
15
+ - **Templates** — reusable style bundles with their own variants.
16
+ - **Modifiers** — custom value transformers (`'space:3'` → `'12px'`) defined in config.
17
+ - **Variants, compound variants, anyOf variants, default variants** out of the box.
18
+
19
+ ## Get started
20
+
21
+ ```bash
22
+ npx salty-css init
23
+ ```
24
+
25
+ `init` detects your framework, installs the right packages, creates `salty.config.ts`, and wires the bundler plugin. Per-framework setup:
26
+
27
+ - **Next.js** → [salty-css.dev/docs/installation](https://salty-css.dev/docs/installation) — `withSaltyCss(nextConfig)` in `next.config.ts`. Auto-detects Webpack vs Turbopack; React Server Components supported.
28
+ - **React + Vite** → [salty-css.dev/docs/installation](https://salty-css.dev/docs/installation) — `saltyPlugin(__dirname)` in `vite.config.ts`.
29
+ - **Astro** → [salty-css.dev/docs/installation](https://salty-css.dev/docs/installation) — `saltyIntegration()` in `astro.config.mjs`.
30
+
31
+ React + Webpack (without Next.js) is also supported via `@salty-css/webpack`.
32
+
33
+ ## CLI
34
+
35
+ | Command | Alias | What it does |
36
+ | ----------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------ |
37
+ | `npx salty-css init [directory]` | — | Detect framework, install packages, create `salty.config.ts`, wire the plugin. |
38
+ | `npx salty-css generate [filePath]` | `g` | Scaffold a new Salty component file. Flags: `--name`, `--className`, `--tag`. |
39
+ | `npx salty-css build [directory]` | `b` | Compile `*.css.ts` files into `saltygen/index.css`. Not needed when the bundler plugin is running. Flags: `--watch`, `--mode`. |
40
+ | `npx salty-css update [version]` | `up` | Update all `@salty-css/*` packages. Defaults to `latest`. Flags: `--dir`, `--yes`. |
41
+ | `npx salty-css --version` | — | Print CLI version. |
42
+
43
+ Full reference: [salty-css.dev/docs/cli](https://salty-css.dev/docs/cli).
44
+
45
+ ## Good to know
46
+
47
+ 1. **File extensions matter.** `styled`, `className`, `keyframes`, and every `defineX(...)` call must live in a file ending `.css.ts`, `.css.tsx`, `.salty.ts`, `.styles.ts`, or `.styled.ts`. The compiler ignores everything else.
48
+ 2. **Extending non-Salty components is fine** — `styled(NextLink, { ... })` — as long as the wrapped component forwards `className` to a DOM element.
49
+ 3. **Async values & functions are allowed** (`base: { color: async () => 'red' }`), but heavy imports inside `*.css.ts` slow the build.
50
+ 4. **React Server Components are supported** via `@salty-css/next` — no `'use client'` needed for styled output.
51
+
52
+ ## ESLint
53
+
54
+ Salty CSS ships a small ESLint plugin and matching shareable config. Two rules, both `error` by default, both autofixable, both scoped to Salty files (`.css.ts`, `.css.tsx`, `.salty.ts`, `.styles.ts`, `.styled.ts`):
55
+
56
+ - **`@salty-css/core/must-be-exported`** — every `styled`, `className`, `keyframes`, and `defineX*` call must be exported; the compiler ignores anything else.
57
+ - **`@salty-css/core/no-variants-in-base`** — `variants` must be a sibling of `base`, not nested inside it.
58
+
59
+ ```bash
60
+ npm i -D @salty-css/eslint-plugin-core @salty-css/eslint-config-core
61
+ ```
62
+
63
+ **Flat config (ESLint 9+):**
64
+
65
+ ```js
66
+ // eslint.config.mjs
67
+ import saltyConfig from '@salty-css/eslint-config-core/flat';
68
+
69
+ export default [saltyConfig];
70
+ ```
71
+
72
+ **Legacy (`.eslintrc`):**
73
+
74
+ ```js
75
+ module.exports = { extends: ['@salty-css/eslint-config-core'] };
76
+ ```
77
+
78
+ Full reference → [salty-css.dev/docs/eslint](https://salty-css.dev/docs/eslint).
79
+
80
+ ## API index
81
+
82
+ | Symbol | Import | One-liner | Docs |
83
+ | ----------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
84
+ | [`styled`](#styled) | `@salty-css/react/styled` | React component factory with variants & extension. | [api/styled](https://salty-css.dev/docs/api/styled) |
85
+ | [`className`](#classname) | `@salty-css/react/class-name` | CSS class string with `.variant()` chaining. | [api/classname](https://salty-css.dev/docs/api/classname) |
86
+ | [Variants](#variants) | — | `variants`, `compoundVariants`, `anyOfVariants`, `defaultVariants` semantics. | [variants](https://salty-css.dev/docs/variants) |
87
+ | [Overrides](#overrides) | — | Extend components, swap element, override per-instance via `style`. | [overrides](https://salty-css.dev/docs/overrides) |
88
+ | [ESLint plugin](#eslint) | `@salty-css/eslint-config-core` | Two rules: enforce `export` and correct `variants` placement on Salty files. | [eslint](https://salty-css.dev/docs/eslint) |
89
+ | [`defineConfig`](#defineconfig) | `@salty-css/core/config` | Top-level project config. | [api/config](https://salty-css.dev/docs/api/config) |
90
+ | [`defineVariables`](#definevariables) | `@salty-css/core/factories` | Static, responsive, and conditional CSS variables (tokens). | [variables](https://salty-css.dev/docs/variables) |
91
+ | [Theming](#theming) | — | `data-theme` switcher built on conditional variables. | [theming](https://salty-css.dev/docs/theming) |
92
+ | [`defineGlobalStyles`](#defineglobalstyles) | `@salty-css/core/factories` | Global rules (`html`, `body`, etc.). | [api/define-factories](https://salty-css.dev/docs/api/define-factories) |
93
+ | [`defineMediaQuery`](#definemediaquery) | `@salty-css/core/factories` | Named, reusable media queries. | [media-queries](https://salty-css.dev/docs/media-queries) |
94
+ | [`defineTemplates`](#definetemplates) | `@salty-css/core/factories` | Reusable style bundles, optionally with variants. | [templates](https://salty-css.dev/docs/templates) |
95
+ | [`defineFont`](#definefont) | `@salty-css/core/factories` | `@font-face` (or `@import`) + CSS variable in one. | [fonts](https://salty-css.dev/docs/fonts) |
96
+ | [`defineImport`](#defineimport) | `@salty-css/core/factories` | Pull external CSS into Salty's `imports` layer. | [imports](https://salty-css.dev/docs/imports) |
97
+ | [`keyframes`](#keyframes) | `@salty-css/react/keyframes` | Typed `@keyframes` with params and initial-state injection. | [animations](https://salty-css.dev/docs/animations) |
98
+ | [`defineViewportClamp`](#defineviewportclamp) | `@salty-css/core/helpers` | Fluid `clamp()` values that scale with the viewport. | [viewport-clamp](https://salty-css.dev/docs/viewport-clamp) |
99
+ | [`color`](#color) | `@salty-css/core/helpers` | Color manipulation (`alpha`, `darken`, …). | [color-function](https://salty-css.dev/docs/color-function) |
100
+ | [Modifiers](#modifiers) | (on `defineConfig`) | Custom value transformers, e.g. `'space:3'` → `'12px'`. | [modifiers](https://salty-css.dev/docs/modifiers) |
101
+ | [`withSaltyCss`](#withsaltycss-nextjs) | `@salty-css/next` | Next.js config wrapper (Webpack + Turbopack). | [installation](https://salty-css.dev/docs/installation) |
102
+ | [`saltyPlugin` (Vite)](#saltyplugin-vite) | `@salty-css/vite` | Vite plugin. | [installation](https://salty-css.dev/docs/installation) |
103
+ | [`saltyPlugin` (Webpack)](#saltyplugin-webpack) | `@salty-css/webpack` | Webpack loader + plugin. | [installation](https://salty-css.dev/docs/installation) |
104
+ | [`saltyIntegration`](#saltyintegration-astro) | `@salty-css/astro/integration` | Astro integration. | [installation](https://salty-css.dev/docs/installation) |
105
+
106
+ ---
107
+
108
+ ## `styled`
109
+
110
+ ```ts
111
+ // components/button.css.ts
112
+ import { styled } from '@salty-css/react/styled';
113
+
114
+ export const Button = styled('button', {
115
+ className: 'btn', // optional custom class
116
+ element: 'button', // optional element override
117
+ base: {
118
+ padding: '0.6em 1.2em',
119
+ border: '1px solid currentColor',
120
+ '&:hover': { background: 'black', color: 'white' },
121
+ },
122
+ variants: {
123
+ variant: {
124
+ outlined: {},
125
+ solid: { background: 'black', color: 'white' },
126
+ },
127
+ },
128
+ compoundVariants: [
129
+ /* { variant: 'solid', size: 'lg', css: { ... } } */
130
+ ],
131
+ defaultVariants: { variant: 'outlined' },
132
+ defaultProps: { type: 'button' },
133
+ passProps: false, // pass variant props through to the rendered element
134
+ priority: undefined, // 0–8, higher wins; usually leave to auto
135
+ });
136
+ ```
137
+
138
+ ```tsx
139
+ <Button variant="solid">Save</Button>
140
+ ```
141
+
142
+ See full reference → [salty-css.dev/docs/api/styled](https://salty-css.dev/docs/api/styled).
143
+
144
+ ## `className`
145
+
146
+ Framework-agnostic class-string factory. The return value is a `string` you can drop in `className=`, plus a `.variant(name, value)` method for chaining variant classes.
147
+
148
+ ```ts
149
+ // components/card.css.ts
150
+ import { className } from '@salty-css/react/class-name';
151
+
152
+ export const card = className({
153
+ className: 'card',
154
+ base: {
155
+ padding: '1rem',
156
+ borderRadius: '8px',
157
+ },
158
+ variants: {
159
+ tone: {
160
+ neutral: { background: '#f6f6f6' },
161
+ brand: { background: '{colors.brand.main}' },
162
+ },
163
+ },
164
+ });
165
+ ```
166
+
167
+ ```tsx
168
+ <div className={`${card.variant('tone', 'brand')}`}>Hello</div>
169
+ ```
170
+
171
+ See full reference → [salty-css.dev/docs/api/classname](https://salty-css.dev/docs/api/classname).
172
+
173
+ ## Variants
174
+
175
+ `styled` and `className` share the same variant shape:
176
+
177
+ - **`variants`** — named axes (e.g. `size: { sm, md, lg }`). Each axis becomes a prop.
178
+ - **`compoundVariants`** — array; styles applied only when **all** listed axes match.
179
+ - **`anyOfVariants`** — array; styles applied when **any** listed axis matches.
180
+ - **`defaultVariants`** — values used when the prop is omitted at the call site.
181
+
182
+ ```ts
183
+ styled('a', {
184
+ base: { textDecoration: 'none' },
185
+ variants: {
186
+ size: { sm: { fontSize: 14 }, lg: { fontSize: 18 } },
187
+ underline: { true: { textDecoration: 'underline' } },
188
+ },
189
+ compoundVariants: [{ size: 'lg', underline: true, css: { textUnderlineOffset: 4 } }],
190
+ defaultVariants: { size: 'sm' },
191
+ });
192
+ ```
193
+
194
+ Boolean variants accept `true`/`false` keys; pass them as `<Link underline />` shorthand. See [salty-css.dev/docs/variants](https://salty-css.dev/docs/variants).
195
+
196
+ ## Overrides
197
+
198
+ - **Extend any component:** `styled(ExistingComponent, { ... })`. The wrapped component must accept `className`.
199
+ - **Swap the rendered element** for one instance: `<Button as="a" href="/x" />` (use `passProps` if you want variant props to reach the underlying element).
200
+ - **Per-instance style overrides:** `<Box style={{ ... }} />` and `<Box css={{ ... }} />` accept regular React `style` and Salty's `css` prop (overrides apply at the highest priority).
201
+
202
+ See [salty-css.dev/docs/overrides](https://salty-css.dev/docs/overrides) for `as`, `style`, CSS-variable overrides, and ref forwarding.
203
+
204
+ ## `defineConfig`
205
+
206
+ ```ts
207
+ // salty.config.ts
208
+ import { defineConfig } from '@salty-css/core/config';
209
+
210
+ export const config = defineConfig({
211
+ importStrategy: 'root', // 'root' | 'component'
212
+ variables: {
213
+ /* see defineVariables */
214
+ },
215
+ global: {
216
+ /* see defineGlobalStyles */
217
+ },
218
+ templates: {
219
+ /* see defineTemplates */
220
+ },
221
+ modifiers: {
222
+ /* see Modifiers */
223
+ },
224
+ reset: 'default', // 'default' | 'none' | GlobalStyles
225
+ externalModules: ['react', 'react-dom'],
226
+ strict: true, // true | 'warn' | false
227
+ defaultUnit: 'px', // px, rem, em, vh, vw, % …
228
+ });
229
+ ```
230
+
231
+ Full reference → [salty-css.dev/docs/api/config](https://salty-css.dev/docs/api/config).
232
+
233
+ ## `defineVariables`
234
+
235
+ Tokens come in three flavours — static, responsive (media-bound), conditional (class/data-attribute-bound):
236
+
237
+ ```ts
238
+ // styles/variables.css.ts
239
+ import { defineVariables } from '@salty-css/core/factories';
240
+
241
+ export default defineVariables({
242
+ colors: {
243
+ dark: '#111',
244
+ light: '#fefefe',
245
+ brand: { main: '#0070f3', highlight: '#ff4081' },
246
+ },
247
+ responsive: {
248
+ base: { fontSize: { heading: '48px', body: '16px' } },
249
+ '@largeMobileDown': { fontSize: { heading: '32px', body: '14px' } },
250
+ },
251
+ conditional: {
252
+ theme: {
253
+ dark: { backgroundColor: '{colors.dark}', textColor: '{colors.light}' },
254
+ light: { backgroundColor: '{colors.light}', textColor: '{colors.dark}' },
255
+ },
256
+ },
257
+ });
258
+ ```
259
+
260
+ Use as string references: `{colors.brand.main}`, `{fontSize.heading}`, `{theme.textColor}`.
261
+
262
+ See [salty-css.dev/docs/variables](https://salty-css.dev/docs/variables).
263
+
264
+ ## Theming
265
+
266
+ The `conditional` bucket above wires up data-attribute / class-based themes with zero providers. Toggle a `data-theme` attribute on `<html>` (or any ancestor) and conditional variables resolve to the matching branch:
267
+
268
+ ```html
269
+ <html data-theme="dark">
270
+ <!-- '{theme.textColor}' resolves to '{colors.light}' -->
271
+ </html>
272
+ ```
273
+
274
+ See the dark-mode walkthrough (with SSR flash fix) → [salty-css.dev/docs/theming](https://salty-css.dev/docs/theming).
275
+
276
+ ## `defineGlobalStyles`
277
+
278
+ ```ts
279
+ // styles/global.css.ts
280
+ import { defineGlobalStyles } from '@salty-css/core/factories';
281
+
282
+ export default defineGlobalStyles({
283
+ html: { fontFamily: 'Inter, system-ui, sans-serif' },
284
+ body: { margin: 0, background: '#fff' },
285
+ });
286
+ ```
287
+
288
+ ## `defineMediaQuery`
289
+
290
+ ```ts
291
+ // styles/media.css.ts
292
+ import { defineMediaQuery } from '@salty-css/core/factories';
293
+
294
+ export const largeMobileDown = defineMediaQuery((media) => media.maxWidth(600));
295
+ export const darkMode = defineMediaQuery((media) => media.prefersColorScheme('dark'));
296
+ ```
297
+
298
+ ```ts
299
+ styled('span', { base: { fontSize: 64, '@largeMobileDown': { fontSize: 32 } } });
300
+ ```
301
+
302
+ See [salty-css.dev/docs/media-queries](https://salty-css.dev/docs/media-queries).
303
+
304
+ ## `defineTemplates`
305
+
306
+ Reusable style bundles. Static templates pick values by dot-path; function templates take a parameter.
307
+
308
+ ```ts
309
+ // styles/templates.css.ts
310
+ import { defineTemplates } from '@salty-css/core/factories';
311
+
312
+ export default defineTemplates({
313
+ textStyle: {
314
+ heading: {
315
+ base: { fontFamily: '{fontFamily.heading}', lineHeight: 1.1 },
316
+ variants: {
317
+ weight: { regular: { fontWeight: 500 }, heavy: { fontWeight: 800 } },
318
+ },
319
+ large: { fontSize: '{fontSize.heading.large}' },
320
+ small: { fontSize: '{fontSize.heading.small}' },
321
+ },
322
+ },
323
+ card: (padding: string) => ({
324
+ padding,
325
+ borderRadius: 8,
326
+ boxShadow: '0 0 10px rgba(0,0,0,0.1)',
327
+ }),
328
+ });
329
+ ```
330
+
331
+ ```ts
332
+ styled('h1', { base: { textStyle: 'heading.large@weight=heavy', card: '20px' } });
333
+ ```
334
+
335
+ Rich-node variants, inheritance, and the `compoundVariants`/`anyOfVariants` rules: [salty-css.dev/docs/templates](https://salty-css.dev/docs/templates).
336
+
337
+ ## `defineFont`
338
+
339
+ ```ts
340
+ // styles/fonts.css.ts
341
+ import { defineFont } from '@salty-css/core/factories';
342
+
343
+ export const Inter = defineFont({
344
+ name: 'Inter',
345
+ variable: '--font-inter',
346
+ display: 'swap',
347
+ fallback: 'system-ui, sans-serif',
348
+ variants: [
349
+ { weight: 400, style: 'normal', src: '/fonts/inter-400.woff2' },
350
+ { weight: 700, style: 'normal', src: ['/fonts/inter-700.woff2', '/fonts/inter-700.ttf'] },
351
+ ],
352
+ });
353
+
354
+ // Or pull a remote stylesheet (e.g. Google Fonts) — emits @import + variable.
355
+ export const InterCdn = defineFont({
356
+ name: 'Inter',
357
+ variable: '--font-inter',
358
+ import: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap',
359
+ });
360
+ ```
361
+
362
+ `Inter.className`, `Inter.variable`, `Inter.fontFamily`, and `Inter.style` are available for explicit usage. See [salty-css.dev/docs/fonts](https://salty-css.dev/docs/fonts).
363
+
364
+ ## `defineImport`
365
+
366
+ Pull external CSS into Salty's `imports` cascade layer (which sits **before** `reset`, `global`, `templates`, and your component layers — so your styles always win).
367
+
368
+ ```ts
369
+ // styles/imports.css.ts
370
+ import { defineImport } from '@salty-css/core/factories';
371
+
372
+ export default defineImport(
373
+ './reset.css', // relative
374
+ 'modern-normalize/modern-normalize.css', // node_modules
375
+ '~normalize.css/normalize.css', // node_modules (~ form)
376
+ '/fonts/inter.css', // public/ folder
377
+ 'https://fonts.googleapis.com/css2?family=Inter', // URL
378
+ { url: './print.css', media: 'print' }, // media-conditional
379
+ { url: './p3.css', supports: 'color(display-p3 1 1 1)' }, // supports-conditional
380
+ );
381
+ ```
382
+
383
+ Layer order: `@layer imports, reset, global, templates, fonts, l0…l8;`. See [salty-css.dev/docs/imports](https://salty-css.dev/docs/imports).
384
+
385
+ ## `keyframes`
386
+
387
+ ```ts
388
+ // styles/animations.css.ts
389
+ import { keyframes } from '@salty-css/react/keyframes';
390
+
391
+ export const fadeIn = keyframes({
392
+ animationName: 'fadeIn',
393
+ appendInitialStyles: true, // injects `from`/`0%` as base styles on the component
394
+ params: { delay: '250ms', fillMode: 'forwards' },
395
+ from: { opacity: 0 },
396
+ to: { opacity: 1 },
397
+ });
398
+ ```
399
+
400
+ ```ts
401
+ styled('div', { base: { animation: fadeIn } });
402
+ ```
403
+
404
+ See [salty-css.dev/docs/animations](https://salty-css.dev/docs/animations).
405
+
406
+ ## `defineViewportClamp`
407
+
408
+ ```ts
409
+ // styles/clamp.css.ts
410
+ import { defineViewportClamp } from '@salty-css/core/helpers';
411
+
412
+ export const fhdClamp = defineViewportClamp({ screenSize: 1920 });
413
+ export const mobileClamp = defineViewportClamp({ screenSize: 640, axis: 'horizontal' });
414
+ ```
415
+
416
+ ```ts
417
+ styled('span', { base: { fontSize: fhdClamp(96), '@largeMobileDown': { fontSize: mobileClamp(48) } } });
418
+ ```
419
+
420
+ Options: `screenSize`, `axis` (`'horizontal' | 'vertical'`), `minMultiplier`, `maxMultiplier`, `minMaxUnit`. See [salty-css.dev/docs/viewport-clamp](https://salty-css.dev/docs/viewport-clamp).
421
+
422
+ ## `color`
423
+
424
+ ```ts
425
+ import { color } from '@salty-css/core/helpers';
426
+ import { styled } from '@salty-css/react/styled';
427
+
428
+ export const Tint = styled('span', {
429
+ base: { backgroundColor: color('#000').alpha(0.5) },
430
+ });
431
+ ```
432
+
433
+ Backed by the [Qix-/color](https://github.com/Qix-/color) library — `.alpha()`, `.darken()`, `.lighten()`, `.mix()`, etc. See [salty-css.dev/docs/color-function](https://salty-css.dev/docs/color-function).
434
+
435
+ ## Modifiers
436
+
437
+ Custom value transformers registered on `defineConfig`. Each modifier is a `{ pattern, transform }` pair: when Salty sees a string value matching `pattern`, it replaces it with `transform(match).value` (and optionally emits extra CSS via `transform(match).css`).
438
+
439
+ ```ts
440
+ // salty.config.ts
441
+ import { defineConfig } from '@salty-css/core/config';
442
+
443
+ export const config = defineConfig({
444
+ modifiers: {
445
+ spaceShorthand: {
446
+ pattern: /^space:(\d+)$/,
447
+ transform: (match) => {
448
+ const n = Number(match.replace('space:', ''));
449
+ return { value: `${n * 4}px` };
450
+ },
451
+ },
452
+ },
453
+ });
454
+ ```
455
+
456
+ ```ts
457
+ styled('div', { base: { padding: 'space:3' } }); // → padding: 12px
458
+ ```
459
+
460
+ See [salty-css.dev/docs/modifiers](https://salty-css.dev/docs/modifiers).
461
+
462
+ ## `withSaltyCss` (Next.js)
463
+
464
+ ```ts
465
+ // next.config.ts
466
+ import { withSaltyCss } from '@salty-css/next';
467
+
468
+ const nextConfig = {
469
+ /* your config */
470
+ };
471
+ export default withSaltyCss(nextConfig);
472
+ // Or pin a bundler: withSaltyCss(nextConfig, { bundler: 'webpack' })
473
+ ```
474
+
475
+ Options: `mode` (build mode override), `bundler` (`'auto' | 'webpack' | 'turbopack'`, defaults to auto-detect via `process.env.TURBOPACK`), `dir` (project root for Turbopack — defaults to `nextConfig.turbopack.root` or `process.cwd()`).
476
+
477
+ Next.js 14 CommonJS:
478
+
479
+ ```js
480
+ const { withSaltyCss } = require('@salty-css/next');
481
+ module.exports = withSaltyCss(nextConfig);
482
+ ```
483
+
484
+ See [salty-css.dev/docs/installation](https://salty-css.dev/docs/installation).
485
+
486
+ ## `saltyPlugin` (Vite)
487
+
488
+ ```ts
489
+ // vite.config.ts
490
+ import { defineConfig } from 'vite';
491
+ import { saltyPlugin } from '@salty-css/vite';
492
+
493
+ export default defineConfig({
494
+ plugins: [saltyPlugin(__dirname)],
495
+ });
496
+ ```
497
+
498
+ Options: `{ mode }`.
499
+
500
+ ## `saltyPlugin` (Webpack)
501
+
502
+ ```js
503
+ // webpack.config.js
504
+ const { saltyPlugin } = require('@salty-css/webpack');
505
+
506
+ module.exports = (env, argv) => {
507
+ const config = {
508
+ /* … */
509
+ };
510
+ saltyPlugin(config, __dirname);
511
+ return config;
512
+ };
513
+ ```
514
+
515
+ Signature: `saltyPlugin(config, dir, isServer?, cjs?, { mode? })`.
516
+
517
+ ## `saltyIntegration` (Astro)
518
+
519
+ ```ts
520
+ // astro.config.mjs
521
+ import { defineConfig } from 'astro/config';
522
+ import saltyIntegration from '@salty-css/astro/integration';
523
+
524
+ export default defineConfig({
525
+ integrations: [saltyIntegration()],
526
+ });
527
+ ```
528
+
529
+ Options: `srcDir` (defaults to `'src'`), `rootDir` (defaults to the Astro config root).
530
+
531
+ ---
532
+
533
+ ## Support
534
+
535
+ Help, questions, or feedback → [Join the Salty CSS Discord](https://discord.gg/R6kr4KxMhP). Bug reports → [GitHub issues](https://github.com/margarita-form/salty-css/issues).
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "bugs": {
15
15
  "url": "https://github.com/margarita-form/salty-css/issues"
16
16
  },
17
- "version": "0.2.2-refactor-vite-8.5",
17
+ "version": "0.2.2-refactor-vite-8.8",
18
18
  "type": "module",
19
19
  "scripts": {
20
20
  "build": "vite build",