mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-03 04:23:56 +08:00
update 2026-10-29 11:59:06
This commit is contained in:
1 parent
bc85557d34
commit
e2f86e09f4
5033 files changed
-2043160
No files matched your search
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2025 eamonxg <eamonxiong@gmail.com>
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const outputDir = resolve(
|
||||
import.meta.dirname,
|
||||
"../../htdocs/luci-static/shadcn",
|
||||
);
|
||||
const files = ["main.css", "login.css"];
|
||||
const forbidden = [
|
||||
{
|
||||
label: "token-based color-mix()",
|
||||
pattern: /color-mix\([^)]*var\(--/g,
|
||||
},
|
||||
{
|
||||
label: "relative oklch()",
|
||||
pattern: /oklch\(from/g,
|
||||
},
|
||||
];
|
||||
const failures = [];
|
||||
|
||||
for (const file of files) {
|
||||
const css = await readFile(resolve(outputDir, file), "utf8");
|
||||
|
||||
for (const { label, pattern } of forbidden) {
|
||||
const count = css.match(pattern)?.length ?? 0;
|
||||
if (count > 0) failures.push(`${file}: ${label} × ${count}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.error(`Runtime token color functions found:\n${failures.join("\n")}`);
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log("Built CSS contains no runtime token color functions.");
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2025 eamonxg <eamonxiong@gmail.com>
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import Color from "colorjs.io";
|
||||
import { resolveMode } from "../tokens/resolve.js";
|
||||
|
||||
const MIN_TEXT_CONTRAST = 4.5;
|
||||
const checks = [
|
||||
["muted_foreground", "background"],
|
||||
["sidebar_muted", "sidebar_bg"],
|
||||
];
|
||||
const failures = [];
|
||||
|
||||
for (const mode of ["light", "dark"]) {
|
||||
const tokens = resolveMode(mode);
|
||||
|
||||
for (const [foreground, background] of checks) {
|
||||
const ratio = Color.contrast(
|
||||
new Color(tokens[background]),
|
||||
new Color(tokens[foreground]),
|
||||
"WCAG21",
|
||||
);
|
||||
|
||||
if (ratio < MIN_TEXT_CONTRAST) {
|
||||
failures.push(
|
||||
`${mode}: ${foreground} on ${background} is ${ratio.toFixed(2)}:1`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.error(
|
||||
`Text token contrast must be at least ${MIN_TEXT_CONTRAST}:1:\n${failures.join("\n")}`,
|
||||
);
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log("Text token contrast meets WCAG AA.");
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2025 eamonxg <eamonxiong@gmail.com>
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { alpha, toOklch } from "@eamonxg/luci-theme-tokens/engine";
|
||||
import { block, themeColors } from "@eamonxg/luci-theme-tokens/emit";
|
||||
import { resolveMode } from "../tokens/resolve.js";
|
||||
import { ALPHAS } from "../tokens/spec.js";
|
||||
|
||||
const snake = (s) => s.replace(/-/g, "_");
|
||||
const withAlpha = (oklchStr, pct) => toOklch(alpha(oklchStr, pct / 100));
|
||||
|
||||
function alphaTokens(resolved) {
|
||||
const out = {};
|
||||
for (const [base, list] of Object.entries(ALPHAS)) {
|
||||
const val = resolved[snake(base)];
|
||||
if (val === undefined) throw new Error(`ALPHAS base not resolved: ${base}`);
|
||||
for (const a of list) out[`${base}-a${a}`] = withAlpha(val, a);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const light = resolveMode("light");
|
||||
const dark = resolveMode("dark");
|
||||
const lightA = alphaTokens(light);
|
||||
const darkA = alphaTokens(dark);
|
||||
|
||||
const STRUCTURE = `
|
||||
--font-sans: "Inter Variable", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
|
||||
--radius-base: 0.5rem;
|
||||
|
||||
/* Elevation. Emitted on :root (not just inlined into the shadow-* utilities)
|
||||
so on-demand patches/*.css -- standalone entries that carry no Tailwind
|
||||
helper output -- can reach it as var(--shadow-sm). */
|
||||
--shadow-sm:
|
||||
0 1px 3px 0 oklch(0% 0 0 / 0.1), 0 1px 2px -1px oklch(0% 0 0 / 0.1);
|
||||
`;
|
||||
|
||||
const themeColorsCss = themeColors([
|
||||
...Object.keys(light),
|
||||
...Object.keys(lightA),
|
||||
]);
|
||||
|
||||
// Add aliases for backward compatibility
|
||||
const aliases = [
|
||||
` --color-sidebar-fg: var(--sidebar-foreground);`,
|
||||
` --color-terminal-fg: var(--terminal-foreground);`,
|
||||
].join("\n");
|
||||
|
||||
const THEME = `@theme inline {
|
||||
${themeColorsCss}
|
||||
|
||||
${aliases}
|
||||
|
||||
--font-sans: var(--font-sans);
|
||||
--font-mono: var(--font-mono);
|
||||
|
||||
--shadow-sm: var(--shadow-sm);
|
||||
|
||||
/* Radius ladder driven by a single knob; at 0.5rem it matches the
|
||||
Tailwind default scale (rounded-lg = 0.5rem). Tune --radius-base
|
||||
to scale all corners for custom-radius support. */
|
||||
--radius-sm: calc(var(--radius-base) * 0.5);
|
||||
--radius: calc(var(--radius-base) * 0.5);
|
||||
--radius-md: calc(var(--radius-base) * 0.75);
|
||||
--radius-lg: var(--radius-base);
|
||||
--radius-xl: calc(var(--radius-base) * 1.5);
|
||||
}
|
||||
`;
|
||||
|
||||
const HEADER = `/**
|
||||
* luci-theme-shadcn: design tokens -- GENERATED, DO NOT EDIT.
|
||||
* Run \`pnpm gen:tokens\`. Source: tokens/defaults.js + tokens/spec.js
|
||||
* All color values are flat oklch() literals; no dynamic color functions.
|
||||
* Dark mode overrides must stay after light mode block.
|
||||
*/
|
||||
`;
|
||||
|
||||
const css =
|
||||
HEADER +
|
||||
"\n" +
|
||||
block(":root", light, lightA) +
|
||||
STRUCTURE +
|
||||
"}\n\n" +
|
||||
block('[data-darkmode="true"]', dark, darkA) +
|
||||
"}\n\n" +
|
||||
THEME;
|
||||
|
||||
await writeFile(
|
||||
resolve(import.meta.dirname, "../src/media/_tokens.css"),
|
||||
css,
|
||||
"utf-8",
|
||||
);
|
||||
console.log("gen-tokens: wrote src/media/_tokens.css");
|
||||
Reference in new issue
Block a user