@usetheo/ui 0.3.0-next.0 → 0.5.0-next.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.
@@ -0,0 +1,31 @@
1
+ import { Config } from 'tailwindcss';
2
+
3
+ /**
4
+ * `@usetheo/ui/preset` — Tailwind v4 preset for zero-config consumers.
5
+ *
6
+ * Default-export a `Partial<Config>` mirroring the design tokens shipped
7
+ * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the
8
+ * library's published artifact tree so consumers' Tailwind builds emit
9
+ * the utilities used by `@usetheo/ui` components.
10
+ *
11
+ * The token surface is delegated to `./styles/tailwind-preset.ts` (the
12
+ * existing source of truth used by the local Ladle dev surface and the
13
+ * shadcn registry). This subpath simply wraps it with `content` and
14
+ * preserves the same shape, so the v3 registry preset and the v4 import
15
+ * preset stay byte-for-byte aligned and impossible to drift.
16
+ *
17
+ * Consumer usage:
18
+ *
19
+ * // tailwind.config.ts
20
+ * import preset from "@usetheo/ui/preset";
21
+ * export default {
22
+ * presets: [preset],
23
+ * content: ["./app/**\/*.{ts,tsx}"],
24
+ * };
25
+ *
26
+ * See RFC 0008.
27
+ */
28
+
29
+ declare const preset: Partial<Config>;
30
+
31
+ export { preset as default };
package/dist/preset.js ADDED
@@ -0,0 +1,159 @@
1
+ import animate from 'tailwindcss-animate';
2
+
3
+ // src/styles/tailwind-preset.ts
4
+ var hsl = (token) => `hsl(var(${token}) / <alpha-value>)`;
5
+ var theoUIPreset = {
6
+ theme: {
7
+ container: {
8
+ center: true,
9
+ padding: "1rem",
10
+ screens: {
11
+ "2xl": "1280px"
12
+ }
13
+ },
14
+ extend: {
15
+ colors: {
16
+ background: hsl("--background"),
17
+ foreground: hsl("--foreground"),
18
+ card: {
19
+ DEFAULT: hsl("--card"),
20
+ foreground: hsl("--card-foreground")
21
+ },
22
+ popover: {
23
+ DEFAULT: hsl("--popover"),
24
+ foreground: hsl("--popover-foreground")
25
+ },
26
+ primary: {
27
+ DEFAULT: hsl("--primary"),
28
+ deep: hsl("--primary-deep"),
29
+ glow: hsl("--primary-glow"),
30
+ foreground: hsl("--primary-foreground")
31
+ },
32
+ secondary: {
33
+ DEFAULT: hsl("--secondary"),
34
+ foreground: hsl("--secondary-foreground")
35
+ },
36
+ accent: {
37
+ DEFAULT: hsl("--accent"),
38
+ deep: hsl("--accent-deep"),
39
+ foreground: hsl("--accent-foreground")
40
+ },
41
+ muted: {
42
+ DEFAULT: hsl("--muted"),
43
+ foreground: hsl("--muted-foreground")
44
+ },
45
+ success: {
46
+ DEFAULT: hsl("--success"),
47
+ foreground: hsl("--success-foreground")
48
+ },
49
+ warning: {
50
+ DEFAULT: hsl("--warning"),
51
+ foreground: hsl("--warning-foreground")
52
+ },
53
+ destructive: {
54
+ DEFAULT: hsl("--destructive"),
55
+ foreground: hsl("--destructive-foreground")
56
+ },
57
+ info: {
58
+ DEFAULT: hsl("--info"),
59
+ foreground: hsl("--info-foreground")
60
+ },
61
+ border: hsl("--border"),
62
+ input: hsl("--input"),
63
+ ring: hsl("--ring")
64
+ },
65
+ fontFamily: {
66
+ display: "var(--font-display)",
67
+ sans: "var(--font-body)",
68
+ mono: "var(--font-mono)"
69
+ },
70
+ /* Geist-inspired Violet Forge typescale.
71
+ *
72
+ * Three strict weights: 400 (body), 500 (UI), 600 (display/headings).
73
+ * Letter-spacing scales with size — aggressive negative on display.
74
+ * Mirrors the Vercel/Geist vocabulary while keeping Theo's identity.
75
+ */
76
+ fontSize: {
77
+ // Display tier — aggressive compression, content-led headlines
78
+ "display-2xl": ["64px", { lineHeight: "1", letterSpacing: "-0.0464em", fontWeight: "600" }],
79
+ "display-xl": ["48px", { lineHeight: "1.05", letterSpacing: "-0.05em", fontWeight: "600" }],
80
+ "display-lg": ["40px", { lineHeight: "1.1", letterSpacing: "-0.05em", fontWeight: "600" }],
81
+ "display-md": ["32px", { lineHeight: "1.2", letterSpacing: "-0.04em", fontWeight: "600" }],
82
+ headline: ["28px", { lineHeight: "1.25", letterSpacing: "-0.035em", fontWeight: "600" }],
83
+ // Title tier — section / card heads
84
+ "title-lg": ["24px", { lineHeight: "1.33", letterSpacing: "-0.04em", fontWeight: "600" }],
85
+ "title-md": ["20px", { lineHeight: "1.4", letterSpacing: "-0.03em", fontWeight: "600" }],
86
+ // Body tier — FAANG-density realignment 2026-05-22: body-md is the
87
+ // industry-standard 14px (shadcn / Vercel Geist / Linear / Stripe /
88
+ // Mantine). The previous 15px was idiosyncratic. body-sm (14px label
89
+ // weight) remains separate via its line-height / weight signature.
90
+ "body-lg": ["18px", { lineHeight: "1.56", letterSpacing: "-0.01em", fontWeight: "400" }],
91
+ "body-md": ["14px", { lineHeight: "1.43", letterSpacing: "0", fontWeight: "400" }],
92
+ "body-sm": ["13px", { lineHeight: "1.46", fontWeight: "400" }],
93
+ // Label tier — used on buttons, nav, secondary actions
94
+ label: ["14px", { lineHeight: "1.43", fontWeight: "500" }],
95
+ "label-caps": ["12px", { lineHeight: "1.33", letterSpacing: "0.04em", fontWeight: "500" }],
96
+ // Mono — code surfaces, technical labels
97
+ "code-md": ["14px", { lineHeight: "1.5", fontWeight: "400" }],
98
+ "code-sm": ["13px", { lineHeight: "1.54", fontWeight: "500" }]
99
+ },
100
+ borderRadius: {
101
+ none: "var(--radius-none)",
102
+ sm: "var(--radius-sm)",
103
+ md: "var(--radius-md)",
104
+ lg: "var(--radius-lg)",
105
+ xl: "var(--radius-xl)",
106
+ "2xl": "var(--radius-2xl)",
107
+ full: "var(--radius-full)"
108
+ },
109
+ boxShadow: {
110
+ sm: "var(--shadow-sm)",
111
+ md: "var(--shadow-md)",
112
+ lg: "var(--shadow-lg)",
113
+ glow: "var(--shadow-glow)",
114
+ "glow-strong": "var(--shadow-glow-strong)"
115
+ },
116
+ transitionTimingFunction: {
117
+ "out-soft": "var(--ease-out-soft)",
118
+ snap: "var(--ease-snap)"
119
+ },
120
+ transitionDuration: {
121
+ fast: "var(--duration-fast)",
122
+ base: "var(--duration-base)",
123
+ slow: "var(--duration-slow)"
124
+ },
125
+ keyframes: {
126
+ "fade-in-up": {
127
+ "0%": { opacity: "0", transform: "translateY(8px)" },
128
+ "100%": { opacity: "1", transform: "translateY(0)" }
129
+ },
130
+ "pulse-glow": {
131
+ "0%, 100%": { boxShadow: "0 0 0 0 hsl(var(--primary) / 0.5)" },
132
+ "50%": { boxShadow: "0 0 0 8px hsl(var(--primary) / 0)" }
133
+ }
134
+ },
135
+ animation: {
136
+ "fade-in-up": "fade-in-up var(--duration-base) var(--ease-out-soft) both",
137
+ "pulse-glow": "pulse-glow 1.5s var(--ease-in-out) infinite"
138
+ }
139
+ }
140
+ },
141
+ plugins: [animate]
142
+ };
143
+
144
+ // src/preset.ts
145
+ var LIBRARY_CONTENT_GLOBS = [
146
+ // Resolved relative to the consumer's `tailwind.config.{ts,js}`.
147
+ "./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}",
148
+ // Yarn PnP / pnpm hoist fallback — Tailwind's globbing tolerates both.
149
+ "./node_modules/@usetheo/ui/dist/**/*.{ts,tsx}"
150
+ ];
151
+ var preset = {
152
+ ...theoUIPreset,
153
+ content: LIBRARY_CONTENT_GLOBS
154
+ };
155
+ var preset_default = preset;
156
+
157
+ export { preset_default as default };
158
+ //# sourceMappingURL=preset.js.map
159
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles/tailwind-preset.ts","../src/preset.ts"],"names":[],"mappings":"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","file":"preset.js","sourcesContent":["/**\n * Theo UI Tailwind preset — Violet Forge identity.\n *\n * Single source of truth for the design system's utility-level tokens:\n * - colors mapped to CSS variables (HSL split via `hsl(var(--x) / <alpha>)`)\n * - Geist-inspired typescale (display / title / body / label / code tiers)\n * - radii, shadows, motion timing & duration, keyframes\n * - tailwindcss-animate plugin\n *\n * Consumed by:\n * - `tailwind.config.ts` (this repo) via `presets: [theoUIPreset]`\n * - registry/r/tailwind-preset.json (shipped to consumers via shadcn CLI)\n *\n * Consumers integrate as:\n *\n * import type { Config } from \"tailwindcss\";\n * import { theoUIPreset } from \"./styles/tailwind-preset\";\n *\n * export default {\n * darkMode: \"class\",\n * content: [\"./src/**\\/*.{ts,tsx}\"],\n * presets: [theoUIPreset],\n * } satisfies Config;\n *\n * Note: `darkMode` and `content` are NOT in the preset — they are consumer\n * decisions. The preset only contains `theme.extend.*` and `plugins`.\n */\n\nimport type { Config } from \"tailwindcss\";\nimport animate from \"tailwindcss-animate\";\n\nconst hsl = (token: string) => `hsl(var(${token}) / <alpha-value>)`;\n\nexport const theoUIPreset: Partial<Config> = {\n theme: {\n container: {\n center: true,\n padding: \"1rem\",\n screens: {\n \"2xl\": \"1280px\",\n },\n },\n extend: {\n colors: {\n background: hsl(\"--background\"),\n foreground: hsl(\"--foreground\"),\n card: {\n DEFAULT: hsl(\"--card\"),\n foreground: hsl(\"--card-foreground\"),\n },\n popover: {\n DEFAULT: hsl(\"--popover\"),\n foreground: hsl(\"--popover-foreground\"),\n },\n primary: {\n DEFAULT: hsl(\"--primary\"),\n deep: hsl(\"--primary-deep\"),\n glow: hsl(\"--primary-glow\"),\n foreground: hsl(\"--primary-foreground\"),\n },\n secondary: {\n DEFAULT: hsl(\"--secondary\"),\n foreground: hsl(\"--secondary-foreground\"),\n },\n accent: {\n DEFAULT: hsl(\"--accent\"),\n deep: hsl(\"--accent-deep\"),\n foreground: hsl(\"--accent-foreground\"),\n },\n muted: {\n DEFAULT: hsl(\"--muted\"),\n foreground: hsl(\"--muted-foreground\"),\n },\n success: {\n DEFAULT: hsl(\"--success\"),\n foreground: hsl(\"--success-foreground\"),\n },\n warning: {\n DEFAULT: hsl(\"--warning\"),\n foreground: hsl(\"--warning-foreground\"),\n },\n destructive: {\n DEFAULT: hsl(\"--destructive\"),\n foreground: hsl(\"--destructive-foreground\"),\n },\n info: {\n DEFAULT: hsl(\"--info\"),\n foreground: hsl(\"--info-foreground\"),\n },\n border: hsl(\"--border\"),\n input: hsl(\"--input\"),\n ring: hsl(\"--ring\"),\n },\n fontFamily: {\n display: \"var(--font-display)\",\n sans: \"var(--font-body)\",\n mono: \"var(--font-mono)\",\n },\n /* Geist-inspired Violet Forge typescale.\n *\n * Three strict weights: 400 (body), 500 (UI), 600 (display/headings).\n * Letter-spacing scales with size — aggressive negative on display.\n * Mirrors the Vercel/Geist vocabulary while keeping Theo's identity.\n */\n fontSize: {\n // Display tier — aggressive compression, content-led headlines\n \"display-2xl\": [\"64px\", { lineHeight: \"1\", letterSpacing: \"-0.0464em\", fontWeight: \"600\" }],\n \"display-xl\": [\"48px\", { lineHeight: \"1.05\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-lg\": [\"40px\", { lineHeight: \"1.1\", letterSpacing: \"-0.05em\", fontWeight: \"600\" }],\n \"display-md\": [\"32px\", { lineHeight: \"1.2\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n headline: [\"28px\", { lineHeight: \"1.25\", letterSpacing: \"-0.035em\", fontWeight: \"600\" }],\n // Title tier — section / card heads\n \"title-lg\": [\"24px\", { lineHeight: \"1.33\", letterSpacing: \"-0.04em\", fontWeight: \"600\" }],\n \"title-md\": [\"20px\", { lineHeight: \"1.4\", letterSpacing: \"-0.03em\", fontWeight: \"600\" }],\n // Body tier — FAANG-density realignment 2026-05-22: body-md is the\n // industry-standard 14px (shadcn / Vercel Geist / Linear / Stripe /\n // Mantine). The previous 15px was idiosyncratic. body-sm (14px label\n // weight) remains separate via its line-height / weight signature.\n \"body-lg\": [\"18px\", { lineHeight: \"1.56\", letterSpacing: \"-0.01em\", fontWeight: \"400\" }],\n \"body-md\": [\"14px\", { lineHeight: \"1.43\", letterSpacing: \"0\", fontWeight: \"400\" }],\n \"body-sm\": [\"13px\", { lineHeight: \"1.46\", fontWeight: \"400\" }],\n // Label tier — used on buttons, nav, secondary actions\n label: [\"14px\", { lineHeight: \"1.43\", fontWeight: \"500\" }],\n \"label-caps\": [\"12px\", { lineHeight: \"1.33\", letterSpacing: \"0.04em\", fontWeight: \"500\" }],\n // Mono — code surfaces, technical labels\n \"code-md\": [\"14px\", { lineHeight: \"1.5\", fontWeight: \"400\" }],\n \"code-sm\": [\"13px\", { lineHeight: \"1.54\", fontWeight: \"500\" }],\n },\n borderRadius: {\n none: \"var(--radius-none)\",\n sm: \"var(--radius-sm)\",\n md: \"var(--radius-md)\",\n lg: \"var(--radius-lg)\",\n xl: \"var(--radius-xl)\",\n \"2xl\": \"var(--radius-2xl)\",\n full: \"var(--radius-full)\",\n },\n boxShadow: {\n sm: \"var(--shadow-sm)\",\n md: \"var(--shadow-md)\",\n lg: \"var(--shadow-lg)\",\n glow: \"var(--shadow-glow)\",\n \"glow-strong\": \"var(--shadow-glow-strong)\",\n },\n transitionTimingFunction: {\n \"out-soft\": \"var(--ease-out-soft)\",\n snap: \"var(--ease-snap)\",\n },\n transitionDuration: {\n fast: \"var(--duration-fast)\",\n base: \"var(--duration-base)\",\n slow: \"var(--duration-slow)\",\n },\n keyframes: {\n \"fade-in-up\": {\n \"0%\": { opacity: \"0\", transform: \"translateY(8px)\" },\n \"100%\": { opacity: \"1\", transform: \"translateY(0)\" },\n },\n \"pulse-glow\": {\n \"0%, 100%\": { boxShadow: \"0 0 0 0 hsl(var(--primary) / 0.5)\" },\n \"50%\": { boxShadow: \"0 0 0 8px hsl(var(--primary) / 0)\" },\n },\n },\n animation: {\n \"fade-in-up\": \"fade-in-up var(--duration-base) var(--ease-out-soft) both\",\n \"pulse-glow\": \"pulse-glow 1.5s var(--ease-in-out) infinite\",\n },\n },\n },\n plugins: [animate],\n};\n","/**\n * `@usetheo/ui/preset` — Tailwind v4 preset for zero-config consumers.\n *\n * Default-export a `Partial<Config>` mirroring the design tokens shipped\n * in `@usetheo/ui/tokens.css`. Adds a `content` field covering the\n * library's published artifact tree so consumers' Tailwind builds emit\n * the utilities used by `@usetheo/ui` components.\n *\n * The token surface is delegated to `./styles/tailwind-preset.ts` (the\n * existing source of truth used by the local Ladle dev surface and the\n * shadcn registry). This subpath simply wraps it with `content` and\n * preserves the same shape, so the v3 registry preset and the v4 import\n * preset stay byte-for-byte aligned and impossible to drift.\n *\n * Consumer usage:\n *\n * // tailwind.config.ts\n * import preset from \"@usetheo/ui/preset\";\n * export default {\n * presets: [preset],\n * content: [\"./app/**\\/*.{ts,tsx}\"],\n * };\n *\n * See RFC 0008.\n */\nimport type { Config } from \"tailwindcss\";\nimport { theoUIPreset } from \"./styles/tailwind-preset.js\";\n\nconst LIBRARY_CONTENT_GLOBS: string[] = [\n // Resolved relative to the consumer's `tailwind.config.{ts,js}`.\n \"./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}\",\n // Yarn PnP / pnpm hoist fallback — Tailwind's globbing tolerates both.\n \"./node_modules/@usetheo/ui/dist/**/*.{ts,tsx}\",\n];\n\nconst preset: Partial<Config> = {\n ...theoUIPreset,\n content: LIBRARY_CONTENT_GLOBS,\n};\n\nexport default preset;\n"]}
@@ -0,0 +1,29 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ /**
4
+ * `@usetheo/ui/vite-plugin` — auto-wire Tailwind v4 for consumers.
5
+ *
6
+ * Default export is a factory returning ONE Vite Plugin. Internally:
7
+ * 1. chains `@tailwindcss/vite` v4 via the `config()` hook when resolvable
8
+ * and `opts.tailwind !== false`,
9
+ * 2. exposes a virtual module `virtual:@usetheo/ui/library-sources.css`
10
+ * whose contents register `@source` directives covering the library's
11
+ * published files, so consumer-side Tailwind scans `@usetheo/ui` JSX
12
+ * and emits its utility classes,
13
+ * 3. degrades gracefully via `console.warn` (never throws) when
14
+ * `@tailwindcss/vite` is not installed — the surface stays usable in
15
+ * CSS-only mode via the pre-built `@usetheo/ui/styles.css` subpath.
16
+ *
17
+ * This is the cross-repo contract TheoKit's `integrateUseTheoUI()` probes
18
+ * for. See `docs/rfcs/0008-vite-plugin-and-preset.md`.
19
+ */
20
+
21
+ interface UseTheoUIPluginOptions {
22
+ /** Disable Tailwind v4 auto-chain. Default: `true`. */
23
+ tailwind?: boolean;
24
+ /** Extra `@source` globs merged into the library defaults. */
25
+ contentExtra?: string[];
26
+ }
27
+ declare function useTheoUIVite(opts?: UseTheoUIPluginOptions): Plugin;
28
+
29
+ export { type UseTheoUIPluginOptions, useTheoUIVite as default };
@@ -0,0 +1,72 @@
1
+ // src/vite-plugin.ts
2
+ var PLUGIN_NAME = "@usetheo/ui/vite-plugin";
3
+ var VIRTUAL_ID = "virtual:@usetheo/ui/library-sources.css";
4
+ var RESOLVED_VIRTUAL_ID = `\0${VIRTUAL_ID}`;
5
+ function buildLibrarySourcesCss(extra = []) {
6
+ const defaults = [
7
+ '"../node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}"',
8
+ '"./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}"'
9
+ ];
10
+ const all = [...defaults, ...extra.map((g) => JSON.stringify(g))];
11
+ return `${all.map((src) => `@source ${src};`).join("\n")}
12
+ `;
13
+ }
14
+ function useTheoUIVite(opts = {}) {
15
+ const wantsTailwind = opts.tailwind !== false;
16
+ const extra = opts.contentExtra ?? [];
17
+ let warned = false;
18
+ const warnMissingPeer = () => {
19
+ if (warned) return;
20
+ warned = true;
21
+ console.warn(
22
+ `[${PLUGIN_NAME}] @tailwindcss/vite was not resolvable; falling back to CSS-only mode. Install \`@tailwindcss/vite@^4\` to get the utility-driven design tokens, or import \`@usetheo/ui/styles.css\` directly for the pre-built surface.`
23
+ );
24
+ };
25
+ return {
26
+ name: PLUGIN_NAME,
27
+ // Vite's typing for `config()` since 5.x explicitly omits `plugins` from
28
+ // the allowed return shape to nudge authors toward `Plugin[]` factories.
29
+ // The runtime still honors `{ plugins }` merge, and the TheoKit contract
30
+ // requires ONE Plugin object (so we can't return `Plugin[]` here).
31
+ // The cast keeps the public surface honest and the type-checker quiet.
32
+ async config(_userConfig, _env) {
33
+ if (!wantsTailwind) {
34
+ return void 0;
35
+ }
36
+ try {
37
+ const specifier = "@tailwindcss/vite";
38
+ const mod = await import(
39
+ /* @vite-ignore */
40
+ specifier
41
+ );
42
+ const factory = mod.default;
43
+ if (typeof factory !== "function") {
44
+ warnMissingPeer();
45
+ return void 0;
46
+ }
47
+ const tw = factory();
48
+ const tailwindPlugins = Array.isArray(tw) ? tw : [tw];
49
+ return { plugins: tailwindPlugins };
50
+ } catch {
51
+ warnMissingPeer();
52
+ return void 0;
53
+ }
54
+ },
55
+ resolveId(id) {
56
+ if (id === VIRTUAL_ID) {
57
+ return RESOLVED_VIRTUAL_ID;
58
+ }
59
+ return void 0;
60
+ },
61
+ load(id) {
62
+ if (id === RESOLVED_VIRTUAL_ID) {
63
+ return buildLibrarySourcesCss(extra);
64
+ }
65
+ return void 0;
66
+ }
67
+ };
68
+ }
69
+
70
+ export { useTheoUIVite as default };
71
+ //# sourceMappingURL=vite-plugin.js.map
72
+ //# sourceMappingURL=vite-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vite-plugin.ts"],"names":[],"mappings":";AA0BA,IAAM,WAAA,GAAc,yBAAA;AACpB,IAAM,UAAA,GAAa,yCAAA;AACnB,IAAM,mBAAA,GAAsB,KAAK,UAAU,CAAA,CAAA;AAE3C,SAAS,sBAAA,CAAuB,KAAA,GAAkB,EAAC,EAAW;AAK5D,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,sDAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,QAAA,EAAU,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAC,CAAA;AAChE,EAAA,OAAO,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,CAAC,GAAA,KAAQ,CAAA,QAAA,EAAW,GAAG,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;AAAA,CAAA;AAC1D;AAEe,SAAR,aAAA,CAA+B,IAAA,GAA+B,EAAC,EAAW;AAC/E,EAAA,MAAM,aAAA,GAAgB,KAAK,QAAA,KAAa,KAAA;AACxC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,IAAgB,EAAC;AAEpC,EAAA,IAAI,MAAA,GAAS,KAAA;AACb,EAAA,MAAM,kBAAkB,MAAY;AAClC,IAAA,IAAI,MAAA,EAAQ;AACZ,IAAA,MAAA,GAAS,IAAA;AAET,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,IAAI,WAAW,CAAA,yNAAA;AAAA,KACjB;AAAA,EACF,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAON,MAAM,MAAA,CAAO,WAAA,EAAa,IAAA,EAAwD;AAChF,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,OAAO,MAAA;AAAA,MACT;AAEA,MAAA,IAAI;AAKF,QAAA,MAAM,SAAA,GAAY,mBAAA;AAClB,QAAA,MAAM,MAAM,MAAM;AAAA;AAAA,UAA0B;AAAA,SAAA;AAC5C,QAAA,MAAM,UAAW,GAAA,CAA8B,OAAA;AAC/C,QAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,UAAA,eAAA,EAAgB;AAChB,UAAA,OAAO,KAAA,CAAA;AAAA,QACT;AACA,QAAA,MAAM,KAAM,OAAA,EAAoC;AAChD,QAAA,MAAM,kBAAkB,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,GAAI,EAAA,GAAK,CAAC,EAAE,CAAA;AACpD,QAAA,OAAO,EAAE,SAAS,eAAA,EAAgB;AAAA,MACpC,CAAA,CAAA,MAAQ;AACN,QAAA,eAAA,EAAgB;AAChB,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IAEA,UAAU,EAAA,EAAI;AACZ,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,OAAO,mBAAA;AAAA,MACT;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,KAAK,EAAA,EAAI;AACP,MAAA,IAAI,OAAO,mBAAA,EAAqB;AAC9B,QAAA,OAAO,uBAAuB,KAAK,CAAA;AAAA,MACrC;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AACF","file":"vite-plugin.js","sourcesContent":["/**\n * `@usetheo/ui/vite-plugin` — auto-wire Tailwind v4 for consumers.\n *\n * Default export is a factory returning ONE Vite Plugin. Internally:\n * 1. chains `@tailwindcss/vite` v4 via the `config()` hook when resolvable\n * and `opts.tailwind !== false`,\n * 2. exposes a virtual module `virtual:@usetheo/ui/library-sources.css`\n * whose contents register `@source` directives covering the library's\n * published files, so consumer-side Tailwind scans `@usetheo/ui` JSX\n * and emits its utility classes,\n * 3. degrades gracefully via `console.warn` (never throws) when\n * `@tailwindcss/vite` is not installed — the surface stays usable in\n * CSS-only mode via the pre-built `@usetheo/ui/styles.css` subpath.\n *\n * This is the cross-repo contract TheoKit's `integrateUseTheoUI()` probes\n * for. See `docs/rfcs/0008-vite-plugin-and-preset.md`.\n */\nimport type { Plugin, UserConfig } from \"vite\";\n\nexport interface UseTheoUIPluginOptions {\n /** Disable Tailwind v4 auto-chain. Default: `true`. */\n tailwind?: boolean;\n /** Extra `@source` globs merged into the library defaults. */\n contentExtra?: string[];\n}\n\nconst PLUGIN_NAME = \"@usetheo/ui/vite-plugin\";\nconst VIRTUAL_ID = \"virtual:@usetheo/ui/library-sources.css\";\nconst RESOLVED_VIRTUAL_ID = `\\0${VIRTUAL_ID}`;\n\nfunction buildLibrarySourcesCss(extra: string[] = []): string {\n // `@source` paths are resolved relative to the importing CSS file in\n // Tailwind v4. The library defaults below cover the published artifact\n // tree under the consumer's `node_modules/@usetheo/ui/dist/`. Extra globs\n // are appended verbatim — consumers can register additional roots.\n const defaults = [\n '\"../node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}\"',\n '\"./node_modules/@usetheo/ui/dist/**/*.{js,mjs,cjs}\"',\n ];\n const all = [...defaults, ...extra.map((g) => JSON.stringify(g))];\n return `${all.map((src) => `@source ${src};`).join(\"\\n\")}\\n`;\n}\n\nexport default function useTheoUIVite(opts: UseTheoUIPluginOptions = {}): Plugin {\n const wantsTailwind = opts.tailwind !== false;\n const extra = opts.contentExtra ?? [];\n\n let warned = false;\n const warnMissingPeer = (): void => {\n if (warned) return;\n warned = true;\n // biome-ignore lint/suspicious/noConsole: TheoKit cross-repo contract requires `console.warn` (not throw) when the optional `@tailwindcss/vite` peer is missing. See RFC 0008 §3 D1.\n console.warn(\n `[${PLUGIN_NAME}] @tailwindcss/vite was not resolvable; falling back to CSS-only mode. Install \\`@tailwindcss/vite@^4\\` to get the utility-driven design tokens, or import \\`@usetheo/ui/styles.css\\` directly for the pre-built surface.`,\n );\n };\n\n return {\n name: PLUGIN_NAME,\n\n // Vite's typing for `config()` since 5.x explicitly omits `plugins` from\n // the allowed return shape to nudge authors toward `Plugin[]` factories.\n // The runtime still honors `{ plugins }` merge, and the TheoKit contract\n // requires ONE Plugin object (so we can't return `Plugin[]` here).\n // The cast keeps the public surface honest and the type-checker quiet.\n async config(_userConfig, _env): Promise<Omit<UserConfig, \"plugins\"> | undefined> {\n if (!wantsTailwind) {\n return undefined;\n }\n\n try {\n // Dynamic import keeps `@tailwindcss/vite` as an OPTIONAL peer. The\n // specifier is held in a variable so Vite's import-analysis pass\n // leaves it alone — at runtime the consumer's resolver does the\n // actual resolution. Resolution failure must not crash the build.\n const specifier = \"@tailwindcss/vite\";\n const mod = await import(/* @vite-ignore */ specifier);\n const factory = (mod as { default?: unknown }).default;\n if (typeof factory !== \"function\") {\n warnMissingPeer();\n return undefined;\n }\n const tw = (factory as () => Plugin | Plugin[])();\n const tailwindPlugins = Array.isArray(tw) ? tw : [tw];\n return { plugins: tailwindPlugins } as unknown as Omit<UserConfig, \"plugins\">;\n } catch {\n warnMissingPeer();\n return undefined;\n }\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n return undefined;\n },\n\n load(id) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return buildLibrarySourcesCss(extra);\n }\n return undefined;\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usetheo/ui",
3
- "version": "0.3.0-next.0",
3
+ "version": "0.5.0-next.0",
4
4
  "description": "Theo UI — framework-agnostic React component library with the Violet Forge design system. Focused on AI-agent interfaces, cloud dashboards, and developer-tooling surfaces.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -439,6 +439,14 @@
