Refresh UI components and showcase; release updated framework packages

This commit is contained in:
Clintchiz committed 2026-09-20 18:13:24 +05:30
1 parent d800228585
commit c77f5e1cec
293 files changed
+22544 -35778

No files matched your search

+10
View File
@@ -27,6 +27,16 @@ Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web fr
## Overview
### Production CSS inlining
`styles.inlineMaxBytes` controls the maximum uncompressed size of the combined
production stylesheet to embed in the document. The default is 4096 bytes; `0`
disables inlining. A measured first-visit optimization can use, for example,
`styles: { inlineMaxBytes: 128 * 1024 }`. Larger limits remove a blocking stylesheet
request but repeat the CSS in each HTML response. Stylesheets containing relative
asset URLs stay external so their URL base does not change. Theme switching and
the separately served stylesheet remain available.
This package owns three server-side concerns that shape every page a WrNexus app renders:
1. **Global stylesheet pipeline** — finds `app/styles/global.css` (or aggregates `app/styles/*.css`), bundles it with Bun's CSS bundler (which resolves `@import`, including from `node_modules`), and produces one stylesheet that is `<link>`ed into every page's `<head>`. Because it is a plain global sheet, it styles server-rendered markup and hydrated client islands identically. A custom `process` hook lets you swap in Tailwind / PostCSS / Sass.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/styles",
"version": "0.8.22",
"version": "0.8.23",
"type": "module",
"main": "src/index.ts",
"exports": {
+2
View File
@@ -39,6 +39,8 @@ export interface StylesConfig {
entry?: string;
/** Include the complete @wrnexus/ui component catalog stylesheet. Default true. */
includeUi?: boolean;
/** Maximum uncompressed production CSS bytes to inline in the document. Default 4096; 0 disables inlining. Larger limits trade repeat HTML bytes for one fewer blocking request. */
inlineMaxBytes?: number;
/**
* Optional custom processor. Return the final CSS string. Use this to run
* Tailwind, PostCSS, Sass, etc. When omitted, the built-in Bun CSS bundler is
+55 -39
View File
@@ -39,6 +39,13 @@ export type ThemeToken =
| `color-on-${"primary" | "secondary"}`
| "radius"
| "radius-sm"
| "radius-md"
| "radius-lg"
| "control-height-sm"
| "control-height"
| "control-height-lg"
| "space-panel"
| "font-size-ui"
| "shadow-1"
| "shadow-2"
| "shadow-3"
@@ -452,16 +459,16 @@ function resolveDefaultAccent(
export const DEFAULT_THEMES: Record<string, ThemeTokens> = {
light: {
"color-scheme": "light",
"color-bg": "#ffffff",
"color-background": "#ffffff",
"color-foreground": "#0b1020",
"color-bg": "#f7f8fa",
"color-background": "#f7f8fa",
"color-foreground": "#20232b",
"color-surface-raised": "#ffffff",
"color-surface-muted": "#eceff6",
"color-surface-soft": "#f1f4f9",
"color-text-muted": "#5a6178",
"color-text-subtle": "#737b91",
"color-border-strong": "#c7cedd",
"color-code-background": "#0b1020",
"color-surface-muted": "#eef0f4",
"color-surface-soft": "#f6f7f9",
"color-text-muted": "#606776",
"color-text-subtle": "#6b7280",
"color-border-strong": "#b9c0cc",
"color-code-background": "#20232b",
"color-code-surface": "#141a30",
"color-code-text": "#e7ecff",
"color-code-muted": "#9aa6d0",
@@ -472,34 +479,41 @@ export const DEFAULT_THEMES: Record<string, ThemeTokens> = {
"space-section": "5rem",
"space-section-sm": "3.5rem",
"container-max": "80rem",
"color-surface": "#f6f7fb",
"color-surface-2": "#eceff6",
"color-text": "#0b1020",
"color-muted": "#5a6178",
"color-border": "#e2e6f0",
"color-surface": "#ffffff",
"color-surface-2": "#eef0f4",
"color-text": "#20232b",
"color-muted": "#606776",
"color-border": "#e1e4ea",
...paletteTokens(THEME_PALETTES.blue, "light"),
radius: "8px",
"radius-sm": "5px",
radius: "10px",
"radius-sm": "6px",
"radius-md": "10px",
"radius-lg": "12px",
"control-height-sm": "2rem",
"control-height": "2.5rem",
"control-height-lg": "2.75rem",
"space-panel": "1.25rem",
"font-size-ui": "0.875rem",
"font-sans": '"Plus Jakarta Sans",ui-sans-serif,system-ui,sans-serif',
"shadow-1": "0 1px 2px rgba(16,24,40,0.06), 0 1px 3px rgba(16,24,40,0.1)",
"shadow-1": "0 1px 3px rgba(16,24,40,0.05)",
"shadow-2": "0 8px 24px rgba(16,24,40,0.10)",
"shadow-3": "0 20px 50px rgba(16,24,40,0.14)",
},
dark: {
"color-scheme": "dark",
"color-bg": "#000000",
"color-background": "#000000",
"color-foreground": "#f5f5f5",
"color-surface-raised": "#111111",
"color-surface-muted": "#181818",
"color-surface-soft": "#141414",
"color-text-muted": "#b3b3b3",
"color-text-subtle": "#8a8a8a",
"color-border-strong": "#ffffff38",
"color-bg": "#101114",
"color-background": "#101114",
"color-foreground": "#f0f1f4",
"color-surface-raised": "#22252d",
"color-surface-muted": "#242730",
"color-surface-soft": "#1c1f26",
"color-text-muted": "#b5bac5",
"color-text-subtle": "#959cab",
"color-border-strong": "#555d6c",
"color-code-background": "#050505",
"color-code-surface": "#101010",
"color-code-text": "#f5f5f5",
"color-code-muted": "#a3a3a3",
"color-code-text": "#f0f1f4",
"color-code-muted": "#a7aeba",
"color-code-border": "#ffffff24",
"shadow-sm": "0 1px 2px rgba(0,0,0,0.28)",
"shadow-md": "0 10px 30px rgba(0,0,0,0.35)",
@@ -507,16 +521,23 @@ export const DEFAULT_THEMES: Record<string, ThemeTokens> = {
"space-section": "5rem",
"space-section-sm": "3.5rem",
"container-max": "80rem",
"color-surface": "#0a0a0a",
"color-surface-2": "#171717",
"color-text": "#f5f5f5",
"color-muted": "#a3a3a3",
"color-border": "#ffffff1f",
"color-surface": "#181a20",
"color-surface-2": "#20232b",
"color-text": "#f0f1f4",
"color-muted": "#a7aeba",
"color-border": "#30343e",
...paletteTokens(THEME_PALETTES.blue, "dark"),
radius: "10px",
"radius-sm": "6px",
"radius-md": "10px",
"radius-lg": "12px",
"control-height-sm": "2rem",
"control-height": "2.5rem",
"control-height-lg": "2.75rem",
"space-panel": "1.25rem",
"font-size-ui": "0.875rem",
"font-sans": '"Plus Jakarta Sans",ui-sans-serif,system-ui,sans-serif',
"shadow-1": "0 1px 2px rgba(0,0,0,0.3), 0 4px 16px rgba(0,0,0,0.35)",
"shadow-1": "0 1px 3px rgba(0,0,0,0.18)",
"shadow-2": "0 10px 30px rgba(0,0,0,0.35)",
"shadow-3": "0 24px 64px rgba(0,0,0,0.45)",
},
@@ -599,11 +620,6 @@ function selectorValue(value: string): string {
function globalThemeCss(): string {
return (
'\nhtml,body{font-family:var(--wrn-font-sans,"Plus Jakarta Sans",ui-sans-serif,system-ui,sans-serif);}\n' +
":root{--wrn-radius-sm:0.55rem;--wrn-radius-md:0.9rem;--wrn-radius-lg:1.35rem;" +
"--wrn-shadow-1:0 1px 2px color-mix(in srgb, black 22%, transparent)," +
"0 10px 30px color-mix(in srgb, black 14%, transparent);" +
"--wrn-shadow-2:0 10px 30px color-mix(in srgb, black 18%, transparent);" +
"--wrn-shadow-3:0 24px 64px color-mix(in srgb, black 24%, transparent);}\n" +
"wrn-slot{display:contents;}\n" +
"[data-for]{display:none !important;}\n"
);
+17 -4
View File
@@ -56,15 +56,15 @@ test("resolveThemeConfig merges user tokens over built-in light/dark", () => {
expect(t.themes.dark["color-bg"]).toBeDefined(); // built-in kept
});
test("built-in themes use Plus Jakarta Sans and neutral black dark surfaces", () => {
test("built-in themes use Plus Jakarta Sans and layered charcoal dark surfaces", () => {
const t = resolveThemeConfig();
expect(t.themes.light["font-sans"]).toBe(
'"Plus Jakarta Sans",ui-sans-serif,system-ui,sans-serif',
);
expect(t.themes.dark["font-sans"]).toBe('"Plus Jakarta Sans",ui-sans-serif,system-ui,sans-serif');
expect(t.themes.dark["color-bg"]).toBe("#000000");
expect(t.themes.dark["color-surface"]).toBe("#0a0a0a");
expect(t.themes.dark["color-surface-2"]).toBe("#171717");
expect(t.themes.dark["color-bg"]).toBe("#101114");
expect(t.themes.dark["color-surface"]).toBe("#181a20");
expect(t.themes.dark["color-surface-2"]).toBe("#20232b");
});
test("resolveThemeName validates against configured names", () => {
@@ -105,3 +105,16 @@ test("renderThemeRuntime bakes the theme names for cycling", () => {
expect(js).toContain(JSON.stringify(t.names));
expect(js).toContain('addEventListener("wrnexus:navigated"');
});
test("active stylesheets preserve configured geometry and elevation without a later reset", () => {
const theme = resolveThemeConfig({
themes: { dark: { "radius-sm": "3px", "radius-lg": "9px", "shadow-1": "none" } },
});
const css = renderActiveThemeCss(theme, "dark");
expect(css.match(/--wrn-radius-sm:/g)).toHaveLength(1);
expect(css.match(/--wrn-radius-lg:/g)).toHaveLength(1);
expect(css.match(/--wrn-shadow-1:/g)).toHaveLength(1);
expect(css).toContain("--wrn-radius-sm:3px");
expect(css).toContain("--wrn-radius-lg:9px");
expect(css).toContain("--wrn-shadow-1:none");
});