@umoa/saascfm-css 0.1.1 → 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 CHANGED
@@ -8,12 +8,12 @@ Vite plugin that scans your source and generates only the utility classes you us
8
8
  npm i -D @umoa/saascfm-css
9
9
  ```
10
10
 
11
- Works with TypeScript or plain JavaScript. Use `vite.config.js`, the `js` template and `main.js` if you are not on TypeScript. The package ships ESM and CommonJS, so it loads whether or not your `package.json` has `"type": "module"`.
11
+ Works with TypeScript or plain JavaScript. If you are not on TypeScript, use `vite.config.js`, the `js` template (import it with `.js`) and `main.js`, and set `"type": "module"` in your `package.json`. The package ships ESM and CommonJS, so it loads whether or not your `package.json` has `"type": "module"`.
12
12
 
13
13
  ```js
14
14
  // vite.config.js (or .ts)
15
15
  import cssModule from '@umoa/saascfm-css'
16
- import * as colors from './src/saascfm-css/_component.tokens'
16
+ import * as colors from './src/saascfm-css/_component.tokens.ts'
17
17
 
18
18
  export default defineConfig({
19
19
  plugins: [cssModule({ colorsModule: colors })],
@@ -36,6 +36,7 @@ TypeScript only: add `"types": ["@umoa/saascfm-css/client"]` to `tsconfig.json`.
36
36
  | `spacing` `layout` `typography` `cursor` `border` | `true` | turn a module off with `false` |
37
37
  | `colorsModule` | none | your `PRIMITIVES` and `TOKENS` |
38
38
  | `primitiveClasses` | `true` | `false` removes the `blue-500` / `bg-blue-500` classes |
39
+ | `primitiveVars` | `false` | `true` also writes every primitive as a CSS variable on `:root` (`--brand-500`), so `var(--brand-500)` works in your own CSS |
39
40
  | `important` | `false` | `true` adds `!important` to every generated declaration |
40
41
  | `exclude` | `[".colors.", ".tokens.", "primitives."]` | file paths containing these are not scanned, so your color definitions do not generate every class |
41
42
 
@@ -64,10 +65,10 @@ src/saascfm-css/
64
65
  RULES.md how the folder works, adding tokens, migrating
65
66
  ```
66
67
 
67
- Then point the plugin at it:
68
+ Then point the plugin at it. Use the file extension (`.ts` or `.js`); Vite 8's native config loader requires it. In TypeScript projects, `allowImportingTsExtensions` must be enabled in the `tsconfig` that covers `vite.config.ts`.
68
69
 
69
70
  ```ts
70
- import * as colors from './src/saascfm-css/_component.tokens'
71
+ import * as colors from './src/saascfm-css/_component.tokens.ts'
71
72
 
72
73
  plugins: [cssModule({ colorsModule: colors })]
73
74
  ```
@@ -88,6 +89,7 @@ export const TOKENS = { 'text-brand': 'brand-500', 'bg-card': 'white' }
88
89
  - `PRIMITIVES`: name → color. Each generates `name` (color), `bg-name`, `border-name`. `rgba`/`hsla` values generate the color class only.
89
90
  - `TOKENS`: name → primitive name, or any CSS color. Each becomes `--name` on `:root`.
90
91
  - Token names are yours. The first word decides the class: `text-*` → `color`, `bg-*` → `background-color`, `border-*` → `border-color`. Any other prefix (`nav-*`, `tabb-*`, `shadow-*`) is a CSS var only.
92
+ - Primitives are classes only by default. Set `primitiveVars: true` to also get a variable for each one (`--brand-500`). You do not need to spread `PRIMITIVES` into `TOKENS` for this. A token with the same name overrides the primitive's variable.
91
93
  - Unknown primitive names print a warning and are skipped.
92
94
  - `hl`, `hl-muted`, `vl` read `--border-default` / `--border-muted`, falling back to `currentColor`.
93
95
 
package/dist/index.cjs CHANGED
@@ -369,11 +369,10 @@ function cssModule(options = {}) {
369
369
  const primitives = colorsModule["PRIMITIVES"];
370
370
  const useColor = !!(tokens || primitives);
371
371
  if (useColor) {
372
- if (tokens) {
373
- const resolved = resolveTokens(tokens, primitives ?? {});
374
- COLOR_ROOT_VARS = generateRootVars(resolved);
375
- COLOR_RULES = buildColorUtilityRules(resolved);
376
- }
372
+ const resolved = tokens ? resolveTokens(tokens, primitives ?? {}) : {};
373
+ const rootVars = { ...options.primitiveVars && primitives ? primitives : {}, ...resolved };
374
+ if (Object.keys(rootVars).length) COLOR_ROOT_VARS = generateRootVars(rootVars);
375
+ COLOR_RULES = buildColorUtilityRules(resolved);
377
376
  if (primitives && options.primitiveClasses !== false) {
378
377
  PRIMITIVE_COLOR_RULES = buildPrimitiveRules(primitives);
379
378
  }
package/dist/index.d.cts CHANGED
@@ -10,6 +10,7 @@ interface CssModuleOptions {
10
10
  border?: boolean;
11
11
  colorsModule?: Record<string, unknown>;
12
12
  primitiveClasses?: boolean;
13
+ primitiveVars?: boolean;
13
14
  exclude?: string[];
14
15
  important?: boolean;
15
16
  }
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ interface CssModuleOptions {
10
10
  border?: boolean;
11
11
  colorsModule?: Record<string, unknown>;
12
12
  primitiveClasses?: boolean;
13
+ primitiveVars?: boolean;
13
14
  exclude?: string[];
14
15
  important?: boolean;
15
16
  }
package/dist/index.js CHANGED
@@ -335,11 +335,10 @@ function cssModule(options = {}) {
335
335
  const primitives = colorsModule["PRIMITIVES"];
336
336
  const useColor = !!(tokens || primitives);
337
337
  if (useColor) {
338
- if (tokens) {
339
- const resolved = resolveTokens(tokens, primitives ?? {});
340
- COLOR_ROOT_VARS = generateRootVars(resolved);
341
- COLOR_RULES = buildColorUtilityRules(resolved);
342
- }
338
+ const resolved = tokens ? resolveTokens(tokens, primitives ?? {}) : {};
339
+ const rootVars = { ...options.primitiveVars && primitives ? primitives : {}, ...resolved };
340
+ if (Object.keys(rootVars).length) COLOR_ROOT_VARS = generateRootVars(rootVars);
341
+ COLOR_RULES = buildColorUtilityRules(resolved);
343
342
  if (primitives && options.primitiveClasses !== false) {
344
343
  PRIMITIVE_COLOR_RULES = buildPrimitiveRules(primitives);
345
344
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umoa/saascfm-css",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "SaaSCFM scan-and-generate utility CSS for Vite: w-54, mt-12, g-8, text-primary.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -19,7 +19,7 @@ The folder belongs to your app. The plugin never imports it by path; you pass `_
19
19
 
20
20
  ```ts
21
21
  import cssModule from '@umoa/saascfm-css'
22
- import * as colors from './src/saascfm-css/_component.tokens'
22
+ import * as colors from './src/saascfm-css/_component.tokens.js'
23
23
 
24
24
  plugins: [cssModule({ colorsModule: colors })]
25
25
  ```
@@ -72,6 +72,8 @@ Each token becomes a CSS variable on `:root`. The first word of the name decides
72
72
  </style>
73
73
  ```
74
74
 
75
+ Primitives are classes only. To also get a CSS variable for every primitive (`var(--brand-500)`), set `primitiveVars: true` in the plugin options. No change to the token files is needed.
76
+
75
77
  A token value can be a primitive (`P['neutral-900']`), a primitive name as a string (`'neutral-900'`), or any CSS color or value (`'#fff'`, `'rgba(0,0,0,.4)'`, `'56px'`). A string that looks like a primitive name but doesn't exist prints a warning and is skipped.
76
78
 
77
79
  ### When to use which
@@ -89,7 +91,7 @@ A token value can be a primitive (`P['neutral-900']`), a primitive name as a str
89
91
  ## Adding a token file
90
92
 
91
93
  1. Create `tokens/my-feature.tokens.js`
92
- 2. `import { PRIMITIVES as P } from '../primitives'`
94
+ 2. `import { PRIMITIVES as P } from '../primitives.js'`
93
95
  3. `export const MY_FEATURE_TOKENS = { 'bg-banner': P['brand-50'] }`
94
96
  4. Import it in `_component.tokens.js` and spread it into `TOKENS`
95
97
 
@@ -1,9 +1,9 @@
1
- import { NAVIGATION_TOKENS } from './tokens/navigation.tokens'
2
- import { STATUS_TOKENS } from './tokens/status.tokens'
3
- import { SURFACE_TOKENS } from './tokens/surface.tokens'
4
- import { BORDER_TOKENS } from './tokens/border.tokens'
1
+ import { NAVIGATION_TOKENS } from './tokens/navigation.tokens.js'
2
+ import { STATUS_TOKENS } from './tokens/status.tokens.js'
3
+ import { SURFACE_TOKENS } from './tokens/surface.tokens.js'
4
+ import { BORDER_TOKENS } from './tokens/border.tokens.js'
5
5
 
6
- import { PRIMITIVES } from './primitives'
6
+ import { PRIMITIVES } from './primitives.js'
7
7
 
8
8
  export const TOKENS = {
9
9
  ...NAVIGATION_TOKENS,
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.js'
2
2
 
3
3
  export const BORDER_TOKENS = {
4
4
  'border-default': P['neutral-200'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.js'
2
2
 
3
3
  export const NAVIGATION_TOKENS = {
4
4
  'nav-bg': P['neutral-50'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.js'
2
2
 
3
3
  export const STATUS_TOKENS = {
4
4
  'text-status-error': P['red-500'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.js'
2
2
 
3
3
  export const SURFACE_TOKENS = {
4
4
  'text-primary': P['neutral-900'],
@@ -19,7 +19,7 @@ The folder belongs to your app. The plugin never imports it by path; you pass `_
19
19
 
20
20
  ```ts
21
21
  import cssModule from '@umoa/saascfm-css'
22
- import * as colors from './src/saascfm-css/_component.tokens'
22
+ import * as colors from './src/saascfm-css/_component.tokens.ts'
23
23
 
24
24
  plugins: [cssModule({ colorsModule: colors })]
25
25
  ```
@@ -72,6 +72,8 @@ Each token becomes a CSS variable on `:root`. The first word of the name decides
72
72
  </style>
73
73
  ```
74
74
 
75
+ Primitives are classes only. To also get a CSS variable for every primitive (`var(--brand-500)`), set `primitiveVars: true` in the plugin options. No change to the token files is needed.
76
+
75
77
  A token value can be a primitive (`P['neutral-900']`), a primitive name as a string (`'neutral-900'`), or any CSS color or value (`'#fff'`, `'rgba(0,0,0,.4)'`, `'56px'`). A string that looks like a primitive name but doesn't exist prints a warning and is skipped.
76
78
 
77
79
  ### When to use which
@@ -89,7 +91,7 @@ A token value can be a primitive (`P['neutral-900']`), a primitive name as a str
89
91
  ## Adding a token file
90
92
 
91
93
  1. Create `tokens/my-feature.tokens.ts`
92
- 2. `import { PRIMITIVES as P } from '../primitives'`
94
+ 2. `import { PRIMITIVES as P } from '../primitives.ts'`
93
95
  3. `export const MY_FEATURE_TOKENS = { 'bg-banner': P['brand-50'] }`
94
96
  4. Import it in `_component.tokens.ts` and spread it into `TOKENS`
95
97
 
@@ -1,9 +1,9 @@
1
- import { NAVIGATION_TOKENS } from './tokens/navigation.tokens'
2
- import { STATUS_TOKENS } from './tokens/status.tokens'
3
- import { SURFACE_TOKENS } from './tokens/surface.tokens'
4
- import { BORDER_TOKENS } from './tokens/border.tokens'
1
+ import { NAVIGATION_TOKENS } from './tokens/navigation.tokens.ts'
2
+ import { STATUS_TOKENS } from './tokens/status.tokens.ts'
3
+ import { SURFACE_TOKENS } from './tokens/surface.tokens.ts'
4
+ import { BORDER_TOKENS } from './tokens/border.tokens.ts'
5
5
 
6
- import { PRIMITIVES } from './primitives'
6
+ import { PRIMITIVES } from './primitives.ts'
7
7
 
8
8
  export const TOKENS = {
9
9
  ...NAVIGATION_TOKENS,
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.ts'
2
2
 
3
3
  export const BORDER_TOKENS = {
4
4
  'border-default': P['neutral-200'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.ts'
2
2
 
3
3
  export const NAVIGATION_TOKENS = {
4
4
  'nav-bg': P['neutral-50'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.ts'
2
2
 
3
3
  export const STATUS_TOKENS = {
4
4
  'text-status-error': P['red-500'],
@@ -1,4 +1,4 @@
1
- import { PRIMITIVES as P } from '../primitives'
1
+ import { PRIMITIVES as P } from '../primitives.ts'
2
2
 
3
3
  export const SURFACE_TOKENS = {
4
4
  'text-primary': P['neutral-900'],