439
439
  "./slide-deck": {
440
440
  "types": "./dist/slide-deck/index.d.ts",
441
441
  "import": "./dist/slide-deck/index.js"
442
+ },
443
+ "./vite-plugin": {
444
+ "types": "./dist/vite-plugin.d.ts",
445
+ "import": "./dist/vite-plugin.js"
446
+ },
447
+ "./preset": {
448
+ "types": "./dist/preset.d.ts",
449
+ "import": "./dist/preset.js"
442
450
  }
443
451
  },
444
452
  "files": ["dist", "registry/r", "registry/index.json", "LICENSE", "CHANGELOG.md"],
@@ -477,6 +485,7 @@
477
485
  "quality:gates:fast": "pnpm format:check && pnpm lint:ci && pnpm typecheck && pnpm registry:build && pnpm registry:validate && pnpm quality:structure"
478
486
  },
479
487
  "peerDependencies": {
488
+ "@tailwindcss/vite": "^4.0.0",
480
489
  "hast-util-from-html": "^2.0.0",
481
490
  "hast-util-sanitize": "^5.0.0",
482
491
  "hast-util-to-jsx-runtime": "^2.0.0",
@@ -493,8 +502,10 @@
493
502
  "react-dom": ">=18.2.0 <20",
494
503
  "roughjs": "^4.6.0",
495
504
  "shiki": "^1.0.0",
505
+ "tailwindcss": "^4.0.0",
496
506
  "unist-util-visit": "^5.0.0",
497
507
  "unist-util-visit-parents": "^6.0.0",
508
+ "vite": "^6.0.0 || ^7.0.0",
498
509
  "yaml": "^2.0.0"
499
510
  },
