oklchtohex 0.7.1 → 0.7.3

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
@@ -4,10 +4,12 @@
4
4
  [![license](https://img.shields.io/npm/l/oklchtohex.svg)](https://www.npmjs.com/package/oklchtohex)
5
5
  [![npm downloads](https://img.shields.io/npm/dm/oklchtohex.svg)](https://www.npmjs.com/package/oklchtohex)
6
6
 
7
- Tailwind v4 outputs many colors as `oklch(...)`.
8
- That is great for color quality, but inconvenient when teams want HEX in generated CSS (QA, clients, design handoff).
7
+ `oklchtohex` converts `oklch(...)` color values to HEX in emitted CSS.
9
8
 
10
- `oklchtohex` converts those values to HEX automatically.
9
+ It provides:
10
+ - A Vite plugin (`oklchtohex/vite`)
11
+ - A Next.js webpack wrapper (`oklchtohex/next`)
12
+ - Direct converter utilities (`oklchtohex` or `oklchtohex/converter`)
11
13
 
12
14
  ## Install
13
15
 
@@ -24,78 +26,78 @@ import { defineConfig } from "vite";
24
26
  import { oklchToHexVitePlugin } from "oklchtohex/vite";
25
27
 
26
28
  export default defineConfig({
27
- plugins: [
28
- // ...existing plugins
29
- oklchToHexVitePlugin()
30
- ]
29
+ plugins: [oklchToHexVitePlugin()]
31
30
  });
32
31
  ```
33
32
 
34
- No command changes needed. Your normal `vite dev` and `vite build` continue to work.
35
-
36
- ### Next.js
33
+ ### Next.js (CJS)
37
34
 
38
35
  ```js
39
36
  const { withOklchToHexNext } = require("oklchtohex/next");
40
37
 
41
- module.exports = withOklchToHexNext(
42
- {
43
- // your existing Next config
44
- },
45
- {
46
- gamut: "clip"
47
- }
48
- );
38
+ module.exports = withOklchToHexNext({
39
+ // your next config
40
+ });
49
41
  ```
50
42
 
51
- For ESM `next.config.mjs`:
43
+ ### Next.js (ESM)
52
44
 
53
45
  ```js
54
46
  import { withOklchToHexNext } from "oklchtohex/next";
55
47
 
56
- export default withOklchToHexNext(
57
- {
58
- // your existing Next config
59
- },
60
- {
61
- gamut: "clip"
62
- }
63
- );
48
+ export default withOklchToHexNext({
49
+ // your next config
50
+ });
64
51
  ```
65
52
 
66
- No command changes needed. Keep `next dev`, `next build`, `next start`.
67
-
68
- ## Common Options
53
+ ## JavaScript API
69
54
 
70
55
  ```js
71
- {
72
- gamut: "clip", // default, closest practical output
73
- includeAlpha: "auto", // include alpha only when needed
74
- uppercase: false,
75
- onError: "preserve"
76
- }
56
+ import {
57
+ parseOklch,
58
+ oklchToHex,
59
+ replaceOklchInText,
60
+ convertTailwindCssToHex
61
+ } from "oklchtohex";
62
+
63
+ parseOklch("oklch(50% 0 0 / 60%)");
64
+ // => { l: 0.5, c: 0, h: 0, alpha: 0.6 }
65
+
66
+ oklchToHex("oklch(0 0 0)");
67
+ // => #000000
68
+
69
+ replaceOklchInText(".btn{color:oklch(0 0 0 / 50%)}");
70
+ // => .btn{color:#00000080}
71
+
72
+ convertTailwindCssToHex(":root{--x:oklch(1 0 0)}");
73
+ // => :root{--x:#ffffff}
77
74
  ```
78
75
 
79
- ## What It Handles
76
+ Use `oklchtohex/converter` if you only want converter functions.
80
77
 
81
- - `oklch(...)` -> HEX
82
- - Tailwind default palette vars (`--color-red-500`, etc.)
83
- - Slash opacity utilities like `border-red-500/30`
84
- - Custom theme color utilities like `border-aurora/40` (when emitted via CSS variables)
78
+ ## Options
85
79
 
86
- ## Notes
80
+ These options are accepted by converter functions and plugin integrations unless marked otherwise.
87
81
 
88
- - DevTools `Styles` shows what your source CSS contains (HEX after conversion).
89
- - DevTools `Computed` may still normalize to `rgb(...)` in some browsers.
90
- - Node.js `>=18` is required.
82
+ | Option | Type | Default | Notes |
83
+ | --- | --- | --- | --- |
84
+ | `gamut` | `"clip" \| "fit"` | `"clip"` | `"clip"` clamps channels, `"fit"` reduces chroma to fit sRGB. |
85
+ | `includeAlpha` | `"auto" \| "always" \| "never" \| boolean` | `"auto"` | `"auto"` adds alpha only when `< 1`. |
86
+ | `uppercase` | `boolean` | `false` | Outputs uppercase HEX. |
87
+ | `onError` | `"preserve" \| "throw"` | `"preserve"` | `"preserve"` keeps original token on parse/convert failure. |
88
+ | `convertDev` | `boolean` | `true` | Vite + Next only. Disable conversion in dev mode. |
89
+ | `convertBuild` | `boolean` | `true` | Vite + Next only. Disable conversion in build mode. |
90
+ | `include` | `RegExp \| (id: string) => boolean` | `/\.(css\|pcss\|postcss\|scss\|sass\|less\|styl\|stylus)(?:$\|\?)/i` | Vite only. File filter. |
91
+ | `exclude` | `RegExp \| (id: string) => boolean` | `undefined` | Vite only. Skip filter. |
91
92
 
92
- ## FAQ
93
+ ## Tailwind-Specific Handling
93
94
 
94
- ### Do I need to change build/dev commands?
95
- No. Add plugin/config once, keep your existing commands.
95
+ `replaceOklchInText` also supports common Tailwind CSS output patterns:
96
+ - Replaces known default palette variables like `--color-red-500` with mapped HEX.
97
+ - Converts `color-mix(in oklab, var(--color-... ) N%, transparent)` into HEX with alpha.
98
+ - Handles slash opacity output such as `border-red-500/30` when emitted through CSS variables.
96
99
 
97
- ### Why do I still see `rgb(...)` sometimes?
98
- That is usually in DevTools `Computed` view. Check `Styles` or emitted CSS for HEX.
100
+ ## Compatibility
99
101
 
100
- ### What if parsing fails for a color token?
101
- By default (`onError: "preserve"`), the original token is kept.
102
+ - Node.js `>=18`
103
+ - Next.js integration is webpack-based and processes emitted `.css` assets
@@ -1 +1 @@
1
- var f=Object.create;var u=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var b=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of x(e))!S.call(t,s)&&s!==o&&u(t,s,{get:()=>e[s],enumerable:!(n=w(e,s))||n.enumerable});return t};var m=(t,e,o)=>(o=t!=null?f(g(t)):{},b(e||!t||!t.__esModule?u(o,"default",{value:t,enumerable:!0}):o,t));class d{constructor(e){this.options=e||{}}apply(e){const o="oklchtohex-next-webpack-plugin",{Compilation:n,sources:s}=e.webpack;let i;e.hooks.thisCompilation.tap(o,c=>{c.hooks.processAssets.tapPromise({name:o,stage:n.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE},async h=>{for(const[r,k]of Object.entries(h)){if(!r.endsWith(".css"))continue;const p=k.source().toString();if(!p.toLowerCase().includes("oklch("))continue;i||(i=import("./converter.js"));const l=(await i).replaceOklchInText(p,this.options);l!==p&&c.updateAsset(r,new s.RawSource(l))}})})}}function a(t,e){const o=t||{};return{...o,webpack(n,s){const i=typeof o.webpack=="function"?o.webpack:null,c=i?i(n,s):n;return c.plugins=c.plugins||[],c.plugins.push(new d(e)),c}}}module.exports=a,module.exports.default=a,module.exports.withOklchToHexNext=a;
1
+ var w=Object.create;var v=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,b=Object.prototype.hasOwnProperty;var O=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of g(e))!b.call(o,s)&&s!==t&&v(o,s,{get:()=>e[s],enumerable:!(n=d(e,s))||n.enumerable});return o};var S=(o,e,t)=>(t=o!=null?w(x(o)):{},O(e||!o||!o.__esModule?v(t,"default",{value:o,enumerable:!0}):t,o));class m{constructor(e){this.options=e||{}}apply(e){const t="oklchtohex-next-webpack-plugin",{Compilation:n,sources:s}=e.webpack;let c;e.hooks.thisCompilation.tap(t,a=>{a.hooks.processAssets.tapPromise({name:t,stage:n.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE},async i=>{for(const[l,p]of Object.entries(i)){if(!l.endsWith(".css"))continue;const r=p.source().toString();if(!r.toLowerCase().includes("oklch("))continue;c||(c=import("./converter.js"));const u=(await c).replaceOklchInText(r,this.options);u!==r&&a.updateAsset(l,new s.RawSource(u))}})})}}function f(o,e){const t=o||{},n=e||{};return{...t,webpack(s,c){const a=typeof t.webpack=="function"?t.webpack:null,i=a?a(s,c):s,l=typeof n.convertDev=="boolean"?n.convertDev:!0,p=typeof n.convertBuild=="boolean"?n.convertBuild:!0,r=!!(c&&c.dev);if(r&&!l||!r&&!p)return i;const{convertDev:h,convertBuild:u,...k}=n;return i.plugins=i.plugins||[],i.plugins.push(new m(k)),i}}}module.exports=f,module.exports.default=f,module.exports.withOklchToHexNext=f;
@@ -1 +1 @@
1
- import{replaceOklchInText as l}from"./converter.js";class k{constructor(s={}){this.options=s}apply(s){const t="oklchtohex-next-webpack-plugin",{Compilation:c,sources:n}=s.webpack;s.hooks.thisCompilation.tap(t,e=>{e.hooks.processAssets.tap({name:t,stage:c.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE},u=>{for(const[p,r]of Object.entries(u)){if(!p.endsWith(".css"))continue;const i=r.source().toString();if(!i.toLowerCase().includes("oklch("))continue;const a=l(i,this.options);a!==i&&e.updateAsset(p,new n.RawSource(a))}})})}}function w(o={},s={}){return{...o,webpack(t,c){const n=typeof o.webpack=="function"?o.webpack:null,e=n?n(t,c):t;return e.plugins=e.plugins||[],e.plugins.push(new k(s)),e}}}export{w as withOklchToHexNext};
1
+ import{replaceOklchInText as l}from"./converter.js";class k{constructor(t={}){this.options=t}apply(t){const s="oklchtohex-next-webpack-plugin",{Compilation:c,sources:i}=t.webpack;t.hooks.thisCompilation.tap(s,e=>{e.hooks.processAssets.tap({name:s,stage:c.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE},p=>{for(const[r,u]of Object.entries(p)){if(!r.endsWith(".css"))continue;const o=u.source().toString();if(!o.toLowerCase().includes("oklch("))continue;const a=l(o,this.options);a!==o&&e.updateAsset(r,new i.RawSource(a))}})})}}function w(n={},t={}){return{...n,webpack(s,c){const i=typeof n.webpack=="function"?n.webpack:null,e=i?i(s,c):s,{convertDev:p=!0,convertBuild:r=!0,...u}=t,o=!!c?.dev;return o&&!p||!o&&!r||(e.plugins=e.plugins||[],e.plugins.push(new k(u))),e}}}export{w as withOklchToHexNext};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oklchtohex",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "Convert OKLCH colors to HEX as a JavaScript package.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",