@adea-ai/themes 0.6.0 → 0.6.2
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 +5 -0
- package/dist/adapters/shadcn.d.ts +18 -0
- package/dist/adapters/shadcn.d.ts.map +1 -1
- package/dist/adapters/shadcn.js +89 -2
- package/dist/adapters/shadcn.js.map +1 -1
- package/dist/derive.d.ts +9 -0
- package/dist/derive.d.ts.map +1 -1
- package/dist/derive.js +55 -0
- package/dist/derive.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/shadcn.ts +117 -2
- package/src/derive.ts +63 -0
- package/src/index.ts +10 -2
package/README.md
CHANGED
|
@@ -91,6 +91,11 @@ terminal.options.theme = toXtermTheme(theme)
|
|
|
91
91
|
const highlighter = await createHighlighter({ themes: [toShikiTheme(theme)], langs: [...] })
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
`syntaxRolesHex(theme)` keeps comments at the catalogue's intentionally quiet default.
|
|
95
|
+
For editor palettes where comments and diff markers are small content text,
|
|
96
|
+
`editorRolesHex(theme)` returns the editor roles with every rounded hex value checked
|
|
97
|
+
against a 4.5:1 contrast floor. The source syntax palette remains unchanged.
|
|
98
|
+
|
|
94
99
|
Every exported theme value is an `oklch()` string, which means the browser does the
|
|
95
100
|
colour work and a consumer can compose — `color-mix(in oklch, var(--adea-accent),
|
|
96
101
|
transparent 20%)` — and get a predictable result. The adapters that need hex (xterm,
|
|
@@ -26,6 +26,24 @@ import type { AdeaTheme, AdeaThemeColors, ShadcnThemeProjection } from '../schem
|
|
|
26
26
|
export type ShadcnTheme = AdeaTheme & {
|
|
27
27
|
shadcn?: ShadcnThemeProjection;
|
|
28
28
|
};
|
|
29
|
+
/** The solid destructive pair consumed by filled shadcn actions. */
|
|
30
|
+
export interface ShadcnDestructiveProjection {
|
|
31
|
+
/** Presentation fill derived from, but distinct from, the canonical error role. */
|
|
32
|
+
readonly fill: string;
|
|
33
|
+
/** Text color that clears the solid and 90%-hover presentation floors. */
|
|
34
|
+
readonly foreground: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The shared destructive solid fill and foreground as rendered by the UI.
|
|
38
|
+
*
|
|
39
|
+
* A filled destructive button uses `--destructive/90` on hover. A foreground that
|
|
40
|
+
* clears the original fill can fall below AA when that color is alpha-composited
|
|
41
|
+
* over a light or dark surface. This projection keeps the canonical error color
|
|
42
|
+
* untouched, adjusts only the presentation lightness along its hue, and tests the
|
|
43
|
+
* rounded sRGB output against the canvas and both card surfaces. The 5:1 internal
|
|
44
|
+
* margin protects the 4.5:1 AA floor from browser quantization.
|
|
45
|
+
*/
|
|
46
|
+
export declare function shadcnDestructiveProjection(theme: ShadcnTheme): ShadcnDestructiveProjection;
|
|
29
47
|
/**
|
|
30
48
|
* Canonical role → shadcn custom-property name.
|
|
31
49
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadcn.d.ts","sourceRoot":"","sources":["../../src/adapters/shadcn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"shadcn.d.ts","sourceRoot":"","sources":["../../src/adapters/shadcn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAWrF,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IAAE,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAAE,CAAA;AAExE,oEAAoE;AACpE,MAAM,WAAW,2BAA2B;IAC1C,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,2BAA2B,CA6D3F;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,eAAe,EAAE,MAAM,CAAC,CAsBzE,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAItE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6D1E;AAED,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,SAAU,GAAG,MAAM,CAKxE"}
|
package/dist/adapters/shadcn.js
CHANGED
|
@@ -22,6 +22,90 @@
|
|
|
22
22
|
* A table of the whole mapping is in `docs/shadcn-bridge.md`.
|
|
23
23
|
*/
|
|
24
24
|
import { STATUS_ROLES, statusForeground, tint } from '../derive.js';
|
|
25
|
+
import { contrastRatio, formatOklch, gamutMap, hexToOklch, oklchToHex, parseColor, } from '../oklch.js';
|
|
26
|
+
const DESTRUCTIVE_PRESENTATION_FLOOR = 5;
|
|
27
|
+
const DESTRUCTIVE_HOVER_OPACITY = 0.9;
|
|
28
|
+
const DESTRUCTIVE_PRESENTATION_SURFACES = ['background', 'surface', 'surfaceElevated'];
|
|
29
|
+
function renderedColor(value) {
|
|
30
|
+
const color = parseColor(value);
|
|
31
|
+
return color ? hexToOklch(oklchToHex(color)) : undefined;
|
|
32
|
+
}
|
|
33
|
+
function compositeSrgb(foreground, background, alpha) {
|
|
34
|
+
const foregroundHex = oklchToHex(parseColor(foreground));
|
|
35
|
+
const backgroundHex = oklchToHex(parseColor(background));
|
|
36
|
+
const channels = [1, 3, 5].map((offset) => {
|
|
37
|
+
const front = Number.parseInt(foregroundHex.slice(offset, offset + 2), 16);
|
|
38
|
+
const back = Number.parseInt(backgroundHex.slice(offset, offset + 2), 16);
|
|
39
|
+
return Math.round(front * alpha + back * (1 - alpha))
|
|
40
|
+
.toString(16)
|
|
41
|
+
.padStart(2, '0');
|
|
42
|
+
});
|
|
43
|
+
return hexToOklch(`#${channels.join('')}`);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The shared destructive solid fill and foreground as rendered by the UI.
|
|
47
|
+
*
|
|
48
|
+
* A filled destructive button uses `--destructive/90` on hover. A foreground that
|
|
49
|
+
* clears the original fill can fall below AA when that color is alpha-composited
|
|
50
|
+
* over a light or dark surface. This projection keeps the canonical error color
|
|
51
|
+
* untouched, adjusts only the presentation lightness along its hue, and tests the
|
|
52
|
+
* rounded sRGB output against the canvas and both card surfaces. The 5:1 internal
|
|
53
|
+
* margin protects the 4.5:1 AA floor from browser quantization.
|
|
54
|
+
*/
|
|
55
|
+
export function shadcnDestructiveProjection(theme) {
|
|
56
|
+
const sourceFill = parseColor(theme.colors.error);
|
|
57
|
+
const sourceForeground = parseColor(theme.colors.foreground);
|
|
58
|
+
const sourceBackground = parseColor(theme.colors.background);
|
|
59
|
+
if (!sourceFill || !sourceForeground || !sourceBackground) {
|
|
60
|
+
throw new Error(`theme ${theme.id} has an invalid destructive color pair`);
|
|
61
|
+
}
|
|
62
|
+
const preferredForeground = statusForeground(theme, 'error');
|
|
63
|
+
const alternateForeground = contrastRatio(sourceForeground, sourceFill) >= contrastRatio(sourceBackground, sourceFill)
|
|
64
|
+
? theme.colors.background
|
|
65
|
+
: theme.colors.foreground;
|
|
66
|
+
const foregrounds = [preferredForeground, alternateForeground]
|
|
67
|
+
.map((value) => ({ value, rendered: renderedColor(value) }))
|
|
68
|
+
.filter((entry) => Boolean(entry.rendered));
|
|
69
|
+
const surfaceValues = [
|
|
70
|
+
...DESTRUCTIVE_PRESENTATION_SURFACES.map((role) => theme.colors[role]),
|
|
71
|
+
theme.shadcn?.card ?? theme.colors.surface,
|
|
72
|
+
theme.shadcn?.popover ?? theme.colors.surfaceElevated,
|
|
73
|
+
];
|
|
74
|
+
const surfaces = surfaceValues
|
|
75
|
+
.map((value) => ({ value, rendered: renderedColor(value) }))
|
|
76
|
+
.filter((entry) => Boolean(entry.rendered));
|
|
77
|
+
if (surfaces.length !== surfaceValues.length) {
|
|
78
|
+
throw new Error(`theme ${theme.id} has an invalid destructive presentation surface`);
|
|
79
|
+
}
|
|
80
|
+
for (let step = 0; step <= 250; step += 1) {
|
|
81
|
+
const directions = step === 0 ? [0] : [-1, 1];
|
|
82
|
+
for (const direction of directions) {
|
|
83
|
+
const candidate = gamutMap({
|
|
84
|
+
...sourceFill,
|
|
85
|
+
l: sourceFill.l + direction * step * 0.001,
|
|
86
|
+
});
|
|
87
|
+
if (candidate.l < 0.02 || candidate.l > 0.98)
|
|
88
|
+
continue;
|
|
89
|
+
const fill = formatOklch(candidate);
|
|
90
|
+
const renderedFill = renderedColor(fill);
|
|
91
|
+
if (!renderedFill)
|
|
92
|
+
continue;
|
|
93
|
+
for (const foreground of foregrounds) {
|
|
94
|
+
const solidRatio = contrastRatio(foreground.rendered, renderedFill);
|
|
95
|
+
if (solidRatio < DESTRUCTIVE_PRESENTATION_FLOOR)
|
|
96
|
+
continue;
|
|
97
|
+
const clearsHoverFloor = surfaces.every(({ rendered }) => {
|
|
98
|
+
const composite = compositeSrgb(fill, formatOklch(rendered), DESTRUCTIVE_HOVER_OPACITY);
|
|
99
|
+
return (composite !== undefined &&
|
|
100
|
+
contrastRatio(foreground.rendered, composite) >= DESTRUCTIVE_PRESENTATION_FLOOR);
|
|
101
|
+
});
|
|
102
|
+
if (clearsHoverFloor)
|
|
103
|
+
return { fill, foreground: foreground.value };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`theme ${theme.id} cannot meet the shared destructive presentation floor`);
|
|
108
|
+
}
|
|
25
109
|
/**
|
|
26
110
|
* Canonical role → shadcn custom-property name.
|
|
27
111
|
*
|
|
@@ -71,8 +155,9 @@ export function shadcnRoles(theme) {
|
|
|
71
155
|
*/
|
|
72
156
|
export function shadcnVariables(theme) {
|
|
73
157
|
const variables = {};
|
|
158
|
+
const destructive = shadcnDestructiveProjection(theme);
|
|
74
159
|
for (const [role, name] of Object.entries(SHADCN_MAPPING)) {
|
|
75
|
-
variables[`--${name}`] = theme.colors[role];
|
|
160
|
+
variables[`--${name}`] = role === 'error' ? destructive.fill : theme.colors[role];
|
|
76
161
|
}
|
|
77
162
|
variables['--accent'] = theme.colors.surfaceHover;
|
|
78
163
|
variables['--accent-foreground'] = theme.colors.text;
|
|
@@ -99,13 +184,15 @@ export function shadcnVariables(theme) {
|
|
|
99
184
|
variables['--sidebar-primary-foreground'] = theme.colors.accentForeground;
|
|
100
185
|
variables['--sidebar-ring'] = theme.colors.accent;
|
|
101
186
|
variables['--sidebar-muted-foreground'] = theme.colors.textMuted;
|
|
187
|
+
variables['--destructive-foreground'] = destructive.foreground;
|
|
102
188
|
for (const role of STATUS_ROLES) {
|
|
103
189
|
// Status labels on a subtle fill use the theme's body foreground; this
|
|
104
190
|
// foreground is reserved for text on the role's solid colour. Keep the
|
|
105
191
|
// generated shadcn names aligned with SHADCN_MAPPING, especially error →
|
|
106
192
|
// destructive, and resolve the tint against a real canvas so it is opaque.
|
|
107
193
|
const shadcnRole = SHADCN_MAPPING[role];
|
|
108
|
-
variables[`--${shadcnRole}-foreground`] =
|
|
194
|
+
variables[`--${shadcnRole}-foreground`] =
|
|
195
|
+
role === 'error' ? destructive.foreground : statusForeground(theme, role);
|
|
109
196
|
variables[`--${shadcnRole}-subtle`] = tint(theme.colors[role], theme.colors.background);
|
|
110
197
|
}
|
|
111
198
|
variables['--surface-sunken'] = theme.colors.background;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadcn.js","sourceRoot":"","sources":["../../src/adapters/shadcn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"shadcn.js","sourceRoot":"","sources":["../../src/adapters/shadcn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EACL,aAAa,EACb,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,aAAa,CAAA;AAapB,MAAM,8BAA8B,GAAG,CAAC,CAAA;AACxC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AACrC,MAAM,iCAAiC,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,iBAAiB,CAAU,CAAA;AAE/F,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1D,CAAC;AAED,SAAS,aAAa,CAAC,UAAkB,EAAE,UAAkB,EAAE,KAAa;IAC1E,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,UAAU,CAAE,CAAC,CAAA;IACzD,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,UAAU,CAAE,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACzE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAClD,QAAQ,CAAC,EAAE,CAAC;aACZ,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACrB,CAAC,CAAC,CAAA;IACF,OAAO,UAAU,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAkB;IAC5D,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC5D,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC5D,IAAI,CAAC,UAAU,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,wCAAwC,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC5D,MAAM,mBAAmB,GACvB,aAAa,CAAC,gBAAgB,EAAE,UAAU,CAAC,IAAI,aAAa,CAAC,gBAAgB,EAAE,UAAU,CAAC;QACxF,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU;QACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAA;IAC7B,MAAM,WAAW,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;SAC3D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,KAAK,EAA4E,EAAE,CAC1F,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CACxB,CAAA;IACH,MAAM,aAAa,GAAG;QACpB,GAAG,iCAAiC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtE,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;QAC1C,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,eAAe;KACtD,CAAA;IACD,MAAM,QAAQ,GAAG,aAAa;SAC3B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,KAAK,EAA4E,EAAE,CAC1F,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CACxB,CAAA;IACH,IAAI,QAAQ,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,kDAAkD,CAAC,CAAA;IACtF,CAAC;IAED,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC7C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,QAAQ,CAAC;gBACzB,GAAG,UAAU;gBACb,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK;aAC3C,CAAC,CAAA;YACF,IAAI,SAAS,CAAC,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,CAAC,GAAG,IAAI;gBAAE,SAAQ;YACtD,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACnC,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;YACxC,IAAI,CAAC,YAAY;gBAAE,SAAQ;YAE3B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACrC,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;gBACnE,IAAI,UAAU,GAAG,8BAA8B;oBAAE,SAAQ;gBAEzD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;oBACvD,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE,yBAAyB,CAAC,CAAA;oBACvF,OAAO,CACL,SAAS,KAAK,SAAS;wBACvB,aAAa,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,8BAA8B,CAChF,CAAA;gBACH,CAAC,CAAC,CAAA;gBACF,IAAI,gBAAgB;oBAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,CAAA;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,wDAAwD,CAAC,CAAA;AAC5F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoD,MAAM,CAAC,MAAM,CAAC;IAC3F,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,yDAAyD;IACzD,OAAO,EAAE,MAAM;IACf,eAAe,EAAE,SAAS;IAC1B,YAAY,EAAE,eAAe;IAC7B,aAAa,EAAE,gBAAgB;IAC/B,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,cAAc;IAC3B,4EAA4E;IAC5E,IAAI,EAAE,YAAY;IAClB,SAAS,EAAE,kBAAkB;IAC7B,UAAU,EAAE,mBAAmB;IAC/B,gEAAgE;IAChE,MAAM,EAAE,SAAS;IACjB,gBAAgB,EAAE,oBAAoB;IACtC,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,qEAAqE;IACrE,KAAK,EAAE,aAAa;IACpB,IAAI,EAAE,MAAM;CACb,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAChG,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,SAAS,GAA2B,EAAE,CAAA;IAC5C,MAAM,WAAW,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAA;IAEtD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAsC,EAAE,CAAC;QAC/F,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACnF,CAAC;IAED,SAAS,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAA;IACjD,SAAS,CAAC,qBAAqB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IACpD,SAAS,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IAC/D,SAAS,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IAEjE,6EAA6E;IAC7E,mFAAmF;IACnF,kFAAkF;IAClF,2EAA2E;IAC3E,qCAAqC;IACrC,SAAS,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAA;IAChE,SAAS,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,eAAe,CAAA;IAC9E,SAAS,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IAClD,SAAS,CAAC,sBAAsB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IACrD,SAAS,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAA;IAC1E,SAAS,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IACvD,SAAS,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAA;IAClE,SAAS,CAAC,oBAAoB,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAA;IACzF,SAAS,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAA;IAC7C,SAAS,CAAC,sBAAsB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IACrD,SAAS,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAA;IACzD,SAAS,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IACnD,SAAS,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IACpD,SAAS,CAAC,8BAA8B,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAA;IACzE,SAAS,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IACjD,SAAS,CAAC,4BAA4B,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAA;IAEhE,SAAS,CAAC,0BAA0B,CAAC,GAAG,WAAW,CAAC,UAAU,CAAA;IAE9D,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,uEAAuE;QACvE,uEAAuE;QACvE,yEAAyE;QACzE,2EAA2E;QAC3E,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QACvC,SAAS,CAAC,KAAK,UAAU,aAAa,CAAC;YACrC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC3E,SAAS,CAAC,KAAK,UAAU,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACzF,CAAC;IAED,SAAS,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAA;IACvD,SAAS,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,eAAe,CAAA;IAC5D,SAAS,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,eAAe,CAAA;IAE7D,2EAA2E;IAC3E,6EAA6E;IAC7E,iDAAiD;IACjD,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM;QAAE,SAAS,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IAErE,SAAS,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,CAAA;IACpC,SAAS,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,SAAS,CAAA;IAE1C,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,SAAS,CAAC,KAAkB,EAAE,QAAQ,GAAG,OAAO;IAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,KAAK,GAAG,CAAC;SAC9C,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO,GAAG,QAAQ,OAAO,IAAI,KAAK,CAAA;AACpC,CAAC"}
|
package/dist/derive.d.ts
CHANGED
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
import type { AdeaTheme } from './schema.js';
|
|
32
32
|
/** The syntax roles, matching the names Shiki's theme contract expects. */
|
|
33
33
|
export type SyntaxRole = 'keyword' | 'string' | 'number' | 'comment' | 'function' | 'variable' | 'type' | 'tag' | 'attribute' | 'operator' | 'heading' | 'link' | 'constant' | 'punctuation' | 'diffAdd' | 'diffDelete' | 'diffHunk' | 'searchMatch';
|
|
34
|
+
/** Roles in the product's editor palette, which are all read as small text. */
|
|
35
|
+
export type EditorRole = Exclude<SyntaxRole, 'constant' | 'punctuation'>;
|
|
34
36
|
/**
|
|
35
37
|
* The syntax palette for a theme, as OKLCH strings.
|
|
36
38
|
*
|
|
@@ -45,6 +47,13 @@ export declare function syntaxRoles(theme: AdeaTheme, options?: {
|
|
|
45
47
|
}): Record<SyntaxRole, string>;
|
|
46
48
|
/** The syntax palette as hex, for engines that cannot evaluate `oklch()`. */
|
|
47
49
|
export declare function syntaxRolesHex(theme: AdeaTheme): Record<SyntaxRole, string>;
|
|
50
|
+
/**
|
|
51
|
+
* The hex role set for code editors, where comments and diffs are rendered as
|
|
52
|
+
* content text rather than decorative syntax. The quiet syntax API stays at its
|
|
53
|
+
* palette-selected comment level; this projection explicitly holds every editor
|
|
54
|
+
* role to WCAG AA on the canvas.
|
|
55
|
+
*/
|
|
56
|
+
export declare function editorRolesHex(theme: AdeaTheme): Record<EditorRole, string>;
|
|
48
57
|
/**
|
|
49
58
|
* The categorical chart series, derived from the ANSI hues.
|
|
50
59
|
*
|
package/dist/derive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAI5C,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,UAAU,GACV,MAAM,GACN,KAAK,GACL,WAAW,GACX,UAAU,GACV,SAAS,GACT,MAAM,GACN,UAAU,GACV,aAAa,GACb,SAAS,GACT,YAAY,GACZ,UAAU,GACV,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAI5C,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,UAAU,GACV,MAAM,GACN,KAAK,GACL,WAAW,GACX,UAAU,GACV,SAAS,GACT,MAAM,GACN,UAAU,GACV,aAAa,GACb,SAAS,GACT,YAAY,GACZ,UAAU,GACV,aAAa,CAAA;AAEjB,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC,CAAA;AAkDxE;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAgC5B;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAQ3E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAiC3E;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC,EAOlD,CAAA;AAEX,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,MAAM,EAAE,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,MAAM,CAK7E;AAED,qEAAqE;AACrE,eAAO,MAAM,YAAY,kDAAmD,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAS3E;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAG9E"}
|
package/dist/derive.js
CHANGED
|
@@ -29,6 +29,24 @@
|
|
|
29
29
|
* palettes today.
|
|
30
30
|
*/
|
|
31
31
|
import { contrastRatio, formatOklch, mix, oklchToHex, parseColor, repairContrast } from './oklch.js';
|
|
32
|
+
const EDITOR_ROLES = [
|
|
33
|
+
'keyword',
|
|
34
|
+
'string',
|
|
35
|
+
'number',
|
|
36
|
+
'comment',
|
|
37
|
+
'function',
|
|
38
|
+
'variable',
|
|
39
|
+
'type',
|
|
40
|
+
'tag',
|
|
41
|
+
'attribute',
|
|
42
|
+
'operator',
|
|
43
|
+
'heading',
|
|
44
|
+
'link',
|
|
45
|
+
'diffAdd',
|
|
46
|
+
'diffDelete',
|
|
47
|
+
'diffHunk',
|
|
48
|
+
'searchMatch',
|
|
49
|
+
];
|
|
32
50
|
/** Which ANSI role each syntax role is read from, and why. */
|
|
33
51
|
const SYNTAX_SOURCE = Object.freeze({
|
|
34
52
|
// Magenta is the slot palettes spend on the most distinctive hue they have, and
|
|
@@ -101,6 +119,43 @@ export function syntaxRolesHex(theme) {
|
|
|
101
119
|
return [role, parsed ? oklchToHex(parsed) : value];
|
|
102
120
|
}));
|
|
103
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* The hex role set for code editors, where comments and diffs are rendered as
|
|
124
|
+
* content text rather than decorative syntax. The quiet syntax API stays at its
|
|
125
|
+
* palette-selected comment level; this projection explicitly holds every editor
|
|
126
|
+
* role to WCAG AA on the canvas.
|
|
127
|
+
*/
|
|
128
|
+
export function editorRolesHex(theme) {
|
|
129
|
+
const roles = syntaxRolesHex(theme);
|
|
130
|
+
const background = parseColor(theme.colors.background);
|
|
131
|
+
if (!background)
|
|
132
|
+
throw new Error(`theme ${theme.id} has no valid editor background`);
|
|
133
|
+
return Object.fromEntries(EDITOR_ROLES.map((role) => {
|
|
134
|
+
const source = parseColor(roles[role]);
|
|
135
|
+
if (!source)
|
|
136
|
+
throw new Error(`theme ${theme.id} has no valid editor.${role}`);
|
|
137
|
+
const initial = oklchToHex(source);
|
|
138
|
+
const renderedInitial = parseColor(initial);
|
|
139
|
+
if (renderedInitial && contrastRatio(renderedInitial, background) >= 4.5 - 1e-9) {
|
|
140
|
+
return [role, initial];
|
|
141
|
+
}
|
|
142
|
+
// Repair against the exact role the editor receives. A repair at precisely
|
|
143
|
+
// 4.5:1 in OKLCH can round to a hex value just below that floor, so advance
|
|
144
|
+
// the requested threshold by the smallest measured step until the encoded
|
|
145
|
+
// value itself clears 4.5:1. No source palette value or hue is rewritten.
|
|
146
|
+
for (let margin = 0.001; margin <= 0.05; margin += 0.001) {
|
|
147
|
+
const repaired = repairContrast(source, background, 4.5 + margin);
|
|
148
|
+
if (!repaired.satisfied)
|
|
149
|
+
continue;
|
|
150
|
+
const candidate = oklchToHex(repaired.color);
|
|
151
|
+
const renderedCandidate = parseColor(candidate);
|
|
152
|
+
if (renderedCandidate && contrastRatio(renderedCandidate, background) >= 4.5 - 1e-9) {
|
|
153
|
+
return [role, candidate];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`cannot encode editor.${role} for ${theme.id} above 4.5:1 contrast`);
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
104
159
|
/**
|
|
105
160
|
* The categorical chart series, derived from the ANSI hues.
|
|
106
161
|
*
|
package/dist/derive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -53,8 +53,8 @@ export type { AnsiInvariant, ContrastFinding, Pairing } from './validate.js';
|
|
|
53
53
|
export { REQUIRED_PAIRINGS, STATUS_PAIRINGS, checkAnsiRamp, formatFindings, validateCatalogue, validateTheme, } from './validate.js';
|
|
54
54
|
export type { NormalizationFinding, NormalizedTheme, ThemeSourceSpec } from './normalize.js';
|
|
55
55
|
export { CONTRAST_FLOORS, normalizeTheme } from './normalize.js';
|
|
56
|
-
export type { StatusRole, SyntaxRole } from './derive.js';
|
|
57
|
-
export { CHART_SERIES, STATUS_ROLES, chartSeries, statusForeground, statusForegroundHex, syntaxRoles, syntaxRolesHex, tint, } from './derive.js';
|
|
56
|
+
export type { EditorRole, StatusRole, SyntaxRole } from './derive.js';
|
|
57
|
+
export { CHART_SERIES, STATUS_ROLES, chartSeries, editorRolesHex, statusForeground, statusForegroundHex, syntaxRoles, syntaxRolesHex, tint, } from './derive.js';
|
|
58
58
|
export type { Base24Palette, Base24Scheme, Base24Slot } from './adapters/base24.js';
|
|
59
59
|
export { BASE24_SLOTS, BASE24_SLOT_MEANING, BASE24_TO_ANSI, Base24ParseError, formatBase24Scheme, parseBase24Palette, parseBase24Scheme, toBase24, } from './adapters/base24.js';
|
|
60
60
|
export type { XtermTheme } from './adapters/xterm.js';
|
|
@@ -65,5 +65,6 @@ export type { TailwindOptions } from './adapters/tailwind.js';
|
|
|
65
65
|
export { toTailwindTheme } from './adapters/tailwind.js';
|
|
66
66
|
export type { ShikiThemeRegistration, ShikiTokenSetting } from './adapters/shiki.js';
|
|
67
67
|
export { toShikiTheme, toShikiThemes } from './adapters/shiki.js';
|
|
68
|
-
export {
|
|
68
|
+
export type { ShadcnDestructiveProjection } from './adapters/shadcn.js';
|
|
69
|
+
export { SHADCN_MAPPING, shadcnCss, shadcnDestructiveProjection, shadcnRoles, shadcnVariables, } from './adapters/shadcn.js';
|
|
69
70
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,YAAY,EACV,QAAQ,EACR,SAAS,EACT,eAAe,EACf,eAAe,EACf,OAAO,EACP,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEzD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,aAAa,EACb,QAAQ,EACR,MAAM,EACN,kBAAkB,EAClB,OAAO,GACR,MAAM,gBAAgB,CAAA;AAGvB,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,EACL,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,GAAG,EACH,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAA;AAGnB,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,eAAe,CAAA;AAGtB,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAGhE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -49,11 +49,11 @@ export { DEFAULT_THEME_IDS, getBase24Scheme, getTheme, hasTheme, resolveTheme, t
|
|
|
49
49
|
export { contrastRatio, deltaEok, formatOklch, gamutMap, hexToOklch, inGamut, mix, oklchToHex, parseColor, parseOklch, relativeLuminance, repairContrast, shiftLightness, } from './oklch.js';
|
|
50
50
|
export { REQUIRED_PAIRINGS, STATUS_PAIRINGS, checkAnsiRamp, formatFindings, validateCatalogue, validateTheme, } from './validate.js';
|
|
51
51
|
export { CONTRAST_FLOORS, normalizeTheme } from './normalize.js';
|
|
52
|
-
export { CHART_SERIES, STATUS_ROLES, chartSeries, statusForeground, statusForegroundHex, syntaxRoles, syntaxRolesHex, tint, } from './derive.js';
|
|
52
|
+
export { CHART_SERIES, STATUS_ROLES, chartSeries, editorRolesHex, statusForeground, statusForegroundHex, syntaxRoles, syntaxRolesHex, tint, } from './derive.js';
|
|
53
53
|
export { BASE24_SLOTS, BASE24_SLOT_MEANING, BASE24_TO_ANSI, Base24ParseError, formatBase24Scheme, parseBase24Palette, parseBase24Scheme, toBase24, } from './adapters/base24.js';
|
|
54
54
|
export { toXtermTheme } from './adapters/xterm.js';
|
|
55
55
|
export { catalogueCss, cssVariableName, themeCss, themeCssVariables } from './adapters/css.js';
|
|
56
56
|
export { toTailwindTheme } from './adapters/tailwind.js';
|
|
57
57
|
export { toShikiTheme, toShikiThemes } from './adapters/shiki.js';
|
|
58
|
-
export { SHADCN_MAPPING, shadcnCss, shadcnRoles, shadcnVariables } from './adapters/shadcn.js';
|
|
58
|
+
export { SHADCN_MAPPING, shadcnCss, shadcnDestructiveProjection, shadcnRoles, shadcnVariables, } from './adapters/shadcn.js';
|
|
59
59
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAgBH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGzD,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,8EAA8E;AAC9E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,aAAa,EACb,QAAQ,EACR,MAAM,EACN,kBAAkB,EAClB,OAAO,GACR,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,GAAG,EACH,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAA;AAInB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,eAAe,CAAA;AAItB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIhE,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,IAAI,GACL,MAAM,aAAa,CAAA;AAIpB,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAG9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAgBH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGzD,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,8EAA8E;AAC9E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,aAAa,EACb,QAAQ,EACR,MAAM,EACN,kBAAkB,EAClB,OAAO,GACR,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,GAAG,EACH,UAAU,EACV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAA;AAInB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,eAAe,CAAA;AAItB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIhE,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,IAAI,GACL,MAAM,aAAa,CAAA;AAIpB,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAG9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGjE,OAAO,EACL,cAAc,EACd,SAAS,EACT,2BAA2B,EAC3B,WAAW,EACX,eAAe,GAChB,MAAM,sBAAsB,CAAA"}
|
package/package.json
CHANGED
package/src/adapters/shadcn.ts
CHANGED
|
@@ -24,10 +24,121 @@
|
|
|
24
24
|
|
|
25
25
|
import type { AdeaTheme, AdeaThemeColors, ShadcnThemeProjection } from '../schema.js'
|
|
26
26
|
import { STATUS_ROLES, statusForeground, tint } from '../derive.js'
|
|
27
|
+
import {
|
|
28
|
+
contrastRatio,
|
|
29
|
+
formatOklch,
|
|
30
|
+
gamutMap,
|
|
31
|
+
hexToOklch,
|
|
32
|
+
oklchToHex,
|
|
33
|
+
parseColor,
|
|
34
|
+
} from '../oklch.js'
|
|
27
35
|
|
|
28
36
|
/** A canonical theme with optional owner-authored shadcn presentation values. */
|
|
29
37
|
export type ShadcnTheme = AdeaTheme & { shadcn?: ShadcnThemeProjection }
|
|
30
38
|
|
|
39
|
+
/** The solid destructive pair consumed by filled shadcn actions. */
|
|
40
|
+
export interface ShadcnDestructiveProjection {
|
|
41
|
+
/** Presentation fill derived from, but distinct from, the canonical error role. */
|
|
42
|
+
readonly fill: string
|
|
43
|
+
/** Text color that clears the solid and 90%-hover presentation floors. */
|
|
44
|
+
readonly foreground: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const DESTRUCTIVE_PRESENTATION_FLOOR = 5
|
|
48
|
+
const DESTRUCTIVE_HOVER_OPACITY = 0.9
|
|
49
|
+
const DESTRUCTIVE_PRESENTATION_SURFACES = ['background', 'surface', 'surfaceElevated'] as const
|
|
50
|
+
|
|
51
|
+
function renderedColor(value: string) {
|
|
52
|
+
const color = parseColor(value)
|
|
53
|
+
return color ? hexToOklch(oklchToHex(color)) : undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function compositeSrgb(foreground: string, background: string, alpha: number) {
|
|
57
|
+
const foregroundHex = oklchToHex(parseColor(foreground)!)
|
|
58
|
+
const backgroundHex = oklchToHex(parseColor(background)!)
|
|
59
|
+
const channels = [1, 3, 5].map((offset) => {
|
|
60
|
+
const front = Number.parseInt(foregroundHex.slice(offset, offset + 2), 16)
|
|
61
|
+
const back = Number.parseInt(backgroundHex.slice(offset, offset + 2), 16)
|
|
62
|
+
return Math.round(front * alpha + back * (1 - alpha))
|
|
63
|
+
.toString(16)
|
|
64
|
+
.padStart(2, '0')
|
|
65
|
+
})
|
|
66
|
+
return hexToOklch(`#${channels.join('')}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The shared destructive solid fill and foreground as rendered by the UI.
|
|
71
|
+
*
|
|
72
|
+
* A filled destructive button uses `--destructive/90` on hover. A foreground that
|
|
73
|
+
* clears the original fill can fall below AA when that color is alpha-composited
|
|
74
|
+
* over a light or dark surface. This projection keeps the canonical error color
|
|
75
|
+
* untouched, adjusts only the presentation lightness along its hue, and tests the
|
|
76
|
+
* rounded sRGB output against the canvas and both card surfaces. The 5:1 internal
|
|
77
|
+
* margin protects the 4.5:1 AA floor from browser quantization.
|
|
78
|
+
*/
|
|
79
|
+
export function shadcnDestructiveProjection(theme: ShadcnTheme): ShadcnDestructiveProjection {
|
|
80
|
+
const sourceFill = parseColor(theme.colors.error)
|
|
81
|
+
const sourceForeground = parseColor(theme.colors.foreground)
|
|
82
|
+
const sourceBackground = parseColor(theme.colors.background)
|
|
83
|
+
if (!sourceFill || !sourceForeground || !sourceBackground) {
|
|
84
|
+
throw new Error(`theme ${theme.id} has an invalid destructive color pair`)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const preferredForeground = statusForeground(theme, 'error')
|
|
88
|
+
const alternateForeground =
|
|
89
|
+
contrastRatio(sourceForeground, sourceFill) >= contrastRatio(sourceBackground, sourceFill)
|
|
90
|
+
? theme.colors.background
|
|
91
|
+
: theme.colors.foreground
|
|
92
|
+
const foregrounds = [preferredForeground, alternateForeground]
|
|
93
|
+
.map((value) => ({ value, rendered: renderedColor(value) }))
|
|
94
|
+
.filter((entry): entry is { value: string; rendered: NonNullable<typeof entry.rendered> } =>
|
|
95
|
+
Boolean(entry.rendered)
|
|
96
|
+
)
|
|
97
|
+
const surfaceValues = [
|
|
98
|
+
...DESTRUCTIVE_PRESENTATION_SURFACES.map((role) => theme.colors[role]),
|
|
99
|
+
theme.shadcn?.card ?? theme.colors.surface,
|
|
100
|
+
theme.shadcn?.popover ?? theme.colors.surfaceElevated,
|
|
101
|
+
]
|
|
102
|
+
const surfaces = surfaceValues
|
|
103
|
+
.map((value) => ({ value, rendered: renderedColor(value) }))
|
|
104
|
+
.filter((entry): entry is { value: string; rendered: NonNullable<typeof entry.rendered> } =>
|
|
105
|
+
Boolean(entry.rendered)
|
|
106
|
+
)
|
|
107
|
+
if (surfaces.length !== surfaceValues.length) {
|
|
108
|
+
throw new Error(`theme ${theme.id} has an invalid destructive presentation surface`)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (let step = 0; step <= 250; step += 1) {
|
|
112
|
+
const directions = step === 0 ? [0] : [-1, 1]
|
|
113
|
+
for (const direction of directions) {
|
|
114
|
+
const candidate = gamutMap({
|
|
115
|
+
...sourceFill,
|
|
116
|
+
l: sourceFill.l + direction * step * 0.001,
|
|
117
|
+
})
|
|
118
|
+
if (candidate.l < 0.02 || candidate.l > 0.98) continue
|
|
119
|
+
const fill = formatOklch(candidate)
|
|
120
|
+
const renderedFill = renderedColor(fill)
|
|
121
|
+
if (!renderedFill) continue
|
|
122
|
+
|
|
123
|
+
for (const foreground of foregrounds) {
|
|
124
|
+
const solidRatio = contrastRatio(foreground.rendered, renderedFill)
|
|
125
|
+
if (solidRatio < DESTRUCTIVE_PRESENTATION_FLOOR) continue
|
|
126
|
+
|
|
127
|
+
const clearsHoverFloor = surfaces.every(({ rendered }) => {
|
|
128
|
+
const composite = compositeSrgb(fill, formatOklch(rendered), DESTRUCTIVE_HOVER_OPACITY)
|
|
129
|
+
return (
|
|
130
|
+
composite !== undefined &&
|
|
131
|
+
contrastRatio(foreground.rendered, composite) >= DESTRUCTIVE_PRESENTATION_FLOOR
|
|
132
|
+
)
|
|
133
|
+
})
|
|
134
|
+
if (clearsHoverFloor) return { fill, foreground: foreground.value }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
throw new Error(`theme ${theme.id} cannot meet the shared destructive presentation floor`)
|
|
140
|
+
}
|
|
141
|
+
|
|
31
142
|
/**
|
|
32
143
|
* Canonical role → shadcn custom-property name.
|
|
33
144
|
*
|
|
@@ -81,9 +192,10 @@ export function shadcnRoles(theme: ShadcnTheme): Record<string, string> {
|
|
|
81
192
|
*/
|
|
82
193
|
export function shadcnVariables(theme: ShadcnTheme): Record<string, string> {
|
|
83
194
|
const variables: Record<string, string> = {}
|
|
195
|
+
const destructive = shadcnDestructiveProjection(theme)
|
|
84
196
|
|
|
85
197
|
for (const [role, name] of Object.entries(SHADCN_MAPPING) as [keyof AdeaThemeColors, string][]) {
|
|
86
|
-
variables[`--${name}`] = theme.colors[role]
|
|
198
|
+
variables[`--${name}`] = role === 'error' ? destructive.fill : theme.colors[role]
|
|
87
199
|
}
|
|
88
200
|
|
|
89
201
|
variables['--accent'] = theme.colors.surfaceHover
|
|
@@ -113,13 +225,16 @@ export function shadcnVariables(theme: ShadcnTheme): Record<string, string> {
|
|
|
113
225
|
variables['--sidebar-ring'] = theme.colors.accent
|
|
114
226
|
variables['--sidebar-muted-foreground'] = theme.colors.textMuted
|
|
115
227
|
|
|
228
|
+
variables['--destructive-foreground'] = destructive.foreground
|
|
229
|
+
|
|
116
230
|
for (const role of STATUS_ROLES) {
|
|
117
231
|
// Status labels on a subtle fill use the theme's body foreground; this
|
|
118
232
|
// foreground is reserved for text on the role's solid colour. Keep the
|
|
119
233
|
// generated shadcn names aligned with SHADCN_MAPPING, especially error →
|
|
120
234
|
// destructive, and resolve the tint against a real canvas so it is opaque.
|
|
121
235
|
const shadcnRole = SHADCN_MAPPING[role]
|
|
122
|
-
variables[`--${shadcnRole}-foreground`] =
|
|
236
|
+
variables[`--${shadcnRole}-foreground`] =
|
|
237
|
+
role === 'error' ? destructive.foreground : statusForeground(theme, role)
|
|
123
238
|
variables[`--${shadcnRole}-subtle`] = tint(theme.colors[role], theme.colors.background)
|
|
124
239
|
}
|
|
125
240
|
|
package/src/derive.ts
CHANGED
|
@@ -54,6 +54,28 @@ export type SyntaxRole =
|
|
|
54
54
|
| 'diffHunk'
|
|
55
55
|
| 'searchMatch'
|
|
56
56
|
|
|
57
|
+
/** Roles in the product's editor palette, which are all read as small text. */
|
|
58
|
+
export type EditorRole = Exclude<SyntaxRole, 'constant' | 'punctuation'>
|
|
59
|
+
|
|
60
|
+
const EDITOR_ROLES = [
|
|
61
|
+
'keyword',
|
|
62
|
+
'string',
|
|
63
|
+
'number',
|
|
64
|
+
'comment',
|
|
65
|
+
'function',
|
|
66
|
+
'variable',
|
|
67
|
+
'type',
|
|
68
|
+
'tag',
|
|
69
|
+
'attribute',
|
|
70
|
+
'operator',
|
|
71
|
+
'heading',
|
|
72
|
+
'link',
|
|
73
|
+
'diffAdd',
|
|
74
|
+
'diffDelete',
|
|
75
|
+
'diffHunk',
|
|
76
|
+
'searchMatch',
|
|
77
|
+
] as const satisfies readonly EditorRole[]
|
|
78
|
+
|
|
57
79
|
/** Which ANSI role each syntax role is read from, and why. */
|
|
58
80
|
const SYNTAX_SOURCE: Readonly<Record<SyntaxRole, keyof AdeaTheme['ansi']>> = Object.freeze({
|
|
59
81
|
// Magenta is the slot palettes spend on the most distinctive hue they have, and
|
|
@@ -140,6 +162,47 @@ export function syntaxRolesHex(theme: AdeaTheme): Record<SyntaxRole, string> {
|
|
|
140
162
|
) as Record<SyntaxRole, string>
|
|
141
163
|
}
|
|
142
164
|
|
|
165
|
+
/**
|
|
166
|
+
* The hex role set for code editors, where comments and diffs are rendered as
|
|
167
|
+
* content text rather than decorative syntax. The quiet syntax API stays at its
|
|
168
|
+
* palette-selected comment level; this projection explicitly holds every editor
|
|
169
|
+
* role to WCAG AA on the canvas.
|
|
170
|
+
*/
|
|
171
|
+
export function editorRolesHex(theme: AdeaTheme): Record<EditorRole, string> {
|
|
172
|
+
const roles = syntaxRolesHex(theme)
|
|
173
|
+
const background = parseColor(theme.colors.background)
|
|
174
|
+
if (!background) throw new Error(`theme ${theme.id} has no valid editor background`)
|
|
175
|
+
|
|
176
|
+
return Object.fromEntries(
|
|
177
|
+
EDITOR_ROLES.map((role) => {
|
|
178
|
+
const source = parseColor(roles[role])
|
|
179
|
+
if (!source) throw new Error(`theme ${theme.id} has no valid editor.${role}`)
|
|
180
|
+
|
|
181
|
+
const initial = oklchToHex(source)
|
|
182
|
+
const renderedInitial = parseColor(initial)
|
|
183
|
+
if (renderedInitial && contrastRatio(renderedInitial, background) >= 4.5 - 1e-9) {
|
|
184
|
+
return [role, initial]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Repair against the exact role the editor receives. A repair at precisely
|
|
188
|
+
// 4.5:1 in OKLCH can round to a hex value just below that floor, so advance
|
|
189
|
+
// the requested threshold by the smallest measured step until the encoded
|
|
190
|
+
// value itself clears 4.5:1. No source palette value or hue is rewritten.
|
|
191
|
+
for (let margin = 0.001; margin <= 0.05; margin += 0.001) {
|
|
192
|
+
const repaired = repairContrast(source, background, 4.5 + margin)
|
|
193
|
+
if (!repaired.satisfied) continue
|
|
194
|
+
const candidate = oklchToHex(repaired.color)
|
|
195
|
+
const renderedCandidate = parseColor(candidate)
|
|
196
|
+
if (renderedCandidate && contrastRatio(renderedCandidate, background) >= 4.5 - 1e-9) {
|
|
197
|
+
return [role, candidate]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
throw new Error(`cannot encode editor.${role} for ${theme.id} above 4.5:1 contrast`)
|
|
202
|
+
})
|
|
203
|
+
) as Record<EditorRole, string>
|
|
204
|
+
}
|
|
205
|
+
|
|
143
206
|
/**
|
|
144
207
|
* The categorical chart series, derived from the ANSI hues.
|
|
145
208
|
*
|
package/src/index.ts
CHANGED
|
@@ -123,11 +123,12 @@ export type { NormalizationFinding, NormalizedTheme, ThemeSourceSpec } from './n
|
|
|
123
123
|
export { CONTRAST_FLOORS, normalizeTheme } from './normalize.js'
|
|
124
124
|
|
|
125
125
|
/* --- Derived colours --------------------------------------------------- */
|
|
126
|
-
export type { StatusRole, SyntaxRole } from './derive.js'
|
|
126
|
+
export type { EditorRole, StatusRole, SyntaxRole } from './derive.js'
|
|
127
127
|
export {
|
|
128
128
|
CHART_SERIES,
|
|
129
129
|
STATUS_ROLES,
|
|
130
130
|
chartSeries,
|
|
131
|
+
editorRolesHex,
|
|
131
132
|
statusForeground,
|
|
132
133
|
statusForegroundHex,
|
|
133
134
|
syntaxRoles,
|
|
@@ -160,4 +161,11 @@ export { toTailwindTheme } from './adapters/tailwind.js'
|
|
|
160
161
|
export type { ShikiThemeRegistration, ShikiTokenSetting } from './adapters/shiki.js'
|
|
161
162
|
export { toShikiTheme, toShikiThemes } from './adapters/shiki.js'
|
|
162
163
|
|
|
163
|
-
export {
|
|
164
|
+
export type { ShadcnDestructiveProjection } from './adapters/shadcn.js'
|
|
165
|
+
export {
|
|
166
|
+
SHADCN_MAPPING,
|
|
167
|
+
shadcnCss,
|
|
168
|
+
shadcnDestructiveProjection,
|
|
169
|
+
shadcnRoles,
|
|
170
|
+
shadcnVariables,
|
|
171
|
+
} from './adapters/shadcn.js'
|