500
511
  "peerDependenciesMeta": {
@@ -548,6 +559,15 @@
548
559
  },
549
560
  "mermaid": {
550
561
  "optional": true
562
+ },
563
+ "@tailwindcss/vite": {
564
+ "optional": true
565
+ },
566
+ "tailwindcss": {
567
+ "optional": true
568
+ },
569
+ "vite": {
570
+ "optional": true
551
571
  }
552
572
  },
553
573
  "dependencies": {
@@ -29,7 +29,7 @@
29
29
  "path": "themes/classic-paper.ts",
30
30
  "type": "registry:lib",
31
31
  "target": "themes/classic-paper.ts",
32
- "content": "import type { Theme } from \"@/themes/types\";\n\n/**\n * Classic Paper — light-primary with deep-navy dark mirror; Inter + JetBrains Mono.\n *\n * Identity: warm paper background, deep navy foreground, indigo primary\n * (closer to traditional dashboard SaaS), Inter throughout. Maximizes\n * legibility and familiarity — use when reading endurance > differentiation.\n *\n * Provides a full `dark` palette mirror so consumers toggling `.dark` still\n * get a coherent surface (it is not \"light-only\" by accident).\n */\nexport const classicPaper: Theme = {\n name: \"classic-paper\",\n label: \"Classic Paper\",\n description: \"Inter + paper background. Maximum legibility, conservative.\",\n fonts: {\n display: '\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n body: '\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n mono: '\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace',\n },\n fontUrls: [\n \"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap\",\n ],\n light: {\n background: \"36 30% 98%\",\n foreground: \"222 47% 11%\",\n card: \"0 0% 100%\",\n \"card-foreground\": \"222 47% 11%\",\n popover: \"0 0% 100%\",\n \"popover-foreground\": \"222 47% 11%\",\n primary: \"221 83% 53%\",\n \"primary-deep\": \"224 76% 38%\",\n \"primary-glow\": \"217 91% 70%\",\n \"primary-foreground\": \"0 0% 100%\",\n secondary: \"210 40% 96%\",\n \"secondary-foreground\": \"222 47% 11%\",\n accent: \"37 92% 50%\",\n \"accent-deep\": \"32 81% 40%\",\n \"accent-foreground\": \"0 0% 100%\",\n muted: \"210 40% 96%\",\n \"muted-foreground\": \"215 16% 47%\",\n border: \"214 32% 91%\",\n input: \"214 32% 91%\",\n ring: \"221 83% 53%\",\n success: \"142 71% 36%\",\n \"success-foreground\": \"0 0% 100%\",\n warning: \"33 92% 44%\",\n \"warning-foreground\": \"0 0% 100%\",\n destructive: \"0 72% 51%\",\n \"destructive-foreground\": \"0 0% 100%\",\n info: \"217 91% 60%\",\n \"info-foreground\": \"0 0% 100%\",\n },\n // Dark mirror — mainly the same hues with inverted lightness so the theme\n // still feels coherent if a consumer toggles `.dark`.\n dark: {\n background: \"222 47% 8%\",\n foreground: \"210 40% 98%\",\n card: \"222 47% 11%\",\n \"card-foreground\": \"210 40% 98%\",\n popover: \"222 47% 11%\",\n \"popover-foreground\": \"210 40% 98%\",\n primary: \"217 91% 60%\",\n \"primary-deep\": \"221 83% 45%\",\n \"primary-glow\": \"213 100% 80%\",\n \"primary-foreground\": \"222 47% 11%\",\n secondary: \"217 19% 18%\",\n \"secondary-foreground\": \"210 40% 98%\",\n accent: \"37 92% 60%\",\n \"accent-deep\": \"32 81% 45%\",\n \"accent-foreground\": \"222 47% 11%\",\n muted: \"217 19% 18%\",\n \"muted-foreground\": \"215 20% 65%\",\n border: \"217 19% 22%\",\n input: \"217 19% 18%\",\n ring: \"217 91% 60%\",\n success: \"152 79% 52%\",\n \"success-foreground\": \"222 47% 11%\",\n warning: \"38 92% 50%\",\n \"warning-foreground\": \"222 47% 11%\",\n destructive: \"350 100% 65%\",\n \"destructive-foreground\": \"222 47% 11%\",\n info: \"213 100% 70%\",\n \"info-foreground\": \"222 47% 11%\",\n },\n};\n"
32
+ "content": "import type { Theme } from \"@/themes/types\";\n\n/**\n * Classic Paper — light-primary with deep-navy dark mirror; Inter + JetBrains Mono.\n *\n * Identity: warm paper background, deep navy foreground, indigo primary\n * (closer to traditional dashboard SaaS), Inter throughout. Maximizes\n * legibility and familiarity — use when reading endurance > differentiation.\n *\n * Provides a full `dark` palette mirror so consumers toggling `.dark` still\n * get a coherent surface (it is not \"light-only\" by accident).\n */\nexport const classicPaper: Theme = {\n name: \"classic-paper\",\n label: \"Classic Paper\",\n description: \"Inter + paper background. Maximum legibility, conservative.\",\n fonts: {\n display: '\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n body: '\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n mono: '\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace',\n },\n fontUrls: [\n \"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap\",\n ],\n light: {\n background: \"36 30% 98%\",\n foreground: \"222 47% 11%\",\n card: \"0 0% 100%\",\n \"card-foreground\": \"222 47% 11%\",\n popover: \"0 0% 100%\",\n \"popover-foreground\": \"222 47% 11%\",\n primary: \"221 83% 53%\",\n \"primary-deep\": \"224 76% 38%\",\n \"primary-glow\": \"217 91% 70%\",\n \"primary-foreground\": \"0 0% 100%\",\n secondary: \"210 40% 96%\",\n \"secondary-foreground\": \"222 47% 11%\",\n accent: \"37 92% 40%\",\n \"accent-deep\": \"32 81% 30%\",\n \"accent-foreground\": \"0 0% 100%\",\n muted: \"210 40% 96%\",\n \"muted-foreground\": \"215 16% 47%\",\n border: \"214 32% 91%\",\n input: \"214 32% 91%\",\n ring: \"221 83% 53%\",\n success: \"142 71% 36%\",\n \"success-foreground\": \"0 0% 100%\",\n warning: \"33 92% 44%\",\n \"warning-foreground\": \"0 0% 100%\",\n destructive: \"0 72% 51%\",\n \"destructive-foreground\": \"0 0% 100%\",\n info: \"217 91% 60%\",\n \"info-foreground\": \"0 0% 100%\",\n },\n // Dark mirror — mainly the same hues with inverted lightness so the theme\n // still feels coherent if a consumer toggles `.dark`.\n dark: {\n background: \"222 47% 8%\",\n foreground: \"210 40% 98%\",\n card: \"222 47% 11%\",\n \"card-foreground\": \"210 40% 98%\",\n popover: \"222 47% 11%\",\n \"popover-foreground\": \"210 40% 98%\",\n primary: \"217 91% 60%\",\n \"primary-deep\": \"221 83% 45%\",\n \"primary-glow\": \"213 100% 80%\",\n \"primary-foreground\": \"222 47% 11%\",\n secondary: \"217 19% 18%\",\n \"secondary-foreground\": \"210 40% 98%\",\n accent: \"37 92% 60%\",\n \"accent-deep\": \"32 81% 45%\",\n \"accent-foreground\": \"222 47% 11%\",\n muted: \"217 19% 18%\",\n \"muted-foreground\": \"215 20% 65%\",\n border: \"217 19% 22%\",\n input: \"217 19% 18%\",\n ring: \"217 91% 60%\",\n success: \"152 79% 52%\",\n \"success-foreground\": \"222 47% 11%\",\n warning: \"38 92% 50%\",\n \"warning-foreground\": \"222 47% 11%\",\n destructive: \"350 100% 65%\",\n \"destructive-foreground\": \"222 47% 11%\",\n info: \"213 100% 70%\",\n \"info-foreground\": \"222 47% 11%\",\n },\n};\n"
33
33
  },
34
34
  {
35
35
  "path": "themes/aurora-terminal.ts",
@@ -53,7 +53,7 @@
53
53
  "path": "themes/index.ts",
54
54
  "type": "registry:lib",
55
55
  "target": "themes/index.ts",
56
- "content": "export type { ColorScale, Theme, ThemeFonts, ThemeMode } from \"@/themes/types\";\nexport { ThemeProvider, useTheme } from \"@/themes/theme-provider\";\nexport { ThemeScript } from \"@/themes/theme-script\";\nexport { ThemeSwitcher } from \"@/themes/theme-switcher\";\nexport { violetForge } from \"@/themes/violet-forge\";\nexport { classicPaper } from \"@/themes/classic-paper\";\nexport { auroraTerminal } from \"@/themes/aurora-terminal\";\nexport { defineTheme, type DefineThemeInput } from \"./define\";\nexport { hex, rgb } from \"./color\";\nexport { useDensity, type Density, type DensityContextValue } from \"./density\";\n\nimport { auroraTerminal } from \"@/themes/aurora-terminal\";\nimport { classicPaper } from \"@/themes/classic-paper\";\nimport { violetForge } from \"@/themes/violet-forge\";\n\n/**\n * All themes bundled with Theo UI. Pass to `<ThemeProvider themes={builtinThemes}>`\n * if you want all of them available out of the box.\n */\nexport const builtinThemes = [violetForge, classicPaper, auroraTerminal];\n"
56
+ "content": "export type { ColorScale, Theme, ThemeFonts, ThemeMode } from \"@/themes/types\";\nexport { ThemeProvider, useTheme } from \"@/themes/theme-provider\";\nexport { ThemeScript } from \"@/themes/theme-script\";\nexport { ThemeSwitcher } from \"@/themes/theme-switcher\";\nexport { violetForge } from \"@/themes/violet-forge\";\nexport { classicPaper } from \"@/themes/classic-paper\";\nexport { auroraTerminal } from \"@/themes/aurora-terminal\";\nexport { defineTheme, type DefineThemeInput } from \"./define\";\nexport { hex, rgb } from \"./color\";\nexport { useDensity, type Density, type DensityContextValue } from \"./density\";\n// Seven new themes — RFC 0007, plan: seven-themes (2026-05-22).\n// Trademark-safe slugs (D1.1) — `*-style` / `*-mono` / `*-glass` suffixes,\n// description includes \"Inspired by, not affiliated with [X]\".\nexport { vercelMono } from \"./vercel-mono\";\nexport { githubDark } from \"./github-dark\";\nexport { dracula } from \"./dracula\";\nexport { oneDark } from \"./one-dark\";\nexport { anthropicStyle } from \"./anthropic-style\";\nexport { openaiStyle } from \"./openai-style\";\nexport { linearGlass } from \"./linear-glass\";\n\nimport { anthropicStyle } from \"./anthropic-style\";\nimport { auroraTerminal } from \"@/themes/aurora-terminal\";\nimport { classicPaper } from \"@/themes/classic-paper\";\nimport { dracula } from \"./dracula\";\nimport { githubDark } from \"./github-dark\";\nimport { linearGlass } from \"./linear-glass\";\nimport { oneDark } from \"./one-dark\";\nimport { openaiStyle } from \"./openai-style\";\nimport { vercelMono } from \"./vercel-mono\";\nimport { violetForge } from \"@/themes/violet-forge\";\n\n/**\n * All themes bundled with Theo UI. Pass to `<ThemeProvider themes={builtinThemes}>`\n * if you want all 10 available out of the box.\n *\n * EC-4 note: passing the full 10-entry list triggers ~60 KB CSS injection in\n * `<style id=\"theo-ui-theme-vars\">`. For apps focused on 1-2 themes, prefer\n * `themes={[violetForge, dracula]}` to keep the payload at ~12 KB.\n */\nexport const builtinThemes = [\n violetForge,\n classicPaper,\n auroraTerminal,\n vercelMono,\n githubDark,\n dracula,\n oneDark,\n anthropicStyle,\n openaiStyle,\n linearGlass,\n];\n"
57
57
  }
58
58
  ]
59
59
  }