🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

typestyles

Package Overview
Dependencies
Maintainers
1
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typestyles - npm Package Compare versions

Comparing version
0.4.0
to
0.5.0
+333
dist/chunk-G6ATUNEZ.js
// src/registry.ts
var registeredNamespaces = /* @__PURE__ */ new Set();
var COLON = ":";
function releaseReservedNamespacesForComponentOrClassNames(namespaces) {
if (namespaces.length === 0) return;
const wanted = new Set(namespaces);
const toRemove = [];
for (const key of registeredNamespaces) {
const i = key.indexOf(COLON);
if (i === -1) continue;
if (wanted.has(key.slice(i + 1))) {
toRemove.push(key);
}
}
for (const key of toRemove) {
registeredNamespaces.delete(key);
}
}
function namespacesFromTypestylesHmrPrefixes(prefixes) {
const out = [];
for (const p of prefixes) {
if (p.length >= 2 && p.startsWith(".") && p.endsWith("-")) {
out.push(p.slice(1, -1));
}
}
return out;
}
// src/sheet.ts
var STYLE_ELEMENT_ID = "typestyles";
var insertedRules = /* @__PURE__ */ new Set();
var ruleCssByKey = /* @__PURE__ */ new Map();
function duplicateRuleKeyConflictWarningsEnabled() {
if (typeof process === "undefined") return true;
return process.env.NODE_ENV !== "production";
}
function warnIfDuplicateRuleKeyConflict(key, previousCss, ignoredCss) {
if (!duplicateRuleKeyConflictWarningsEnabled()) return;
const prevShort = previousCss.length > 220 ? `${previousCss.slice(0, 220)}\u2026` : previousCss;
const nextShort = ignoredCss.length > 220 ? `${ignoredCss.slice(0, 220)}\u2026` : ignoredCss;
console.warn(
`[typestyles] Skipped a rule: dedupe key "${key}" already exists with different CSS. Only the first registration is kept. For globals, merge into one \`global.style\`, or use a distinct selector (e.g. \`html body\` after reset\u2019s \`body\`).
Existing: ${prevShort}
Skipped: ${nextShort}`
);
}
function readNextPublicRuntimeDisabled() {
if (typeof process === "undefined" || !process.env) return false;
return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === "true";
}
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true" || readNextPublicRuntimeDisabled();
var pendingRules = [];
var allRules = [];
var flushScheduled = false;
var styleElement = null;
var ssrBuffer = null;
var isBrowser = typeof document !== "undefined" && typeof window !== "undefined";
function writeAllRulesToStyleElement(el) {
if (RUNTIME_DISABLED || allRules.length === 0) return;
const sheet = el.sheet;
if (sheet) {
for (const css of allRules) {
try {
sheet.insertRule(css, sheet.cssRules.length);
} catch {
el.appendChild(document.createTextNode(css));
}
}
} else {
el.appendChild(document.createTextNode(allRules.join("\n")));
}
}
function getStyleElement() {
let reconnectAfterDetach = false;
if (styleElement && !styleElement.isConnected) {
reconnectAfterDetach = true;
styleElement = null;
}
if (styleElement) return styleElement;
const existing = document.getElementById(STYLE_ELEMENT_ID);
if (existing?.isConnected) {
styleElement = existing;
return styleElement;
}
styleElement = document.createElement("style");
styleElement.id = STYLE_ELEMENT_ID;
document.head.appendChild(styleElement);
if (reconnectAfterDetach && allRules.length > 0) {
writeAllRulesToStyleElement(styleElement);
}
return styleElement;
}
function ensureDocumentStylesAttached() {
if (!isBrowser || RUNTIME_DISABLED) return;
getStyleElement();
}
function flush() {
flushScheduled = false;
if (pendingRules.length === 0) return;
const rules = pendingRules;
pendingRules = [];
if (ssrBuffer) {
ssrBuffer.push(...rules);
return;
}
if (!isBrowser || RUNTIME_DISABLED) return;
const el = getStyleElement();
const sheet = el.sheet;
if (sheet) {
for (const rule of rules) {
try {
sheet.insertRule(rule, sheet.cssRules.length);
} catch {
el.appendChild(document.createTextNode(rule));
}
}
} else {
el.appendChild(document.createTextNode(rules.join("\n")));
}
}
function scheduleFlush() {
if (flushScheduled) return;
flushScheduled = true;
if (ssrBuffer) {
flush();
return;
}
if (isBrowser && !RUNTIME_DISABLED) {
queueMicrotask(flush);
}
}
function registerCascadeLayerOrder(preambleKey, css) {
const key = `typestyles:@layer-order:${preambleKey}`;
if (insertedRules.has(key)) return;
insertedRules.add(key);
allRules.unshift(css);
if (ssrBuffer) {
ssrBuffer.unshift(css);
return;
}
if (RUNTIME_DISABLED) return;
if (!isBrowser) return;
const el = getStyleElement();
const sheet = el.sheet;
if (sheet) {
try {
sheet.insertRule(css, 0);
} catch {
el.insertBefore(document.createTextNode(`${css}
`), el.firstChild);
}
} else {
el.insertBefore(document.createTextNode(`${css}
`), el.firstChild);
}
}
function insertRule(key, css) {
if (insertedRules.has(key)) {
const prev = ruleCssByKey.get(key);
if (prev != null && prev !== css) {
warnIfDuplicateRuleKeyConflict(key, prev, css);
}
return;
}
insertedRules.add(key);
ruleCssByKey.set(key, css);
allRules.push(css);
if (RUNTIME_DISABLED && !ssrBuffer) return;
pendingRules.push(css);
scheduleFlush();
}
function insertRules(rules) {
let added = false;
for (const { key, css } of rules) {
if (insertedRules.has(key)) {
const prev = ruleCssByKey.get(key);
if (prev != null && prev !== css) {
warnIfDuplicateRuleKeyConflict(key, prev, css);
}
continue;
}
insertedRules.add(key);
ruleCssByKey.set(key, css);
allRules.push(css);
if (!RUNTIME_DISABLED || ssrBuffer) {
pendingRules.push(css);
added = true;
}
}
if (added) scheduleFlush();
}
function startCollection() {
ssrBuffer = [];
return () => {
const css = ssrBuffer ? ssrBuffer.join("\n") : "";
ssrBuffer = null;
return css;
};
}
function getRegisteredCss() {
return allRules.join("\n");
}
function reset() {
insertedRules.clear();
ruleCssByKey.clear();
pendingRules = [];
allRules.length = 0;
flushScheduled = false;
ssrBuffer = null;
if (isBrowser && styleElement) {
styleElement.remove();
styleElement = null;
}
}
function flushSync() {
flush();
}
function invalidatePrefix(prefix) {
for (const key of insertedRules) {
if (key.startsWith(prefix)) {
insertedRules.delete(key);
ruleCssByKey.delete(key);
}
}
releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));
if (!isBrowser) return;
const el = styleElement;
if (!el) return;
const sheet = el.sheet;
if (!sheet) return;
for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
const rule = sheet.cssRules[i];
if (ruleMatchesPrefix(rule, prefix)) {
sheet.deleteRule(i);
}
}
}
function invalidateKeys(keys, prefixes) {
for (const key of keys) {
insertedRules.delete(key);
ruleCssByKey.delete(key);
}
for (const prefix of prefixes) {
for (const key of insertedRules) {
if (key.startsWith(prefix)) {
insertedRules.delete(key);
ruleCssByKey.delete(key);
}
}
}
releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));
if (!isBrowser) return;
const el = styleElement;
if (!el) return;
const sheet = el.sheet;
if (!sheet) return;
const keySet = new Set(keys);
for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
const rule = sheet.cssRules[i];
let shouldRemove = false;
for (const prefix of prefixes) {
if (ruleMatchesPrefix(rule, prefix)) {
shouldRemove = true;
break;
}
}
if (!shouldRemove) {
const ruleText = rule.cssText;
for (const key of keySet) {
if (ruleMatchesKey(ruleText, key)) {
shouldRemove = true;
break;
}
}
}
if (shouldRemove) {
sheet.deleteRule(i);
}
}
}
function invalidateComponentNamespaceForDev(namespace) {
const selectorInfix = `.${namespace}-`;
const keysToDrop = [];
for (const k of insertedRules) {
if (k.includes(selectorInfix)) {
keysToDrop.push(k);
}
}
invalidateKeys(keysToDrop, [selectorInfix]);
}
function ruleMatchesPrefix(rule, prefix) {
if (prefix.startsWith("font-face:")) {
const family = prefix.slice("font-face:".length).split(":")[0];
if (rule.cssText.includes("@font-face")) {
return rule.cssText.includes(`"${family}"`) || rule.cssText.includes(`'${family}'`);
}
return false;
}
if ("selectorText" in rule) {
return rule.selectorText.startsWith(prefix);
}
if ("name" in rule && prefix.startsWith("keyframes:")) {
return rule.name === prefix.slice("keyframes:".length);
}
if ("cssRules" in rule) {
const innerRules = rule.cssRules;
for (let i = 0; i < innerRules.length; i++) {
if (ruleMatchesPrefix(innerRules[i], prefix)) return true;
}
}
return false;
}
function ruleMatchesKey(cssText, key) {
if (key.startsWith("tokens:")) {
const rest = key.slice("tokens:".length);
const at = rest.lastIndexOf("@");
const namespace = at === -1 ? rest : rest.slice(0, at);
return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);
}
if (key.startsWith("theme:")) {
const name = key.slice("theme:".length);
return cssText.includes(`.theme-${name}`);
}
if (key.startsWith("keyframes:")) {
const name = key.slice("keyframes:".length);
return cssText.includes(`@keyframes ${name}`);
}
return false;
}
export { ensureDocumentStylesAttached, flushSync, getRegisteredCss, insertRule, insertRules, invalidateComponentNamespaceForDev, invalidateKeys, invalidatePrefix, registerCascadeLayerOrder, registeredNamespaces, reset, startCollection };
//# sourceMappingURL=chunk-G6ATUNEZ.js.map
//# sourceMappingURL=chunk-G6ATUNEZ.js.map
{"version":3,"sources":["../src/registry.ts","../src/sheet.ts"],"names":[],"mappings":"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","file":"chunk-G6ATUNEZ.js","sourcesContent":["/**\n * Shared registry for detecting duplicate namespace registrations.\n */\nexport const registeredNamespaces = new Set<string>();\n\nconst COLON = ':';\n\n/**\n * Drop reserved `scopeId:namespace` keys so a module can re-register after HMR.\n * `namespace` is the first argument to `styles.component()` / `styles.class()` (not the scope).\n */\nexport function releaseReservedNamespacesForComponentOrClassNames(\n namespaces: readonly string[],\n): void {\n if (namespaces.length === 0) return;\n const wanted = new Set(namespaces);\n const toRemove: string[] = [];\n for (const key of registeredNamespaces) {\n const i = key.indexOf(COLON);\n if (i === -1) continue;\n if (wanted.has(key.slice(i + 1))) {\n toRemove.push(key);\n }\n }\n for (const key of toRemove) {\n registeredNamespaces.delete(key);\n }\n}\n\n/** Vite plugin passes `.${namespace}-` prefixes for `styles.component()` invalidation. */\nexport function namespacesFromTypestylesHmrPrefixes(prefixes: readonly string[]): string[] {\n const out: string[] = [];\n for (const p of prefixes) {\n if (p.length >= 2 && p.startsWith('.') && p.endsWith('-')) {\n out.push(p.slice(1, -1));\n }\n }\n return out;\n}\n","import {\n namespacesFromTypestylesHmrPrefixes,\n releaseReservedNamespacesForComponentOrClassNames,\n} from './registry';\n\nconst STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Last emitted CSS per dedupe key (see {@link warnIfDuplicateRuleKeyConflict}).\n * Cleared with {@link reset} and kept in sync when keys are invalidated.\n */\nconst ruleCssByKey = new Map<string, string>();\n\nfunction duplicateRuleKeyConflictWarningsEnabled(): boolean {\n if (typeof process === 'undefined') return true;\n return process.env.NODE_ENV !== 'production';\n}\n\n/**\n * When the same key is registered again with different CSS, the second rule is skipped\n * (idempotency / HMR). In non-production builds, surface that so overlapping globals\n * (e.g. reset `body` + app `body` in the same scope) are not silent failures.\n */\nfunction warnIfDuplicateRuleKeyConflict(\n key: string,\n previousCss: string,\n ignoredCss: string,\n): void {\n if (!duplicateRuleKeyConflictWarningsEnabled()) return;\n const prevShort = previousCss.length > 220 ? `${previousCss.slice(0, 220)}…` : previousCss;\n const nextShort = ignoredCss.length > 220 ? `${ignoredCss.slice(0, 220)}…` : ignoredCss;\n console.warn(\n `[typestyles] Skipped a rule: dedupe key \"${key}\" already exists with different CSS. ` +\n `Only the first registration is kept. For globals, merge into one \\`global.style\\`, ` +\n `or use a distinct selector (e.g. \\`html body\\` after reset’s \\`body\\`).\\n` +\n ` Existing: ${prevShort}\\n` +\n ` Skipped: ${nextShort}`,\n );\n}\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n *\n * `@typestyles/next/build` `withTypestylesExtract` sets `NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED`\n * via `next.config` `env` so Turbopack and webpack both inline the flag (DefinePlugin\n * alone does not run under Turbopack).\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nfunction readNextPublicRuntimeDisabled(): boolean {\n if (typeof process === 'undefined' || !process.env) return false;\n return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === 'true';\n}\nconst RUNTIME_DISABLED =\n (typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true') ||\n readNextPublicRuntimeDisabled();\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser = typeof document !== 'undefined' && typeof window !== 'undefined';\n\n/**\n * Re-insert every registered rule into a (usually fresh) <style> element.\n * Used when the live element was detached (e.g. Astro view transitions replacing <head>).\n */\nfunction writeAllRulesToStyleElement(el: HTMLStyleElement): void {\n if (RUNTIME_DISABLED || allRules.length === 0) return;\n const sheet = el.sheet;\n if (sheet) {\n for (const css of allRules) {\n try {\n sheet.insertRule(css, sheet.cssRules.length);\n } catch {\n el.appendChild(document.createTextNode(css));\n }\n }\n } else {\n el.appendChild(document.createTextNode(allRules.join('\\n')));\n }\n}\n\nfunction getStyleElement(): HTMLStyleElement {\n let reconnectAfterDetach = false;\n if (styleElement && !styleElement.isConnected) {\n reconnectAfterDetach = true;\n styleElement = null;\n }\n if (styleElement) return styleElement;\n\n // Prefer an element actually in the document (SSR or another copy on the page).\n const existing = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement | null;\n if (existing?.isConnected) {\n styleElement = existing;\n return styleElement;\n }\n\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n\n // After a doc swap, we have a new empty sheet but insertRule() won't re-queue (deduped keys).\n if (reconnectAfterDetach && allRules.length > 0) {\n writeAllRulesToStyleElement(styleElement);\n }\n\n return styleElement;\n}\n\n/**\n * Ensure the managed <style id=\"typestyles\"> is attached to the current document and populated.\n * Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.\n */\nexport function ensureDocumentStylesAttached(): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n getStyleElement();\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Register a single `@layer a, b, c;` preamble so layer **order** is defined before any\n * `@layer name { … }` blocks. Inserts at the front of the virtual sheet and at CSSOM index 0\n * when injecting into the document.\n */\nexport function registerCascadeLayerOrder(preambleKey: string, css: string): void {\n const key = `typestyles:@layer-order:${preambleKey}`;\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n\n allRules.unshift(css);\n\n if (ssrBuffer) {\n ssrBuffer.unshift(css);\n return;\n }\n\n if (RUNTIME_DISABLED) return;\n\n if (!isBrowser) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n try {\n sheet.insertRule(css, 0);\n } catch {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n } else {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n return;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n continue;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n ruleCssByKey.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Drop every rule key tied to a `styles.component('namespace', …)` registration, including\n * `@layer`-wrapped keys (`layer:….:.namespace-…`), and release reserved namespace entries.\n * Used for Vite HMR and for dev recovery when a module re-runs before `hot.dispose`.\n */\nexport function invalidateComponentNamespaceForDev(namespace: string): void {\n const selectorInfix = `.${namespace}-`;\n const keysToDrop: string[] = [];\n for (const k of insertedRules) {\n if (k.includes(selectorInfix)) {\n keysToDrop.push(k);\n }\n }\n invalidateKeys(keysToDrop, [selectorInfix]);\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`);\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color or tokens:color@layerName -> :root rule with --color- custom properties\n const rest = key.slice('tokens:'.length);\n const at = rest.lastIndexOf('@');\n const namespace = at === -1 ? rest : rest.slice(0, at);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n"]}
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
export { __export };
//# sourceMappingURL=chunk-PZ5AY32C.js.map
//# sourceMappingURL=chunk-PZ5AY32C.js.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-PZ5AY32C.js"}
import * as CSS from 'csstype';
/**
* A CSS value that can be a standard value or a token reference (var() string).
*
* Values are emitted verbatim. TypeScript does **not** validate CSS syntax, so a typo in
* `calc()`, `clamp()`, `min()`, `max()`, `url()`, etc. (for example a missing `)`) can produce
* invalid CSS that breaks parsing for following rules. Use **`calc`** (tagged template) and
* **`clamp`** from `typestyles` to keep function parentheses balanced, or small named helpers;
* see the docs “TypeScript Tips” page.
*/
type CSSValue = string | number;
/**
* CSS properties with support for nested selectors and at-rules.
* Extends csstype's Properties with nesting capabilities.
*
* For `@…` keys, **`container()`** / **`styles.container()`** infer a **literal** `@container …` template so
* `[container({ minWidth: 400 })]` mixes with longhands without casting. For **dynamic** `@…` strings, spread
* **`atRuleBlock` / `styles.atRuleBlock`**. Same idea for **`has` / `is` / `where`**: variadic literals narrow
* to `&:…` keys; if the key is only known as `string`, spread a one-key object or use `atRuleBlock`.
*/
interface CSSProperties extends CSS.Properties<CSSValue> {
/** Nested selector (e.g., '&:hover', `has('.x')`, '& .child', '&::before', '&[data-variant]') */
[selector: `&${string}`]: CSSProperties;
/**
* Ancestor-prefixed selector where `&` is the styled element (e.g. `html[data-mode="dark"] &`,
* `html:not([data-mode="light"]) &`). Runtime serialization replaces every `&` with the class selector.
*/
[selectorWithAncestor: `${string}&${string}`]: CSSProperties;
/** Attribute selector (e.g., '[data-variant]', '[data-variant="primary"]', '[disabled]') */
[attribute: `[${string}]`]: CSSProperties;
/** At-rule (e.g., '@media (max-width: 768px)', '@container', '@supports') */
[atRule: `@${string}`]: CSSProperties;
}
/**
* Utility function map used by styles.withUtils().
* Each key becomes an extra style property that expands into CSSProperties.
*/
type BivariantCallback<Arg, Ret> = {
bivarianceHack(value: Arg): Ret;
}['bivarianceHack'];
type StyleUtils = Record<string, BivariantCallback<unknown, CSSProperties>>;
type UtilityValue<U extends StyleUtils, K extends keyof U> = U[K] extends (value: infer V) => CSSProperties ? V : never;
/**
* CSS properties augmented with user-defined utility keys.
*/
type CSSPropertiesWithUtils<U extends StyleUtils> = CSS.Properties<CSSValue> & {
[K in keyof U]?: UtilityValue<U, K>;
} & {
[selector: `&${string}`]: CSSPropertiesWithUtils<U>;
[selectorWithAncestor: `${string}&${string}`]: CSSPropertiesWithUtils<U>;
[attribute: `[${string}]`]: CSSPropertiesWithUtils<U>;
[atRule: `@${string}`]: CSSPropertiesWithUtils<U>;
};
/**
* A map of style names to utility-aware CSS property definitions.
*/
type StyleDefinitionsWithUtils<U extends StyleUtils> = Record<string, CSSPropertiesWithUtils<U>>;
/**
* A map of variant names to their CSS property definitions.
*/
type StyleDefinitions = Record<string, CSSProperties>;
/**
* A token value can be a string/number or a nested object of token values.
* Supports arbitrarily deep nesting for hierarchical token structures.
*/
type TokenValues = string | number | {
[key: string]: TokenValues;
};
/**
* A flattened key-value pair for CSS custom property generation.
*/
type FlatTokenEntry = [key: string, value: string];
/**
* Flattens a nested TokenValues object into an array of [key, value] pairs.
* Deeply nested objects are flattened with keys joined by hyphens.
*
* @example
* flattenTokens({ text: { primary: '#000' } })
* // => [['text-primary', '#000']]
*/
declare function flattenTokenEntries(obj: TokenValues, prefix?: string): FlatTokenEntry[];
/**
* A typed token reference object. Property access returns var(--namespace-key).
* Supports nested access: token.text.primary => var(--namespace-text-primary)
*/
type TokenRef<T extends TokenValues> = T extends string | number ? string : {
readonly [K in keyof T]: T[K] extends TokenValues ? TokenRef<T[K]> : string;
};
/**
* Nested token values where any object level may omit keys (for mode layers that
* only tweak a subtree of `base`).
*/
type DeepPartialTokenValues = string | number | {
[key: string]: DeepPartialTokenValues | undefined;
};
/**
* Theme overrides: namespaces map to full or deeply partial token trees.
* Aligns with `tokens.create` namespaces; mode `overrides` often only set a subset of keys.
*/
type ThemeOverrides = {
[namespace: string]: DeepPartialTokenValues | undefined;
};
/**
* Keyframe stops: 'from', 'to', or percentage strings mapped to CSS properties.
*/
type KeyframeStops = Record<string, CSSProperties>;
/** Match a media query (e.g. `(prefers-color-scheme: dark)`). */
type ThemeConditionMedia = {
readonly type: 'media';
readonly query: string;
};
/** Match an attribute on the themed element (`self`) or an ancestor (`ancestor`). */
type ThemeConditionAttr = {
readonly type: 'attr';
readonly name: string;
readonly value: string;
readonly scope: 'self' | 'ancestor';
};
/** Match a class on the themed element (`self`) or an ancestor (`ancestor`). */
type ThemeConditionClass = {
readonly type: 'class';
readonly name: string;
readonly scope: 'self' | 'ancestor';
};
/** Raw selector escape hatch — the selector is used as an ancestor context for the theme class. */
type ThemeConditionSelector = {
readonly type: 'selector';
readonly selector: string;
};
/** All child conditions must hold. */
type ThemeConditionAnd = {
readonly type: 'and';
readonly conditions: readonly ThemeCondition[];
};
/** Any child condition must hold (emits separate rules per branch). */
type ThemeConditionOr = {
readonly type: 'or';
readonly conditions: readonly ThemeCondition[];
};
/** Negate a single-branch condition (see `tokens.when.not` JSDoc for limits). */
type ThemeConditionNot = {
readonly type: 'not';
readonly condition: ThemeCondition;
};
/**
* A condition that determines **when** a set of token overrides applies.
* Conditions compile to media queries, selector prefixes/suffixes, or combinations.
*/
type ThemeCondition = ThemeConditionMedia | ThemeConditionAttr | ThemeConditionClass | ThemeConditionSelector | ThemeConditionAnd | ThemeConditionOr | ThemeConditionNot;
/**
* A single mode layer within a theme surface.
* Applies `overrides` when `when` is satisfied.
*/
type ThemeModeDefinition = {
readonly id: string;
readonly overrides: ThemeOverrides;
readonly when: ThemeCondition;
};
/**
* Configuration for `tokens.createTheme()`.
* Provide `modes` (manual) **or** `colorMode` (preset), not both.
*/
type ThemeConfig = {
/** Base token overrides — emitted as `.theme-{name} { … }`. */
base?: ThemeOverrides;
/** Manual mode layers with explicit conditions. Mutually exclusive with `colorMode`. */
modes?: ThemeModeDefinition[];
/** Preset mode layers from `tokens.colorMode.*`. Mutually exclusive with `modes`. */
colorMode?: ThemeModeDefinition[];
};
/**
* The object returned by `tokens.createTheme()`.
*
* - `surface.className` — the generated class name (e.g. `"theme-acme"`)
* - `surface.name` — the theme name (e.g. `"acme"`)
* - `String(surface)` / template interpolation — coerces to `className`
*/
interface ThemeSurface {
readonly className: string;
readonly name: string;
toString(): string;
[Symbol.toPrimitive](hint: string): string;
}
/**
* Styles for a single variant option (or slot variant block).
* Union with a permissive record so **`[v.name]: value`** from {@link ComponentInternalVarRef}
* (custom properties) infers as `{ [key: string]: … }` and still matches — that shape is not
* assignable to {@link CSSProperties} alone, which would otherwise reject the dimensioned overload
* and fall through to unrelated `component` overloads. **`Record<string, unknown>`** also covers
* objects that mix custom-property keys with nested selector blocks like `'&:hover'`.
*/
type VariantOptionStyle = CSSProperties | Record<string, unknown>;
/**
* A map of variant dimensions to their options (each option is {@link VariantOptionStyle}).
*/
type VariantDefinitions = Record<string, Record<string, VariantOptionStyle>>;
type SlotStyles<S extends string> = Partial<Record<S, VariantOptionStyle>>;
type SlotVariantDefinitions<S extends string> = Record<string, Record<string, SlotStyles<S>>>;
type VariantDimensions = Record<string, Record<string, unknown>>;
type VariantOptionKey<V extends VariantDimensions, K extends keyof V> = Extract<keyof V[K], string>;
type VariantSelectionValue<OptionKey extends string> = OptionKey | (Extract<OptionKey, 'true'> extends never ? never : true) | (Extract<OptionKey, 'false'> extends never ? never : false);
type CompoundSelectionValue<OptionKey extends string> = VariantSelectionValue<OptionKey> | readonly VariantSelectionValue<OptionKey>[];
type ComponentSelections<V extends VariantDimensions> = {
[K in keyof V]?: VariantSelectionValue<VariantOptionKey<V, K>> | null | undefined;
};
/**
* A CSS custom property reference as a `var(--…)` value (tokens, `createVar()`, component internal vars).
*/
type CSSVarRef = `var(--${string})`;
/**
* Leaf shape for `ctx.vars({ … })` — mirrors typed tokens: `value` is the default (merged into `base`);
* optional `syntax` / `inherits` register `@property` like typed design tokens.
*/
type ComponentVarDescriptor = {
value: string | number;
syntax?: string;
inherits?: boolean;
};
/**
* Nested map of component internal vars (same nesting as `tokens.create` / theme token trees).
*/
type ComponentVarNode = string | number | ComponentVarDescriptor | {
[key: string]: ComponentVarNode;
};
type ComponentVarDefinitions = {
[key: string]: ComponentVarNode;
};
/**
* Options for `ctx.var(id, options?)`. Set `value` to merge a default into `base` and as `@property` initial-value when `syntax` is set.
*/
type ComponentVarOptions = {
value?: string | number;
syntax?: string;
inherits?: boolean;
};
/**
* Reference to a component-scoped custom property: `.name` for declaration keys and transitions, `.var` for values.
*/
type ComponentInternalVarRef = {
readonly name: string;
readonly var: CSSVarRef;
};
/**
* Context passed to `styles.component(namespace, (ctx) => { ... })` to declare internal custom properties.
*/
/** Proxy tree returned by `ctx.vars({ … })` — leaves are `{ name, var }`, nested objects are sub-trees. */
type ComponentVarRefTree<T> = {
[K in keyof T]: T[K] extends ComponentVarDescriptor | string | number ? ComponentInternalVarRef : ComponentVarRefTree<T[K]>;
};
type ComponentConfigContext = {
var: (id: string, options?: ComponentVarOptions) => ComponentInternalVarRef;
vars: <const T extends ComponentVarDefinitions>(definitions: T) => ComponentVarRefTree<T>;
};
/**
* The full config object passed to styles.component() with dimensioned variants.
*/
type ComponentConfig<V extends VariantDefinitions> = {
base?: CSSProperties;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: VariantOptionStyle;
}>;
defaultVariants?: ComponentSelections<V>;
};
/**
* Config for flat variants: `{ base: {...}, elevated: {...}, compact: {...} }`.
* Each key besides `base` is a boolean-style variant.
*
* **`variants`**, **`defaultVariants`**, **`compoundVariants`**, and **`slots`** are forbidden
* on this shape so TypeScript does not pick the flat overload for CVA-style or slot configs.
* Nested variant maps can otherwise satisfy {@link CSSProperties} too loosely (index signatures),
* which produced wrong callable types for `styles.component(ns, (ctx) => ({ variants: … }), { layer })`
* when cascade layers are enabled.
*/
type FlatComponentConfig<K extends string> = {
base?: CSSProperties;
variants?: never;
defaultVariants?: never;
compoundVariants?: never;
slots?: never;
} & Record<K, CSSProperties>;
/**
* Selection object for flat variants: `{ elevated: true, compact: true }`.
*/
type FlatComponentSelections<K extends string> = {
[P in K]?: boolean | null | undefined;
};
/**
* All possible variant class string keys that can be destructured from a
* dimensioned component. Includes 'base' plus all `{dimension}-{option}` keys
* flattened from the variants config.
*/
type DimensionedVariantKeys<V extends VariantDefinitions> = {
[D in keyof V]: keyof V[D] extends string ? `${D & string}-${keyof V[D] & string}` : never;
}[keyof V];
/**
* The CVA-style return for dimensioned variants.
* Callable as a function, destructurable as an object.
*/
type ComponentReturn<V extends VariantDefinitions> = {
/** Call with variant selections to get composed class string (base always included). */
(selections?: ComponentSelections<V>): string;
} & {
/** The base class string. */
readonly base: string;
} & {
/** Individual variant class strings, keyed as `{dimension}-{option}`. */
readonly [K in DimensionedVariantKeys<V>]: string;
};
/**
* The CVA-style return for flat variants.
* Callable as a function, destructurable as an object.
*/
type FlatComponentReturn<K extends string> = {
/** Call with variant selections to get composed class string (base always included). */
(selections?: FlatComponentSelections<Exclude<K, 'base'>>): string;
} & {
/** The base class string. */
readonly base: string;
} & {
/** Individual variant class strings. */
readonly [P in Exclude<K, 'base'>]: string;
};
type MultiSlotConfig<Slots extends readonly string[]> = {
slots: Slots;
} & Partial<Record<Slots[number], CSSProperties>>;
type MultiSlotReturn<Slots extends readonly string[]> = {
(): Record<Slots[number], string>;
} & {
readonly [K in Slots[number]]: string;
};
type SlotComponentConfig<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = {
slots: Slots;
base?: SlotStyles<Slots[number]>;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: SlotStyles<Slots[number]>;
}>;
defaultVariants?: ComponentSelections<V>;
};
type SlotComponentFunction<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = (selections?: ComponentSelections<V>) => Record<Slots[number], string>;
/**
* Config for `styles.component` may be a plain object or a function that receives {@link ComponentConfigContext}.
*/
type ComponentConfigInput<V extends VariantDefinitions> = ComponentConfig<V> | ((ctx: ComponentConfigContext) => ComponentConfig<V>);
type FlatComponentConfigInput<K extends string> = FlatComponentConfig<K> | ((ctx: ComponentConfigContext) => FlatComponentConfig<K>);
type SlotComponentConfigInput<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = SlotComponentConfig<Slots, V> | ((ctx: ComponentConfigContext) => SlotComponentConfig<Slots, V>);
type MultiSlotConfigInput<Slots extends readonly string[]> = MultiSlotConfig<Slots> | ((ctx: ComponentConfigContext) => MultiSlotConfig<Slots>);
/**
* Extract the variant prop types from a ComponentReturn or ComponentFunction.
*
* @example
* ```ts
* const button = styles.component('button', {
* variants: {
* intent: { primary: {...}, ghost: {...} },
* size: { sm: {...}, lg: {...} },
* },
* });
*
* type ButtonProps = ComponentVariants<typeof button>;
* // { intent?: 'primary' | 'ghost'; size?: 'sm' | 'lg' }
* ```
*/
type ComponentVariants<T> = T extends (selections?: ComponentSelections<infer V>) => unknown ? {
[K in keyof V]?: keyof V[K];
} : never;
/**
* `src` value for {@link FontFaceProps}: a single CSS `src` fragment or multiple
* fragments joined with commas (same as authoring `url(...), local(...)` by hand).
*/
type FontFaceSrc = string | readonly string[];
/**
* Font face property declarations.
*
* Maps to standard `@font-face` descriptors. Values are emitted verbatim in CSS.
*/
type FontFaceProps = {
src: FontFaceSrc;
fontWeight?: string | number;
fontStyle?: 'normal' | 'italic' | 'oblique' | string;
fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
fontStretch?: string;
unicodeRange?: string;
/** `size-adjust` — fallback tuning and font-size-adjust related metrics. */
sizeAdjust?: string;
/** `ascent-override` */
ascentOverride?: string;
/** `descent-override` */
descentOverride?: string;
/** `line-gap-override` */
lineGapOverride?: string;
};
/**
* Return type of helpers in `typestyles/globals`, passed to `global.style(…)`.
*
* @example
* ```ts
* global.style(boxSizing());
* global.style(body({ margin: 0 }, { layer: 'components' }));
* ```
*/
type GlobalStyleTuple = readonly [selector: string, properties: CSSProperties] | readonly [selector: string, properties: CSSProperties, options: {
layer?: string;
}];
export { type ComponentSelections as A, type ComponentVarDefinitions as B, type CSSProperties as C, type ComponentVarDescriptor as D, type ComponentVarNode as E, type FlatComponentConfigInput as F, type GlobalStyleTuple as G, type ComponentVarOptions as H, type ComponentVarRefTree as I, type ComponentVariants as J, type DeepPartialTokenValues as K, type FlatComponentConfig as L, type MultiSlotConfigInput as M, type FlatComponentSelections as N, type FlatTokenEntry as O, type FontFaceSrc as P, type KeyframeStops as Q, type SlotComponentConfig as R, type SlotVariantDefinitions as S, type ThemeConditionMedia as T, type SlotStyles as U, type VariantDefinitions as V, type StyleDefinitions as W, type StyleDefinitionsWithUtils as X, type ThemeConditionNot as Y, type VariantOptionStyle as Z, flattenTokenEntries as _, type ThemeConditionAttr as a, type ThemeConditionClass as b, type ThemeConditionSelector as c, type ThemeCondition as d, type ThemeConditionAnd as e, type ThemeConditionOr as f, type ThemeOverrides as g, type ThemeModeDefinition as h, type ThemeSurface as i, type ThemeConfig as j, type TokenValues as k, type TokenRef as l, type ComponentConfigInput as m, type ComponentReturn as n, type FlatComponentReturn as o, type SlotComponentConfigInput as p, type SlotComponentFunction as q, type MultiSlotReturn as r, type StyleUtils as s, type CSSPropertiesWithUtils as t, type FontFaceProps as u, type CSSVarRef as v, type CSSValue as w, type ComponentConfig as x, type ComponentConfigContext as y, type ComponentInternalVarRef as z };
import * as CSS from 'csstype';
/**
* A CSS value that can be a standard value or a token reference (var() string).
*
* Values are emitted verbatim. TypeScript does **not** validate CSS syntax, so a typo in
* `calc()`, `clamp()`, `min()`, `max()`, `url()`, etc. (for example a missing `)`) can produce
* invalid CSS that breaks parsing for following rules. Use **`calc`** (tagged template) and
* **`clamp`** from `typestyles` to keep function parentheses balanced, or small named helpers;
* see the docs “TypeScript Tips” page.
*/
type CSSValue = string | number;
/**
* CSS properties with support for nested selectors and at-rules.
* Extends csstype's Properties with nesting capabilities.
*
* For `@…` keys, **`container()`** / **`styles.container()`** infer a **literal** `@container …` template so
* `[container({ minWidth: 400 })]` mixes with longhands without casting. For **dynamic** `@…` strings, spread
* **`atRuleBlock` / `styles.atRuleBlock`**. Same idea for **`has` / `is` / `where`**: variadic literals narrow
* to `&:…` keys; if the key is only known as `string`, spread a one-key object or use `atRuleBlock`.
*/
interface CSSProperties extends CSS.Properties<CSSValue> {
/** Nested selector (e.g., '&:hover', `has('.x')`, '& .child', '&::before', '&[data-variant]') */
[selector: `&${string}`]: CSSProperties;
/**
* Ancestor-prefixed selector where `&` is the styled element (e.g. `html[data-mode="dark"] &`,
* `html:not([data-mode="light"]) &`). Runtime serialization replaces every `&` with the class selector.
*/
[selectorWithAncestor: `${string}&${string}`]: CSSProperties;
/** Attribute selector (e.g., '[data-variant]', '[data-variant="primary"]', '[disabled]') */
[attribute: `[${string}]`]: CSSProperties;
/** At-rule (e.g., '@media (max-width: 768px)', '@container', '@supports') */
[atRule: `@${string}`]: CSSProperties;
}
/**
* Utility function map used by styles.withUtils().
* Each key becomes an extra style property that expands into CSSProperties.
*/
type BivariantCallback<Arg, Ret> = {
bivarianceHack(value: Arg): Ret;
}['bivarianceHack'];
type StyleUtils = Record<string, BivariantCallback<unknown, CSSProperties>>;
type UtilityValue<U extends StyleUtils, K extends keyof U> = U[K] extends (value: infer V) => CSSProperties ? V : never;
/**
* CSS properties augmented with user-defined utility keys.
*/
type CSSPropertiesWithUtils<U extends StyleUtils> = CSS.Properties<CSSValue> & {
[K in keyof U]?: UtilityValue<U, K>;
} & {
[selector: `&${string}`]: CSSPropertiesWithUtils<U>;
[selectorWithAncestor: `${string}&${string}`]: CSSPropertiesWithUtils<U>;
[attribute: `[${string}]`]: CSSPropertiesWithUtils<U>;
[atRule: `@${string}`]: CSSPropertiesWithUtils<U>;
};
/**
* A map of style names to utility-aware CSS property definitions.
*/
type StyleDefinitionsWithUtils<U extends StyleUtils> = Record<string, CSSPropertiesWithUtils<U>>;
/**
* A map of variant names to their CSS property definitions.
*/
type StyleDefinitions = Record<string, CSSProperties>;
/**
* A token value can be a string/number or a nested object of token values.
* Supports arbitrarily deep nesting for hierarchical token structures.
*/
type TokenValues = string | number | {
[key: string]: TokenValues;
};
/**
* A flattened key-value pair for CSS custom property generation.
*/
type FlatTokenEntry = [key: string, value: string];
/**
* Flattens a nested TokenValues object into an array of [key, value] pairs.
* Deeply nested objects are flattened with keys joined by hyphens.
*
* @example
* flattenTokens({ text: { primary: '#000' } })
* // => [['text-primary', '#000']]
*/
declare function flattenTokenEntries(obj: TokenValues, prefix?: string): FlatTokenEntry[];
/**
* A typed token reference object. Property access returns var(--namespace-key).
* Supports nested access: token.text.primary => var(--namespace-text-primary)
*/
type TokenRef<T extends TokenValues> = T extends string | number ? string : {
readonly [K in keyof T]: T[K] extends TokenValues ? TokenRef<T[K]> : string;
};
/**
* Nested token values where any object level may omit keys (for mode layers that
* only tweak a subtree of `base`).
*/
type DeepPartialTokenValues = string | number | {
[key: string]: DeepPartialTokenValues | undefined;
};
/**
* Theme overrides: namespaces map to full or deeply partial token trees.
* Aligns with `tokens.create` namespaces; mode `overrides` often only set a subset of keys.
*/
type ThemeOverrides = {
[namespace: string]: DeepPartialTokenValues | undefined;
};
/**
* Keyframe stops: 'from', 'to', or percentage strings mapped to CSS properties.
*/
type KeyframeStops = Record<string, CSSProperties>;
/** Match a media query (e.g. `(prefers-color-scheme: dark)`). */
type ThemeConditionMedia = {
readonly type: 'media';
readonly query: string;
};
/** Match an attribute on the themed element (`self`) or an ancestor (`ancestor`). */
type ThemeConditionAttr = {
readonly type: 'attr';
readonly name: string;
readonly value: string;
readonly scope: 'self' | 'ancestor';
};
/** Match a class on the themed element (`self`) or an ancestor (`ancestor`). */
type ThemeConditionClass = {
readonly type: 'class';
readonly name: string;
readonly scope: 'self' | 'ancestor';
};
/** Raw selector escape hatch — the selector is used as an ancestor context for the theme class. */
type ThemeConditionSelector = {
readonly type: 'selector';
readonly selector: string;
};
/** All child conditions must hold. */
type ThemeConditionAnd = {
readonly type: 'and';
readonly conditions: readonly ThemeCondition[];
};
/** Any child condition must hold (emits separate rules per branch). */
type ThemeConditionOr = {
readonly type: 'or';
readonly conditions: readonly ThemeCondition[];
};
/** Negate a single-branch condition (see `tokens.when.not` JSDoc for limits). */
type ThemeConditionNot = {
readonly type: 'not';
readonly condition: ThemeCondition;
};
/**
* A condition that determines **when** a set of token overrides applies.
* Conditions compile to media queries, selector prefixes/suffixes, or combinations.
*/
type ThemeCondition = ThemeConditionMedia | ThemeConditionAttr | ThemeConditionClass | ThemeConditionSelector | ThemeConditionAnd | ThemeConditionOr | ThemeConditionNot;
/**
* A single mode layer within a theme surface.
* Applies `overrides` when `when` is satisfied.
*/
type ThemeModeDefinition = {
readonly id: string;
readonly overrides: ThemeOverrides;
readonly when: ThemeCondition;
};
/**
* Configuration for `tokens.createTheme()`.
* Provide `modes` (manual) **or** `colorMode` (preset), not both.
*/
type ThemeConfig = {
/** Base token overrides — emitted as `.theme-{name} { … }`. */
base?: ThemeOverrides;
/** Manual mode layers with explicit conditions. Mutually exclusive with `colorMode`. */
modes?: ThemeModeDefinition[];
/** Preset mode layers from `tokens.colorMode.*`. Mutually exclusive with `modes`. */
colorMode?: ThemeModeDefinition[];
};
/**
* The object returned by `tokens.createTheme()`.
*
* - `surface.className` — the generated class name (e.g. `"theme-acme"`)
* - `surface.name` — the theme name (e.g. `"acme"`)
* - `String(surface)` / template interpolation — coerces to `className`
*/
interface ThemeSurface {
readonly className: string;
readonly name: string;
toString(): string;
[Symbol.toPrimitive](hint: string): string;
}
/**
* Styles for a single variant option (or slot variant block).
* Union with a permissive record so **`[v.name]: value`** from {@link ComponentInternalVarRef}
* (custom properties) infers as `{ [key: string]: … }` and still matches — that shape is not
* assignable to {@link CSSProperties} alone, which would otherwise reject the dimensioned overload
* and fall through to unrelated `component` overloads. **`Record<string, unknown>`** also covers
* objects that mix custom-property keys with nested selector blocks like `'&:hover'`.
*/
type VariantOptionStyle = CSSProperties | Record<string, unknown>;
/**
* A map of variant dimensions to their options (each option is {@link VariantOptionStyle}).
*/
type VariantDefinitions = Record<string, Record<string, VariantOptionStyle>>;
type SlotStyles<S extends string> = Partial<Record<S, VariantOptionStyle>>;
type SlotVariantDefinitions<S extends string> = Record<string, Record<string, SlotStyles<S>>>;
type VariantDimensions = Record<string, Record<string, unknown>>;
type VariantOptionKey<V extends VariantDimensions, K extends keyof V> = Extract<keyof V[K], string>;
type VariantSelectionValue<OptionKey extends string> = OptionKey | (Extract<OptionKey, 'true'> extends never ? never : true) | (Extract<OptionKey, 'false'> extends never ? never : false);
type CompoundSelectionValue<OptionKey extends string> = VariantSelectionValue<OptionKey> | readonly VariantSelectionValue<OptionKey>[];
type ComponentSelections<V extends VariantDimensions> = {
[K in keyof V]?: VariantSelectionValue<VariantOptionKey<V, K>> | null | undefined;
};
/**
* A CSS custom property reference as a `var(--…)` value (tokens, `createVar()`, component internal vars).
*/
type CSSVarRef = `var(--${string})`;
/**
* Leaf shape for `ctx.vars({ … })` — mirrors typed tokens: `value` is the default (merged into `base`);
* optional `syntax` / `inherits` register `@property` like typed design tokens.
*/
type ComponentVarDescriptor = {
value: string | number;
syntax?: string;
inherits?: boolean;
};
/**
* Nested map of component internal vars (same nesting as `tokens.create` / theme token trees).
*/
type ComponentVarNode = string | number | ComponentVarDescriptor | {
[key: string]: ComponentVarNode;
};
type ComponentVarDefinitions = {
[key: string]: ComponentVarNode;
};
/**
* Options for `ctx.var(id, options?)`. Set `value` to merge a default into `base` and as `@property` initial-value when `syntax` is set.
*/
type ComponentVarOptions = {
value?: string | number;
syntax?: string;
inherits?: boolean;
};
/**
* Reference to a component-scoped custom property: `.name` for declaration keys and transitions, `.var` for values.
*/
type ComponentInternalVarRef = {
readonly name: string;
readonly var: CSSVarRef;
};
/**
* Context passed to `styles.component(namespace, (ctx) => { ... })` to declare internal custom properties.
*/
/** Proxy tree returned by `ctx.vars({ … })` — leaves are `{ name, var }`, nested objects are sub-trees. */
type ComponentVarRefTree<T> = {
[K in keyof T]: T[K] extends ComponentVarDescriptor | string | number ? ComponentInternalVarRef : ComponentVarRefTree<T[K]>;
};
type ComponentConfigContext = {
var: (id: string, options?: ComponentVarOptions) => ComponentInternalVarRef;
vars: <const T extends ComponentVarDefinitions>(definitions: T) => ComponentVarRefTree<T>;
};
/**
* The full config object passed to styles.component() with dimensioned variants.
*/
type ComponentConfig<V extends VariantDefinitions> = {
base?: CSSProperties;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: VariantOptionStyle;
}>;
defaultVariants?: ComponentSelections<V>;
};
/**
* Config for flat variants: `{ base: {...}, elevated: {...}, compact: {...} }`.
* Each key besides `base` is a boolean-style variant.
*
* **`variants`**, **`defaultVariants`**, **`compoundVariants`**, and **`slots`** are forbidden
* on this shape so TypeScript does not pick the flat overload for CVA-style or slot configs.
* Nested variant maps can otherwise satisfy {@link CSSProperties} too loosely (index signatures),
* which produced wrong callable types for `styles.component(ns, (ctx) => ({ variants: … }), { layer })`
* when cascade layers are enabled.
*/
type FlatComponentConfig<K extends string> = {
base?: CSSProperties;
variants?: never;
defaultVariants?: never;
compoundVariants?: never;
slots?: never;
} & Record<K, CSSProperties>;
/**
* Selection object for flat variants: `{ elevated: true, compact: true }`.
*/
type FlatComponentSelections<K extends string> = {
[P in K]?: boolean | null | undefined;
};
/**
* All possible variant class string keys that can be destructured from a
* dimensioned component. Includes 'base' plus all `{dimension}-{option}` keys
* flattened from the variants config.
*/
type DimensionedVariantKeys<V extends VariantDefinitions> = {
[D in keyof V]: keyof V[D] extends string ? `${D & string}-${keyof V[D] & string}` : never;
}[keyof V];
/**
* The CVA-style return for dimensioned variants.
* Callable as a function, destructurable as an object.
*/
type ComponentReturn<V extends VariantDefinitions> = {
/** Call with variant selections to get composed class string (base always included). */
(selections?: ComponentSelections<V>): string;
} & {
/** The base class string. */
readonly base: string;
} & {
/** Individual variant class strings, keyed as `{dimension}-{option}`. */
readonly [K in DimensionedVariantKeys<V>]: string;
};
/**
* The CVA-style return for flat variants.
* Callable as a function, destructurable as an object.
*/
type FlatComponentReturn<K extends string> = {
/** Call with variant selections to get composed class string (base always included). */
(selections?: FlatComponentSelections<Exclude<K, 'base'>>): string;
} & {
/** The base class string. */
readonly base: string;
} & {
/** Individual variant class strings. */
readonly [P in Exclude<K, 'base'>]: string;
};
type MultiSlotConfig<Slots extends readonly string[]> = {
slots: Slots;
} & Partial<Record<Slots[number], CSSProperties>>;
type MultiSlotReturn<Slots extends readonly string[]> = {
(): Record<Slots[number], string>;
} & {
readonly [K in Slots[number]]: string;
};
type SlotComponentConfig<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = {
slots: Slots;
base?: SlotStyles<Slots[number]>;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: SlotStyles<Slots[number]>;
}>;
defaultVariants?: ComponentSelections<V>;
};
type SlotComponentFunction<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = (selections?: ComponentSelections<V>) => Record<Slots[number], string>;
/**
* Config for `styles.component` may be a plain object or a function that receives {@link ComponentConfigContext}.
*/
type ComponentConfigInput<V extends VariantDefinitions> = ComponentConfig<V> | ((ctx: ComponentConfigContext) => ComponentConfig<V>);
type FlatComponentConfigInput<K extends string> = FlatComponentConfig<K> | ((ctx: ComponentConfigContext) => FlatComponentConfig<K>);
type SlotComponentConfigInput<Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>> = SlotComponentConfig<Slots, V> | ((ctx: ComponentConfigContext) => SlotComponentConfig<Slots, V>);
type MultiSlotConfigInput<Slots extends readonly string[]> = MultiSlotConfig<Slots> | ((ctx: ComponentConfigContext) => MultiSlotConfig<Slots>);
/**
* Extract the variant prop types from a ComponentReturn or ComponentFunction.
*
* @example
* ```ts
* const button = styles.component('button', {
* variants: {
* intent: { primary: {...}, ghost: {...} },
* size: { sm: {...}, lg: {...} },
* },
* });
*
* type ButtonProps = ComponentVariants<typeof button>;
* // { intent?: 'primary' | 'ghost'; size?: 'sm' | 'lg' }
* ```
*/
type ComponentVariants<T> = T extends (selections?: ComponentSelections<infer V>) => unknown ? {
[K in keyof V]?: keyof V[K];
} : never;
/**
* `src` value for {@link FontFaceProps}: a single CSS `src` fragment or multiple
* fragments joined with commas (same as authoring `url(...), local(...)` by hand).
*/
type FontFaceSrc = string | readonly string[];
/**
* Font face property declarations.
*
* Maps to standard `@font-face` descriptors. Values are emitted verbatim in CSS.
*/
type FontFaceProps = {
src: FontFaceSrc;
fontWeight?: string | number;
fontStyle?: 'normal' | 'italic' | 'oblique' | string;
fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
fontStretch?: string;
unicodeRange?: string;
/** `size-adjust` — fallback tuning and font-size-adjust related metrics. */
sizeAdjust?: string;
/** `ascent-override` */
ascentOverride?: string;
/** `descent-override` */
descentOverride?: string;
/** `line-gap-override` */
lineGapOverride?: string;
};
/**
* Return type of helpers in `typestyles/globals`, passed to `global.style(…)`.
*
* @example
* ```ts
* global.style(boxSizing());
* global.style(body({ margin: 0 }, { layer: 'components' }));
* ```
*/
type GlobalStyleTuple = readonly [selector: string, properties: CSSProperties] | readonly [selector: string, properties: CSSProperties, options: {
layer?: string;
}];
export { type ComponentSelections as A, type ComponentVarDefinitions as B, type CSSProperties as C, type ComponentVarDescriptor as D, type ComponentVarNode as E, type FlatComponentConfigInput as F, type GlobalStyleTuple as G, type ComponentVarOptions as H, type ComponentVarRefTree as I, type ComponentVariants as J, type DeepPartialTokenValues as K, type FlatComponentConfig as L, type MultiSlotConfigInput as M, type FlatComponentSelections as N, type FlatTokenEntry as O, type FontFaceSrc as P, type KeyframeStops as Q, type SlotComponentConfig as R, type SlotVariantDefinitions as S, type ThemeConditionMedia as T, type SlotStyles as U, type VariantDefinitions as V, type StyleDefinitions as W, type StyleDefinitionsWithUtils as X, type ThemeConditionNot as Y, type VariantOptionStyle as Z, flattenTokenEntries as _, type ThemeConditionAttr as a, type ThemeConditionClass as b, type ThemeConditionSelector as c, type ThemeCondition as d, type ThemeConditionAnd as e, type ThemeConditionOr as f, type ThemeOverrides as g, type ThemeModeDefinition as h, type ThemeSurface as i, type ThemeConfig as j, type TokenValues as k, type TokenRef as l, type ComponentConfigInput as m, type ComponentReturn as n, type FlatComponentReturn as o, type SlotComponentConfigInput as p, type SlotComponentFunction as q, type MultiSlotReturn as r, type StyleUtils as s, type CSSPropertiesWithUtils as t, type FontFaceProps as u, type CSSVarRef as v, type CSSValue as w, type ComponentConfig as x, type ComponentConfigContext as y, type ComponentInternalVarRef as z };
'use strict';
// src/globals.ts
function withLayer(tuple, layer) {
if (layer == null || layer === "") {
return tuple;
}
return [tuple[0], tuple[1], { layer }];
}
function reset(options) {
const layer = options?.layer;
const includeAppRoot = options?.includeAppRootIsolation !== false;
const htmlInterpolate = {
"@media (prefers-reduced-motion: no-preference)": {
interpolateSize: "allow-keywords"
}
};
const out = [
withLayer(["*, *::before, *::after", { boxSizing: "border-box" }], layer),
withLayer(["*:not(dialog)", { margin: 0 }], layer),
withLayer(["html", htmlInterpolate], layer),
withLayer(
[
"body",
{
lineHeight: 1.5,
WebkitFontSmoothing: "antialiased"
}
],
layer
),
withLayer(
[
"img, picture, video, canvas, svg",
{
display: "block",
maxWidth: "100%"
}
],
layer
),
withLayer(
[
"input, button, textarea, select",
{
font: "inherit"
}
],
layer
),
withLayer(
[
"p, h1, h2, h3, h4, h5, h6",
{
overflowWrap: "break-word"
}
],
layer
),
withLayer(["p", { textWrap: "pretty" }], layer),
withLayer(["h1, h2, h3, h4, h5, h6", { textWrap: "balance" }], layer)
];
if (includeAppRoot) {
out.push(withLayer(["#root, #__next", { isolation: "isolate" }], layer));
}
return out;
}
function boxSizing() {
return ["*, *::before, *::after", { boxSizing: "border-box" }];
}
var borderBox = boxSizing;
function body(properties, options) {
return options != null ? ["body", properties, options] : ["body", properties];
}
function selection(properties, options) {
return options != null ? ["::selection", properties, options] : ["::selection", properties];
}
function html(properties, options) {
return options != null ? ["html", properties, options] : ["html", properties];
}
exports.body = body;
exports.borderBox = borderBox;
exports.boxSizing = boxSizing;
exports.html = html;
exports.reset = reset;
exports.selection = selection;
//# sourceMappingURL=globals.cjs.map
//# sourceMappingURL=globals.cjs.map
{"version":3,"sources":["../src/globals.ts"],"names":[],"mappings":";;;AAoBA,SAAS,SAAA,CACP,OACA,KAAA,EACkB;AAClB,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,EAAA,EAAI;AACjC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,MAAM,CAAC,CAAA,EAAG,MAAM,CAAC,CAAA,EAAG,EAAE,KAAA,EAAO,CAAA;AACvC;AAwBO,SAAS,MAAM,OAAA,EAA+D;AACnF,EAAA,MAAM,QAAQ,OAAA,EAAS,KAAA;AACvB,EAAA,MAAM,cAAA,GAAiB,SAAS,uBAAA,KAA4B,KAAA;AAE5D,EAAA,MAAM,eAAA,GAAiC;AAAA,IACrC,gDAAA,EAAkD;AAAA,MAChD,eAAA,EAAiB;AAAA;AACnB,GACF;AAEA,EAAA,MAAM,GAAA,GAA0B;AAAA,IAC9B,SAAA,CAAU,CAAC,wBAAA,EAA0B,EAAE,WAAW,YAAA,EAAc,GAAG,KAAK,CAAA;AAAA,IACxE,SAAA,CAAU,CAAC,eAAA,EAAiB,EAAE,QAAQ,CAAA,EAAG,GAAG,KAAK,CAAA;AAAA,IACjD,SAAA,CAAU,CAAC,MAAA,EAAQ,eAAe,GAAG,KAAK,CAAA;AAAA,IAC1C,SAAA;AAAA,MACE;AAAA,QACE,MAAA;AAAA,QACA;AAAA,UACE,UAAA,EAAY,GAAA;AAAA,UACZ,mBAAA,EAAqB;AAAA;AACvB,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,kCAAA;AAAA,QACA;AAAA,UACE,OAAA,EAAS,OAAA;AAAA,UACT,QAAA,EAAU;AAAA;AACZ,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,iCAAA;AAAA,QACA;AAAA,UACE,IAAA,EAAM;AAAA;AACR,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,2BAAA;AAAA,QACA;AAAA,UACE,YAAA,EAAc;AAAA;AAChB,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA,CAAU,CAAC,GAAA,EAAK,EAAE,UAAU,QAAA,EAA2B,GAAG,KAAK,CAAA;AAAA,IAC/D,SAAA,CAAU,CAAC,wBAAA,EAA0B,EAAE,UAAU,SAAA,EAA4B,GAAG,KAAK;AAAA,GACvF;AAEA,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,CAAC,gBAAA,EAAkB,EAAE,WAAW,SAAA,EAAW,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EACzE;AAEA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,SAAA,GAA8B;AAC5C,EAAA,OAAO,CAAC,wBAAA,EAA0B,EAAE,SAAA,EAAW,cAAc,CAAA;AAC/D;AAGO,IAAM,SAAA,GAAY;AAGlB,SAAS,IAAA,CAAK,YAA2B,OAAA,EAAgD;AAC9F,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,MAAA,EAAQ,YAAY,OAAO,CAAA,GAAI,CAAC,MAAA,EAAQ,UAAU,CAAA;AAC9E;AAGO,SAAS,SAAA,CACd,YACA,OAAA,EACkB;AAClB,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,aAAA,EAAe,YAAY,OAAO,CAAA,GAAI,CAAC,aAAA,EAAe,UAAU,CAAA;AAC5F;AAGO,SAAS,IAAA,CAAK,YAA2B,OAAA,EAAgD;AAC9F,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,MAAA,EAAQ,YAAY,OAAO,CAAA,GAAI,CAAC,MAAA,EAAQ,UAAU,CAAA;AAC9E","file":"globals.cjs","sourcesContent":["import type { CSSProperties } from './types';\nimport type { GlobalStyleTuple } from './global-style-tuple';\n\nexport type { GlobalStyleTuple } from './global-style-tuple';\n\n/** Options for {@link reset} (Josh Comeau’s custom CSS reset). */\nexport type JoshComeauResetOptions = {\n /**\n * Include `#root, #__next { isolation: isolate }` from the\n * [original reset](https://www.joshwcomeau.com/css/custom-css-reset/).\n * @default true\n */\n includeAppRootIsolation?: boolean;\n /**\n * When set, each tuple includes `{ layer }` so the reset works with\n * `createGlobal({ layers })` / `createTypeStyles({ layers })` without a factory `globalLayer`.\n */\n layer?: string;\n};\n\nfunction withLayer(\n tuple: readonly [string, CSSProperties],\n layer: string | undefined,\n): GlobalStyleTuple {\n if (layer == null || layer === '') {\n return tuple;\n }\n return [tuple[0], tuple[1], { layer }];\n}\n\n/**\n * [Josh Comeau’s custom CSS reset](https://www.joshwcomeau.com/css/custom-css-reset/) as an array of\n * {@link GlobalStyleTuple}s — use with `global.apply(...reset())` or call `global.style` per tuple.\n *\n * With cascade layers, pass `{ layer: 'reset' }` (or your baseline layer) so these rules stay below\n * component layers — or set `globalLayer` on `createTypeStyles` / `createGlobal` and omit `layer` here.\n *\n * Released into the public domain by the author; this port keeps the same rules for convenience.\n *\n * @example\n * ```ts\n * import { createTypeStyles } from 'typestyles';\n * import { reset } from 'typestyles/globals';\n *\n * const { global } = createTypeStyles({\n * layers: ['reset', 'tokens', 'components'] as const,\n * tokenLayer: 'tokens',\n * globalLayer: 'reset',\n * });\n * global.apply(...reset({ includeAppRootIsolation: false }));\n * ```\n */\nexport function reset(options?: JoshComeauResetOptions): readonly GlobalStyleTuple[] {\n const layer = options?.layer;\n const includeAppRoot = options?.includeAppRootIsolation !== false;\n\n const htmlInterpolate: CSSProperties = {\n '@media (prefers-reduced-motion: no-preference)': {\n interpolateSize: 'allow-keywords',\n } as CSSProperties,\n };\n\n const out: GlobalStyleTuple[] = [\n withLayer(['*, *::before, *::after', { boxSizing: 'border-box' }], layer),\n withLayer(['*:not(dialog)', { margin: 0 }], layer),\n withLayer(['html', htmlInterpolate], layer),\n withLayer(\n [\n 'body',\n {\n lineHeight: 1.5,\n WebkitFontSmoothing: 'antialiased',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'img, picture, video, canvas, svg',\n {\n display: 'block',\n maxWidth: '100%',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'input, button, textarea, select',\n {\n font: 'inherit',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'p, h1, h2, h3, h4, h5, h6',\n {\n overflowWrap: 'break-word',\n },\n ],\n layer,\n ),\n withLayer(['p', { textWrap: 'pretty' } as CSSProperties], layer),\n withLayer(['h1, h2, h3, h4, h5, h6', { textWrap: 'balance' } as CSSProperties], layer),\n ];\n\n if (includeAppRoot) {\n out.push(withLayer(['#root, #__next', { isolation: 'isolate' }], layer));\n }\n\n return out;\n}\n\n/** `box-sizing: border-box` on the universal selector (safe with layered component padding). */\nexport function boxSizing(): GlobalStyleTuple {\n return ['*, *::before, *::after', { boxSizing: 'border-box' }];\n}\n\n/** Alias of {@link boxSizing}. */\nexport const borderBox = boxSizing;\n\n/** Styles applied to `body` (e.g. margin reset, background, base font). */\nexport function body(properties: CSSProperties, options?: { layer?: string }): GlobalStyleTuple {\n return options != null ? ['body', properties, options] : ['body', properties];\n}\n\n/** `::selection` colors. */\nexport function selection(\n properties: CSSProperties,\n options?: { layer?: string },\n): GlobalStyleTuple {\n return options != null ? ['::selection', properties, options] : ['::selection', properties];\n}\n\n/** Styles on the `html` element (e.g. font smoothing, scroll behavior). */\nexport function html(properties: CSSProperties, options?: { layer?: string }): GlobalStyleTuple {\n return options != null ? ['html', properties, options] : ['html', properties];\n}\n"]}
import { C as CSSProperties, G as GlobalStyleTuple } from './global-style-tuple-CDbP5BY3.cjs';
import 'csstype';
/** Options for {@link reset} (Josh Comeau’s custom CSS reset). */
type JoshComeauResetOptions = {
/**
* Include `#root, #__next { isolation: isolate }` from the
* [original reset](https://www.joshwcomeau.com/css/custom-css-reset/).
* @default true
*/
includeAppRootIsolation?: boolean;
/**
* When set, each tuple includes `{ layer }` so the reset works with
* `createGlobal({ layers })` / `createTypeStyles({ layers })` without a factory `globalLayer`.
*/
layer?: string;
};
/**
* [Josh Comeau’s custom CSS reset](https://www.joshwcomeau.com/css/custom-css-reset/) as an array of
* {@link GlobalStyleTuple}s — use with `global.apply(...reset())` or call `global.style` per tuple.
*
* With cascade layers, pass `{ layer: 'reset' }` (or your baseline layer) so these rules stay below
* component layers — or set `globalLayer` on `createTypeStyles` / `createGlobal` and omit `layer` here.
*
* Released into the public domain by the author; this port keeps the same rules for convenience.
*
* @example
* ```ts
* import { createTypeStyles } from 'typestyles';
* import { reset } from 'typestyles/globals';
*
* const { global } = createTypeStyles({
* layers: ['reset', 'tokens', 'components'] as const,
* tokenLayer: 'tokens',
* globalLayer: 'reset',
* });
* global.apply(...reset({ includeAppRootIsolation: false }));
* ```
*/
declare function reset(options?: JoshComeauResetOptions): readonly GlobalStyleTuple[];
/** `box-sizing: border-box` on the universal selector (safe with layered component padding). */
declare function boxSizing(): GlobalStyleTuple;
/** Alias of {@link boxSizing}. */
declare const borderBox: typeof boxSizing;
/** Styles applied to `body` (e.g. margin reset, background, base font). */
declare function body(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
/** `::selection` colors. */
declare function selection(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
/** Styles on the `html` element (e.g. font smoothing, scroll behavior). */
declare function html(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
export { GlobalStyleTuple, type JoshComeauResetOptions, body, borderBox, boxSizing, html, reset, selection };
import { C as CSSProperties, G as GlobalStyleTuple } from './global-style-tuple-CDbP5BY3.js';
import 'csstype';
/** Options for {@link reset} (Josh Comeau’s custom CSS reset). */
type JoshComeauResetOptions = {
/**
* Include `#root, #__next { isolation: isolate }` from the
* [original reset](https://www.joshwcomeau.com/css/custom-css-reset/).
* @default true
*/
includeAppRootIsolation?: boolean;
/**
* When set, each tuple includes `{ layer }` so the reset works with
* `createGlobal({ layers })` / `createTypeStyles({ layers })` without a factory `globalLayer`.
*/
layer?: string;
};
/**
* [Josh Comeau’s custom CSS reset](https://www.joshwcomeau.com/css/custom-css-reset/) as an array of
* {@link GlobalStyleTuple}s — use with `global.apply(...reset())` or call `global.style` per tuple.
*
* With cascade layers, pass `{ layer: 'reset' }` (or your baseline layer) so these rules stay below
* component layers — or set `globalLayer` on `createTypeStyles` / `createGlobal` and omit `layer` here.
*
* Released into the public domain by the author; this port keeps the same rules for convenience.
*
* @example
* ```ts
* import { createTypeStyles } from 'typestyles';
* import { reset } from 'typestyles/globals';
*
* const { global } = createTypeStyles({
* layers: ['reset', 'tokens', 'components'] as const,
* tokenLayer: 'tokens',
* globalLayer: 'reset',
* });
* global.apply(...reset({ includeAppRootIsolation: false }));
* ```
*/
declare function reset(options?: JoshComeauResetOptions): readonly GlobalStyleTuple[];
/** `box-sizing: border-box` on the universal selector (safe with layered component padding). */
declare function boxSizing(): GlobalStyleTuple;
/** Alias of {@link boxSizing}. */
declare const borderBox: typeof boxSizing;
/** Styles applied to `body` (e.g. margin reset, background, base font). */
declare function body(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
/** `::selection` colors. */
declare function selection(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
/** Styles on the `html` element (e.g. font smoothing, scroll behavior). */
declare function html(properties: CSSProperties, options?: {
layer?: string;
}): GlobalStyleTuple;
export { GlobalStyleTuple, type JoshComeauResetOptions, body, borderBox, boxSizing, html, reset, selection };
import './chunk-PZ5AY32C.js';
// src/globals.ts
function withLayer(tuple, layer) {
if (layer == null || layer === "") {
return tuple;
}
return [tuple[0], tuple[1], { layer }];
}
function reset(options) {
const layer = options?.layer;
const includeAppRoot = options?.includeAppRootIsolation !== false;
const htmlInterpolate = {
"@media (prefers-reduced-motion: no-preference)": {
interpolateSize: "allow-keywords"
}
};
const out = [
withLayer(["*, *::before, *::after", { boxSizing: "border-box" }], layer),
withLayer(["*:not(dialog)", { margin: 0 }], layer),
withLayer(["html", htmlInterpolate], layer),
withLayer(
[
"body",
{
lineHeight: 1.5,
WebkitFontSmoothing: "antialiased"
}
],
layer
),
withLayer(
[
"img, picture, video, canvas, svg",
{
display: "block",
maxWidth: "100%"
}
],
layer
),
withLayer(
[
"input, button, textarea, select",
{
font: "inherit"
}
],
layer
),
withLayer(
[
"p, h1, h2, h3, h4, h5, h6",
{
overflowWrap: "break-word"
}
],
layer
),
withLayer(["p", { textWrap: "pretty" }], layer),
withLayer(["h1, h2, h3, h4, h5, h6", { textWrap: "balance" }], layer)
];
if (includeAppRoot) {
out.push(withLayer(["#root, #__next", { isolation: "isolate" }], layer));
}
return out;
}
function boxSizing() {
return ["*, *::before, *::after", { boxSizing: "border-box" }];
}
var borderBox = boxSizing;
function body(properties, options) {
return options != null ? ["body", properties, options] : ["body", properties];
}
function selection(properties, options) {
return options != null ? ["::selection", properties, options] : ["::selection", properties];
}
function html(properties, options) {
return options != null ? ["html", properties, options] : ["html", properties];
}
export { body, borderBox, boxSizing, html, reset, selection };
//# sourceMappingURL=globals.js.map
//# sourceMappingURL=globals.js.map
{"version":3,"sources":["../src/globals.ts"],"names":[],"mappings":";;;AAoBA,SAAS,SAAA,CACP,OACA,KAAA,EACkB;AAClB,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,EAAA,EAAI;AACjC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,MAAM,CAAC,CAAA,EAAG,MAAM,CAAC,CAAA,EAAG,EAAE,KAAA,EAAO,CAAA;AACvC;AAwBO,SAAS,MAAM,OAAA,EAA+D;AACnF,EAAA,MAAM,QAAQ,OAAA,EAAS,KAAA;AACvB,EAAA,MAAM,cAAA,GAAiB,SAAS,uBAAA,KAA4B,KAAA;AAE5D,EAAA,MAAM,eAAA,GAAiC;AAAA,IACrC,gDAAA,EAAkD;AAAA,MAChD,eAAA,EAAiB;AAAA;AACnB,GACF;AAEA,EAAA,MAAM,GAAA,GAA0B;AAAA,IAC9B,SAAA,CAAU,CAAC,wBAAA,EAA0B,EAAE,WAAW,YAAA,EAAc,GAAG,KAAK,CAAA;AAAA,IACxE,SAAA,CAAU,CAAC,eAAA,EAAiB,EAAE,QAAQ,CAAA,EAAG,GAAG,KAAK,CAAA;AAAA,IACjD,SAAA,CAAU,CAAC,MAAA,EAAQ,eAAe,GAAG,KAAK,CAAA;AAAA,IAC1C,SAAA;AAAA,MACE;AAAA,QACE,MAAA;AAAA,QACA;AAAA,UACE,UAAA,EAAY,GAAA;AAAA,UACZ,mBAAA,EAAqB;AAAA;AACvB,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,kCAAA;AAAA,QACA;AAAA,UACE,OAAA,EAAS,OAAA;AAAA,UACT,QAAA,EAAU;AAAA;AACZ,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,iCAAA;AAAA,QACA;AAAA,UACE,IAAA,EAAM;AAAA;AACR,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,MACE;AAAA,QACE,2BAAA;AAAA,QACA;AAAA,UACE,YAAA,EAAc;AAAA;AAChB,OACF;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA,CAAU,CAAC,GAAA,EAAK,EAAE,UAAU,QAAA,EAA2B,GAAG,KAAK,CAAA;AAAA,IAC/D,SAAA,CAAU,CAAC,wBAAA,EAA0B,EAAE,UAAU,SAAA,EAA4B,GAAG,KAAK;AAAA,GACvF;AAEA,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,CAAC,gBAAA,EAAkB,EAAE,WAAW,SAAA,EAAW,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EACzE;AAEA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,SAAA,GAA8B;AAC5C,EAAA,OAAO,CAAC,wBAAA,EAA0B,EAAE,SAAA,EAAW,cAAc,CAAA;AAC/D;AAGO,IAAM,SAAA,GAAY;AAGlB,SAAS,IAAA,CAAK,YAA2B,OAAA,EAAgD;AAC9F,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,MAAA,EAAQ,YAAY,OAAO,CAAA,GAAI,CAAC,MAAA,EAAQ,UAAU,CAAA;AAC9E;AAGO,SAAS,SAAA,CACd,YACA,OAAA,EACkB;AAClB,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,aAAA,EAAe,YAAY,OAAO,CAAA,GAAI,CAAC,aAAA,EAAe,UAAU,CAAA;AAC5F;AAGO,SAAS,IAAA,CAAK,YAA2B,OAAA,EAAgD;AAC9F,EAAA,OAAO,OAAA,IAAW,OAAO,CAAC,MAAA,EAAQ,YAAY,OAAO,CAAA,GAAI,CAAC,MAAA,EAAQ,UAAU,CAAA;AAC9E","file":"globals.js","sourcesContent":["import type { CSSProperties } from './types';\nimport type { GlobalStyleTuple } from './global-style-tuple';\n\nexport type { GlobalStyleTuple } from './global-style-tuple';\n\n/** Options for {@link reset} (Josh Comeau’s custom CSS reset). */\nexport type JoshComeauResetOptions = {\n /**\n * Include `#root, #__next { isolation: isolate }` from the\n * [original reset](https://www.joshwcomeau.com/css/custom-css-reset/).\n * @default true\n */\n includeAppRootIsolation?: boolean;\n /**\n * When set, each tuple includes `{ layer }` so the reset works with\n * `createGlobal({ layers })` / `createTypeStyles({ layers })` without a factory `globalLayer`.\n */\n layer?: string;\n};\n\nfunction withLayer(\n tuple: readonly [string, CSSProperties],\n layer: string | undefined,\n): GlobalStyleTuple {\n if (layer == null || layer === '') {\n return tuple;\n }\n return [tuple[0], tuple[1], { layer }];\n}\n\n/**\n * [Josh Comeau’s custom CSS reset](https://www.joshwcomeau.com/css/custom-css-reset/) as an array of\n * {@link GlobalStyleTuple}s — use with `global.apply(...reset())` or call `global.style` per tuple.\n *\n * With cascade layers, pass `{ layer: 'reset' }` (or your baseline layer) so these rules stay below\n * component layers — or set `globalLayer` on `createTypeStyles` / `createGlobal` and omit `layer` here.\n *\n * Released into the public domain by the author; this port keeps the same rules for convenience.\n *\n * @example\n * ```ts\n * import { createTypeStyles } from 'typestyles';\n * import { reset } from 'typestyles/globals';\n *\n * const { global } = createTypeStyles({\n * layers: ['reset', 'tokens', 'components'] as const,\n * tokenLayer: 'tokens',\n * globalLayer: 'reset',\n * });\n * global.apply(...reset({ includeAppRootIsolation: false }));\n * ```\n */\nexport function reset(options?: JoshComeauResetOptions): readonly GlobalStyleTuple[] {\n const layer = options?.layer;\n const includeAppRoot = options?.includeAppRootIsolation !== false;\n\n const htmlInterpolate: CSSProperties = {\n '@media (prefers-reduced-motion: no-preference)': {\n interpolateSize: 'allow-keywords',\n } as CSSProperties,\n };\n\n const out: GlobalStyleTuple[] = [\n withLayer(['*, *::before, *::after', { boxSizing: 'border-box' }], layer),\n withLayer(['*:not(dialog)', { margin: 0 }], layer),\n withLayer(['html', htmlInterpolate], layer),\n withLayer(\n [\n 'body',\n {\n lineHeight: 1.5,\n WebkitFontSmoothing: 'antialiased',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'img, picture, video, canvas, svg',\n {\n display: 'block',\n maxWidth: '100%',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'input, button, textarea, select',\n {\n font: 'inherit',\n },\n ],\n layer,\n ),\n withLayer(\n [\n 'p, h1, h2, h3, h4, h5, h6',\n {\n overflowWrap: 'break-word',\n },\n ],\n layer,\n ),\n withLayer(['p', { textWrap: 'pretty' } as CSSProperties], layer),\n withLayer(['h1, h2, h3, h4, h5, h6', { textWrap: 'balance' } as CSSProperties], layer),\n ];\n\n if (includeAppRoot) {\n out.push(withLayer(['#root, #__next', { isolation: 'isolate' }], layer));\n }\n\n return out;\n}\n\n/** `box-sizing: border-box` on the universal selector (safe with layered component padding). */\nexport function boxSizing(): GlobalStyleTuple {\n return ['*, *::before, *::after', { boxSizing: 'border-box' }];\n}\n\n/** Alias of {@link boxSizing}. */\nexport const borderBox = boxSizing;\n\n/** Styles applied to `body` (e.g. margin reset, background, base font). */\nexport function body(properties: CSSProperties, options?: { layer?: string }): GlobalStyleTuple {\n return options != null ? ['body', properties, options] : ['body', properties];\n}\n\n/** `::selection` colors. */\nexport function selection(\n properties: CSSProperties,\n options?: { layer?: string },\n): GlobalStyleTuple {\n return options != null ? ['::selection', properties, options] : ['::selection', properties];\n}\n\n/** Styles on the `html` element (e.g. font smoothing, scroll behavior). */\nexport function html(properties: CSSProperties, options?: { layer?: string }): GlobalStyleTuple {\n return options != null ? ['html', properties, options] : ['html', properties];\n}\n"]}
/**
* Ensure the managed <style id="typestyles"> is attached to the current document and populated.
* Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.
*/
declare function ensureDocumentStylesAttached(): void;
/**
* Insert multiple CSS rules at once.
*/
declare function insertRules(rules: Array<{
key: string;
css: string;
}>): void;
/**
* Return all registered CSS as a string.
*
* Unlike `collectStyles`, this doesn't require wrapping a render function.
* It simply returns every CSS rule that has been registered via
* `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.
*
* Ideal for SSR frameworks that need the CSS separately from the render
* pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).
*
* @example
* ```ts
* import { getRegisteredCss } from 'typestyles/server';
*
* // In a route's head/meta function:
* export const head = () => ({
* styles: [{ id: 'typestyles', children: getRegisteredCss() }],
* });
* ```
*/
declare function getRegisteredCss(): string;
/**
* Reset all state (useful for testing).
*/
declare function reset(): void;
/**
* Flush all pending rules synchronously. Used for SSR and testing.
*/
declare function flushSync(): void;
/**
* Invalidate all dedup keys that start with the given prefix.
* Also removes matching rules from the live stylesheet.
* Used for HMR — allows modules to re-register their styles after editing.
*/
declare function invalidatePrefix(prefix: string): void;
/**
* Invalidate a list of exact keys or prefixes.
* Each entry in `keys` is treated as an exact key match.
* Each entry in `prefixes` is treated as a prefix match.
* Used for HMR to invalidate all styles from a module at once.
*/
declare function invalidateKeys(keys: string[], prefixes: string[]): void;
export { invalidateKeys as a, invalidatePrefix as b, ensureDocumentStylesAttached as e, flushSync as f, getRegisteredCss as g, insertRules as i, reset as r };
/**
* Ensure the managed <style id="typestyles"> is attached to the current document and populated.
* Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.
*/
declare function ensureDocumentStylesAttached(): void;
/**
* Insert multiple CSS rules at once.
*/
declare function insertRules(rules: Array<{
key: string;
css: string;
}>): void;
/**
* Return all registered CSS as a string.
*
* Unlike `collectStyles`, this doesn't require wrapping a render function.
* It simply returns every CSS rule that has been registered via
* `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.
*
* Ideal for SSR frameworks that need the CSS separately from the render
* pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).
*
* @example
* ```ts
* import { getRegisteredCss } from 'typestyles/server';
*
* // In a route's head/meta function:
* export const head = () => ({
* styles: [{ id: 'typestyles', children: getRegisteredCss() }],
* });
* ```
*/
declare function getRegisteredCss(): string;
/**
* Reset all state (useful for testing).
*/
declare function reset(): void;
/**
* Flush all pending rules synchronously. Used for SSR and testing.
*/
declare function flushSync(): void;
/**
* Invalidate all dedup keys that start with the given prefix.
* Also removes matching rules from the live stylesheet.
* Used for HMR — allows modules to re-register their styles after editing.
*/
declare function invalidatePrefix(prefix: string): void;
/**
* Invalidate a list of exact keys or prefixes.
* Each entry in `keys` is treated as an exact key match.
* Each entry in `prefixes` is treated as a prefix match.
* Used for HMR to invalidate all styles from a module at once.
*/
declare function invalidateKeys(keys: string[], prefixes: string[]): void;
export { invalidateKeys as a, invalidatePrefix as b, ensureDocumentStylesAttached as e, flushSync as f, getRegisteredCss as g, insertRules as i, reset as r };
+31
-5

@@ -5,13 +5,36 @@ 'use strict';

var STYLE_ELEMENT_ID = "typestyles";
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true";
function readNextPublicRuntimeDisabled() {
if (typeof process === "undefined" || !process.env) return false;
return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === "true";
}
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true" || readNextPublicRuntimeDisabled();
var pendingRules = [];
var allRules = [];
var styleElement = null;
var ssrBuffer = null;
var isBrowser = typeof document !== "undefined" && typeof window !== "undefined";
function writeAllRulesToStyleElement(el) {
if (RUNTIME_DISABLED || allRules.length === 0) return;
const sheet = el.sheet;
if (sheet) {
for (const css of allRules) {
try {
sheet.insertRule(css, sheet.cssRules.length);
} catch {
el.appendChild(document.createTextNode(css));
}
}
} else {
el.appendChild(document.createTextNode(allRules.join("\n")));
}
}
function getStyleElement() {
let reconnectAfterDetach = false;
if (styleElement && !styleElement.isConnected) {
reconnectAfterDetach = true;
styleElement = null;
}
if (styleElement) return styleElement;
const existing = document.getElementById(
STYLE_ELEMENT_ID
);
if (existing) {
const existing = document.getElementById(STYLE_ELEMENT_ID);
if (existing?.isConnected) {
styleElement = existing;

@@ -23,2 +46,5 @@ return styleElement;

document.head.appendChild(styleElement);
if (reconnectAfterDetach && allRules.length > 0) {
writeAllRulesToStyleElement(styleElement);
}
return styleElement;

@@ -25,0 +51,0 @@ }

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/sheet.ts","../src/build.ts"],"names":[],"mappings":";;;AAAA,IAAM,gBAAA,GAAmB,YAAA;AAazB,IAAM,gBAAA,GACJ,OAAO,+BAAA,KAAoC,WAAA,IAC3C,+BAAA,KAAoC,MAAA;AAKtC,IAAI,eAAyB,EAAC;AAiB9B,IAAI,YAAA,GAAwC,IAAA;AAK5C,IAAI,SAAA,GAA6B,IAAA;AAKjC,IAAM,SAAA,GACJ,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,MAAA,KAAW,WAAA;AAEvD,SAAS,eAAA,GAAoC;AAC3C,EAAA,IAAI,cAAc,OAAO,YAAA;AAGzB,EAAA,MAAM,WAAW,QAAA,CAAS,cAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,YAAA,GAAe,QAAA;AACf,IAAA,OAAO,YAAA;AAAA,EACT;AAGA,EAAA,YAAA,GAAe,QAAA,CAAS,cAAc,OAAO,CAAA;AAC7C,EAAA,YAAA,CAAa,EAAA,GAAK,gBAAA;AAClB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,YAAY,CAAA;AACtC,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,KAAA,GAAc;AAErB,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE/B,EAAA,MAAM,KAAA,GAAQ,YAAA;AACd,EAAA,YAAA,GAAe,EAAC;AAEhB,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,SAAA,CAAU,IAAA,CAAK,GAAG,KAAK,CAAA;AACvB,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,aAAa,gBAAA,EAAkB;AAEpC,EAAA,MAAM,KAAK,eAAA,EAAgB;AAC3B,EAAA,MAAM,QAAQ,EAAA,CAAG,KAAA;AAEjB,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI;AACF,QAAA,KAAA,CAAM,UAAA,CAAW,IAAA,EAAM,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAEN,QAAA,EAAA,CAAG,WAAA,CAAY,QAAA,CAAS,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AAEL,IAAA,EAAA,CAAG,YAAY,QAAA,CAAS,cAAA,CAAe,MAAM,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA;AAAA,EAC1D;AACF;AAuEO,SAAS,eAAA,GAAgC;AAC9C,EAAA,SAAA,GAAY,EAAC;AACb,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,GAAA,GAAM,SAAA,GAAY,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AAC/C,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AACF;AA4CO,SAAS,SAAA,GAAkB;AAChC,EAAA,KAAA,EAAM;AACR;;;AC5MA,eAAsB,yBACpB,OAAA,EACiB;AACjB,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAK1B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb;AAEA,EAAA,SAAA,EAAU;AACV,EAAA,OAAO,aAAA,EAAc;AACvB","file":"build.cjs","sourcesContent":["const STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nconst RUNTIME_DISABLED =\n typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true';\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser =\n typeof document !== 'undefined' && typeof window !== 'undefined';\n\nfunction getStyleElement(): HTMLStyleElement {\n if (styleElement) return styleElement;\n\n // Check for an existing element (e.g., from SSR)\n const existing = document.getElementById(\n STYLE_ELEMENT_ID\n ) as HTMLStyleElement | null;\n if (existing) {\n styleElement = existing;\n return styleElement;\n }\n\n // Create a new one\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n return styleElement;\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) continue;\n insertedRules.add(key);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.create`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return (\n rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`)\n );\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color -> :root rule with --color- custom properties\n const namespace = key.slice('tokens:'.length);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n","import { startCollection, flushSync } from './sheet.js';\n\n/**\n * Collect all CSS generated by executing one or more loader functions.\n *\n * This is a low-level primitive intended for build tools (Vite, Next.js, etc.)\n * to implement a zero-runtime extraction step.\n *\n * Example usage (Vite/Node):\n *\n * ```ts\n * import { collectStylesFromModules } from 'typestyles/build';\n *\n * const css = await collectStylesFromModules([\n * () => import('./src/styles'),\n * () => import('./src/tokens'),\n * ]);\n * ```\n */\nexport async function collectStylesFromModules(\n loaders: Array<() => unknown | Promise<unknown>>\n): Promise<string> {\n const endCollection = startCollection();\n\n for (const load of loaders) {\n // Each loader can synchronously or asynchronously import modules that\n // register typestyles styles, tokens, keyframes, etc.\n // We await in case a loader returns a promise (e.g. dynamic import).\n // The return value itself is ignored; only the side effects matter.\n await load();\n }\n\n flushSync();\n return endCollection();\n}\n\n"]}
{"version":3,"sources":["../src/sheet.ts","../src/build.ts"],"names":[],"mappings":"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","file":"build.cjs","sourcesContent":["import {\n namespacesFromTypestylesHmrPrefixes,\n releaseReservedNamespacesForComponentOrClassNames,\n} from './registry';\n\nconst STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Last emitted CSS per dedupe key (see {@link warnIfDuplicateRuleKeyConflict}).\n * Cleared with {@link reset} and kept in sync when keys are invalidated.\n */\nconst ruleCssByKey = new Map<string, string>();\n\nfunction duplicateRuleKeyConflictWarningsEnabled(): boolean {\n if (typeof process === 'undefined') return true;\n return process.env.NODE_ENV !== 'production';\n}\n\n/**\n * When the same key is registered again with different CSS, the second rule is skipped\n * (idempotency / HMR). In non-production builds, surface that so overlapping globals\n * (e.g. reset `body` + app `body` in the same scope) are not silent failures.\n */\nfunction warnIfDuplicateRuleKeyConflict(\n key: string,\n previousCss: string,\n ignoredCss: string,\n): void {\n if (!duplicateRuleKeyConflictWarningsEnabled()) return;\n const prevShort = previousCss.length > 220 ? `${previousCss.slice(0, 220)}…` : previousCss;\n const nextShort = ignoredCss.length > 220 ? `${ignoredCss.slice(0, 220)}…` : ignoredCss;\n console.warn(\n `[typestyles] Skipped a rule: dedupe key \"${key}\" already exists with different CSS. ` +\n `Only the first registration is kept. For globals, merge into one \\`global.style\\`, ` +\n `or use a distinct selector (e.g. \\`html body\\` after reset’s \\`body\\`).\\n` +\n ` Existing: ${prevShort}\\n` +\n ` Skipped: ${nextShort}`,\n );\n}\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n *\n * `@typestyles/next/build` `withTypestylesExtract` sets `NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED`\n * via `next.config` `env` so Turbopack and webpack both inline the flag (DefinePlugin\n * alone does not run under Turbopack).\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nfunction readNextPublicRuntimeDisabled(): boolean {\n if (typeof process === 'undefined' || !process.env) return false;\n return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === 'true';\n}\nconst RUNTIME_DISABLED =\n (typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true') ||\n readNextPublicRuntimeDisabled();\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser = typeof document !== 'undefined' && typeof window !== 'undefined';\n\n/**\n * Re-insert every registered rule into a (usually fresh) <style> element.\n * Used when the live element was detached (e.g. Astro view transitions replacing <head>).\n */\nfunction writeAllRulesToStyleElement(el: HTMLStyleElement): void {\n if (RUNTIME_DISABLED || allRules.length === 0) return;\n const sheet = el.sheet;\n if (sheet) {\n for (const css of allRules) {\n try {\n sheet.insertRule(css, sheet.cssRules.length);\n } catch {\n el.appendChild(document.createTextNode(css));\n }\n }\n } else {\n el.appendChild(document.createTextNode(allRules.join('\\n')));\n }\n}\n\nfunction getStyleElement(): HTMLStyleElement {\n let reconnectAfterDetach = false;\n if (styleElement && !styleElement.isConnected) {\n reconnectAfterDetach = true;\n styleElement = null;\n }\n if (styleElement) return styleElement;\n\n // Prefer an element actually in the document (SSR or another copy on the page).\n const existing = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement | null;\n if (existing?.isConnected) {\n styleElement = existing;\n return styleElement;\n }\n\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n\n // After a doc swap, we have a new empty sheet but insertRule() won't re-queue (deduped keys).\n if (reconnectAfterDetach && allRules.length > 0) {\n writeAllRulesToStyleElement(styleElement);\n }\n\n return styleElement;\n}\n\n/**\n * Ensure the managed <style id=\"typestyles\"> is attached to the current document and populated.\n * Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.\n */\nexport function ensureDocumentStylesAttached(): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n getStyleElement();\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Register a single `@layer a, b, c;` preamble so layer **order** is defined before any\n * `@layer name { … }` blocks. Inserts at the front of the virtual sheet and at CSSOM index 0\n * when injecting into the document.\n */\nexport function registerCascadeLayerOrder(preambleKey: string, css: string): void {\n const key = `typestyles:@layer-order:${preambleKey}`;\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n\n allRules.unshift(css);\n\n if (ssrBuffer) {\n ssrBuffer.unshift(css);\n return;\n }\n\n if (RUNTIME_DISABLED) return;\n\n if (!isBrowser) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n try {\n sheet.insertRule(css, 0);\n } catch {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n } else {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n return;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n continue;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n ruleCssByKey.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Drop every rule key tied to a `styles.component('namespace', …)` registration, including\n * `@layer`-wrapped keys (`layer:….:.namespace-…`), and release reserved namespace entries.\n * Used for Vite HMR and for dev recovery when a module re-runs before `hot.dispose`.\n */\nexport function invalidateComponentNamespaceForDev(namespace: string): void {\n const selectorInfix = `.${namespace}-`;\n const keysToDrop: string[] = [];\n for (const k of insertedRules) {\n if (k.includes(selectorInfix)) {\n keysToDrop.push(k);\n }\n }\n invalidateKeys(keysToDrop, [selectorInfix]);\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`);\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color or tokens:color@layerName -> :root rule with --color- custom properties\n const rest = key.slice('tokens:'.length);\n const at = rest.lastIndexOf('@');\n const namespace = at === -1 ? rest : rest.slice(0, at);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n","import { startCollection, flushSync } from './sheet';\n\n/**\n * Collect all CSS generated by executing one or more loader functions.\n *\n * This is a low-level primitive intended for build tools (Vite, Next.js, etc.)\n * to implement a zero-runtime extraction step.\n *\n * Example usage (Vite/Node):\n *\n * ```ts\n * import { collectStylesFromModules } from 'typestyles/build';\n *\n * const css = await collectStylesFromModules([\n * () => import('./src/styles'),\n * () => import('./src/tokens'),\n * ]);\n * ```\n */\nexport async function collectStylesFromModules(\n loaders: Array<() => unknown | Promise<unknown>>,\n): Promise<string> {\n const endCollection = startCollection();\n\n for (const load of loaders) {\n // Each loader can synchronously or asynchronously import modules that\n // register typestyles styles, tokens, keyframes, etc.\n // We await in case a loader returns a promise (e.g. dynamic import).\n // The return value itself is ignored; only the side effects matter.\n await load();\n }\n\n flushSync();\n return endCollection();\n}\n"]}

@@ -1,2 +0,3 @@

import { startCollection, flushSync } from './chunk-AYFIQGCF.js';
import { startCollection, flushSync } from './chunk-G6ATUNEZ.js';
import './chunk-PZ5AY32C.js';

@@ -3,0 +4,0 @@ // src/build.ts

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/build.ts"],"names":[],"mappings":";;;AAmBA,eAAsB,yBACpB,OAAA,EACiB;AACjB,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAK1B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb;AAEA,EAAA,SAAA,EAAU;AACV,EAAA,OAAO,aAAA,EAAc;AACvB","file":"build.js","sourcesContent":["import { startCollection, flushSync } from './sheet.js';\n\n/**\n * Collect all CSS generated by executing one or more loader functions.\n *\n * This is a low-level primitive intended for build tools (Vite, Next.js, etc.)\n * to implement a zero-runtime extraction step.\n *\n * Example usage (Vite/Node):\n *\n * ```ts\n * import { collectStylesFromModules } from 'typestyles/build';\n *\n * const css = await collectStylesFromModules([\n * () => import('./src/styles'),\n * () => import('./src/tokens'),\n * ]);\n * ```\n */\nexport async function collectStylesFromModules(\n loaders: Array<() => unknown | Promise<unknown>>\n): Promise<string> {\n const endCollection = startCollection();\n\n for (const load of loaders) {\n // Each loader can synchronously or asynchronously import modules that\n // register typestyles styles, tokens, keyframes, etc.\n // We await in case a loader returns a promise (e.g. dynamic import).\n // The return value itself is ignored; only the side effects matter.\n await load();\n }\n\n flushSync();\n return endCollection();\n}\n\n"]}
{"version":3,"sources":["../src/build.ts"],"names":[],"mappings":";;;;AAmBA,eAAsB,yBACpB,OAAA,EACiB;AACjB,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAK1B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb;AAEA,EAAA,SAAA,EAAU;AACV,EAAA,OAAO,aAAA,EAAc;AACvB","file":"build.js","sourcesContent":["import { startCollection, flushSync } from './sheet';\n\n/**\n * Collect all CSS generated by executing one or more loader functions.\n *\n * This is a low-level primitive intended for build tools (Vite, Next.js, etc.)\n * to implement a zero-runtime extraction step.\n *\n * Example usage (Vite/Node):\n *\n * ```ts\n * import { collectStylesFromModules } from 'typestyles/build';\n *\n * const css = await collectStylesFromModules([\n * () => import('./src/styles'),\n * () => import('./src/tokens'),\n * ]);\n * ```\n */\nexport async function collectStylesFromModules(\n loaders: Array<() => unknown | Promise<unknown>>,\n): Promise<string> {\n const endCollection = startCollection();\n\n for (const load of loaders) {\n // Each loader can synchronously or asynchronously import modules that\n // register typestyles styles, tokens, keyframes, etc.\n // We await in case a loader returns a promise (e.g. dynamic import).\n // The return value itself is ignored; only the side effects matter.\n await load();\n }\n\n flushSync();\n return endCollection();\n}\n"]}
'use strict';
// src/registry.ts
var registeredNamespaces = /* @__PURE__ */ new Set();
var COLON = ":";
function releaseReservedNamespacesForComponentOrClassNames(namespaces) {
if (namespaces.length === 0) return;
const wanted = new Set(namespaces);
const toRemove = [];
for (const key of registeredNamespaces) {
const i = key.indexOf(COLON);
if (i === -1) continue;
if (wanted.has(key.slice(i + 1))) {
toRemove.push(key);
}
}
for (const key of toRemove) {
registeredNamespaces.delete(key);
}
}
function namespacesFromTypestylesHmrPrefixes(prefixes) {
const out = [];
for (const p of prefixes) {
if (p.length >= 2 && p.startsWith(".") && p.endsWith("-")) {
out.push(p.slice(1, -1));
}
}
return out;
}
// src/sheet.ts
var insertedRules = /* @__PURE__ */ new Set();
typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true";
var ruleCssByKey = /* @__PURE__ */ new Map();
function readNextPublicRuntimeDisabled() {
if (typeof process === "undefined" || !process.env) return false;
return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === "true";
}
typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true" || readNextPublicRuntimeDisabled();
var isBrowser = typeof document !== "undefined" && typeof window !== "undefined";

@@ -11,4 +44,6 @@ function invalidatePrefix(prefix) {

insertedRules.delete(key);
ruleCssByKey.delete(key);
}
}
releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));
if (!isBrowser) return;

@@ -20,2 +55,3 @@ return;

insertedRules.delete(key);
ruleCssByKey.delete(key);
}

@@ -26,5 +62,7 @@ for (const prefix of prefixes) {

insertedRules.delete(key);
ruleCssByKey.delete(key);
}
}
}
releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));
if (!isBrowser) return;

@@ -31,0 +69,0 @@ return;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/sheet.ts"],"names":[],"mappings":";;;AAKA,IAAM,aAAA,uBAAoB,GAAA,EAAY;AASpC,OAAO,+BAAA,KAAoC,WAAA,IAC3C,+BAAA,KAAoC;AAgCtC,IAAM,SAAA,GACJ,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,MAAA,KAAW,WAAA;AAsLhD,SAAS,iBAAiB,MAAA,EAAsB;AACrD,EAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAC/B,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,MAAA,aAAA,CAAc,OAAO,GAAG,CAAA;AAAA,IAC1B;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AAGhB,EAAS;AAUX;AAQO,SAAS,cAAA,CAAe,MAAgB,QAAA,EAA0B;AACvE,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,aAAA,CAAc,OAAO,GAAG,CAAA;AAAA,EAC1B;AACA,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAC/B,MAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,QAAA,aAAA,CAAc,OAAO,GAAG,CAAA;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AAGhB,EAAS;AAgCX","file":"hmr.cjs","sourcesContent":["const STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nconst RUNTIME_DISABLED =\n typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true';\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser =\n typeof document !== 'undefined' && typeof window !== 'undefined';\n\nfunction getStyleElement(): HTMLStyleElement {\n if (styleElement) return styleElement;\n\n // Check for an existing element (e.g., from SSR)\n const existing = document.getElementById(\n STYLE_ELEMENT_ID\n ) as HTMLStyleElement | null;\n if (existing) {\n styleElement = existing;\n return styleElement;\n }\n\n // Create a new one\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n return styleElement;\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) continue;\n insertedRules.add(key);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.create`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return (\n rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`)\n );\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color -> :root rule with --color- custom properties\n const namespace = key.slice('tokens:'.length);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n"]}
{"version":3,"sources":["../src/registry.ts","../src/sheet.ts"],"names":[],"mappings":"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","file":"hmr.cjs","sourcesContent":["/**\n * Shared registry for detecting duplicate namespace registrations.\n */\nexport const registeredNamespaces = new Set<string>();\n\nconst COLON = ':';\n\n/**\n * Drop reserved `scopeId:namespace` keys so a module can re-register after HMR.\n * `namespace` is the first argument to `styles.component()` / `styles.class()` (not the scope).\n */\nexport function releaseReservedNamespacesForComponentOrClassNames(\n namespaces: readonly string[],\n): void {\n if (namespaces.length === 0) return;\n const wanted = new Set(namespaces);\n const toRemove: string[] = [];\n for (const key of registeredNamespaces) {\n const i = key.indexOf(COLON);\n if (i === -1) continue;\n if (wanted.has(key.slice(i + 1))) {\n toRemove.push(key);\n }\n }\n for (const key of toRemove) {\n registeredNamespaces.delete(key);\n }\n}\n\n/** Vite plugin passes `.${namespace}-` prefixes for `styles.component()` invalidation. */\nexport function namespacesFromTypestylesHmrPrefixes(prefixes: readonly string[]): string[] {\n const out: string[] = [];\n for (const p of prefixes) {\n if (p.length >= 2 && p.startsWith('.') && p.endsWith('-')) {\n out.push(p.slice(1, -1));\n }\n }\n return out;\n}\n","import {\n namespacesFromTypestylesHmrPrefixes,\n releaseReservedNamespacesForComponentOrClassNames,\n} from './registry';\n\nconst STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Last emitted CSS per dedupe key (see {@link warnIfDuplicateRuleKeyConflict}).\n * Cleared with {@link reset} and kept in sync when keys are invalidated.\n */\nconst ruleCssByKey = new Map<string, string>();\n\nfunction duplicateRuleKeyConflictWarningsEnabled(): boolean {\n if (typeof process === 'undefined') return true;\n return process.env.NODE_ENV !== 'production';\n}\n\n/**\n * When the same key is registered again with different CSS, the second rule is skipped\n * (idempotency / HMR). In non-production builds, surface that so overlapping globals\n * (e.g. reset `body` + app `body` in the same scope) are not silent failures.\n */\nfunction warnIfDuplicateRuleKeyConflict(\n key: string,\n previousCss: string,\n ignoredCss: string,\n): void {\n if (!duplicateRuleKeyConflictWarningsEnabled()) return;\n const prevShort = previousCss.length > 220 ? `${previousCss.slice(0, 220)}…` : previousCss;\n const nextShort = ignoredCss.length > 220 ? `${ignoredCss.slice(0, 220)}…` : ignoredCss;\n console.warn(\n `[typestyles] Skipped a rule: dedupe key \"${key}\" already exists with different CSS. ` +\n `Only the first registration is kept. For globals, merge into one \\`global.style\\`, ` +\n `or use a distinct selector (e.g. \\`html body\\` after reset’s \\`body\\`).\\n` +\n ` Existing: ${prevShort}\\n` +\n ` Skipped: ${nextShort}`,\n );\n}\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n *\n * `@typestyles/next/build` `withTypestylesExtract` sets `NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED`\n * via `next.config` `env` so Turbopack and webpack both inline the flag (DefinePlugin\n * alone does not run under Turbopack).\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nfunction readNextPublicRuntimeDisabled(): boolean {\n if (typeof process === 'undefined' || !process.env) return false;\n return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === 'true';\n}\nconst RUNTIME_DISABLED =\n (typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true') ||\n readNextPublicRuntimeDisabled();\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser = typeof document !== 'undefined' && typeof window !== 'undefined';\n\n/**\n * Re-insert every registered rule into a (usually fresh) <style> element.\n * Used when the live element was detached (e.g. Astro view transitions replacing <head>).\n */\nfunction writeAllRulesToStyleElement(el: HTMLStyleElement): void {\n if (RUNTIME_DISABLED || allRules.length === 0) return;\n const sheet = el.sheet;\n if (sheet) {\n for (const css of allRules) {\n try {\n sheet.insertRule(css, sheet.cssRules.length);\n } catch {\n el.appendChild(document.createTextNode(css));\n }\n }\n } else {\n el.appendChild(document.createTextNode(allRules.join('\\n')));\n }\n}\n\nfunction getStyleElement(): HTMLStyleElement {\n let reconnectAfterDetach = false;\n if (styleElement && !styleElement.isConnected) {\n reconnectAfterDetach = true;\n styleElement = null;\n }\n if (styleElement) return styleElement;\n\n // Prefer an element actually in the document (SSR or another copy on the page).\n const existing = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement | null;\n if (existing?.isConnected) {\n styleElement = existing;\n return styleElement;\n }\n\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n\n // After a doc swap, we have a new empty sheet but insertRule() won't re-queue (deduped keys).\n if (reconnectAfterDetach && allRules.length > 0) {\n writeAllRulesToStyleElement(styleElement);\n }\n\n return styleElement;\n}\n\n/**\n * Ensure the managed <style id=\"typestyles\"> is attached to the current document and populated.\n * Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.\n */\nexport function ensureDocumentStylesAttached(): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n getStyleElement();\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Register a single `@layer a, b, c;` preamble so layer **order** is defined before any\n * `@layer name { … }` blocks. Inserts at the front of the virtual sheet and at CSSOM index 0\n * when injecting into the document.\n */\nexport function registerCascadeLayerOrder(preambleKey: string, css: string): void {\n const key = `typestyles:@layer-order:${preambleKey}`;\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n\n allRules.unshift(css);\n\n if (ssrBuffer) {\n ssrBuffer.unshift(css);\n return;\n }\n\n if (RUNTIME_DISABLED) return;\n\n if (!isBrowser) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n try {\n sheet.insertRule(css, 0);\n } catch {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n } else {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n return;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n continue;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n ruleCssByKey.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Drop every rule key tied to a `styles.component('namespace', …)` registration, including\n * `@layer`-wrapped keys (`layer:….:.namespace-…`), and release reserved namespace entries.\n * Used for Vite HMR and for dev recovery when a module re-runs before `hot.dispose`.\n */\nexport function invalidateComponentNamespaceForDev(namespace: string): void {\n const selectorInfix = `.${namespace}-`;\n const keysToDrop: string[] = [];\n for (const k of insertedRules) {\n if (k.includes(selectorInfix)) {\n keysToDrop.push(k);\n }\n }\n invalidateKeys(keysToDrop, [selectorInfix]);\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`);\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color or tokens:color@layerName -> :root rule with --color- custom properties\n const rest = key.slice('tokens:'.length);\n const at = rest.lastIndexOf('@');\n const namespace = at === -1 ? rest : rest.slice(0, at);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n"]}

@@ -1,1 +0,1 @@

export { a as invalidateKeys, b as invalidatePrefix } from './hmr-BACAnP4Y.cjs';
export { a as invalidateKeys, b as invalidatePrefix } from './hmr-D5sXuQgK.cjs';

@@ -1,1 +0,1 @@

export { a as invalidateKeys, b as invalidatePrefix } from './hmr-BACAnP4Y.js';
export { a as invalidateKeys, b as invalidatePrefix } from './hmr-D5sXuQgK.js';

@@ -1,3 +0,4 @@

export { invalidateKeys, invalidatePrefix } from './chunk-AYFIQGCF.js';
export { invalidateKeys, invalidatePrefix } from './chunk-G6ATUNEZ.js';
import './chunk-PZ5AY32C.js';
//# sourceMappingURL=hmr.js.map
//# sourceMappingURL=hmr.js.map

@@ -1,310 +0,687 @@

import * as CSS from 'csstype';
export { f as flushSync, g as getRegisteredCss, i as insertRules, r as reset } from './hmr-BACAnP4Y.cjs';
import { T as ThemeConditionMedia, a as ThemeConditionAttr, b as ThemeConditionClass, c as ThemeConditionSelector, d as ThemeCondition, e as ThemeConditionAnd, f as ThemeConditionOr, g as ThemeOverrides, h as ThemeModeDefinition, i as ThemeSurface, j as ThemeConfig, k as TokenValues, l as TokenRef, C as CSSProperties, V as VariantDefinitions, m as ComponentConfigInput, n as ComponentReturn, F as FlatComponentConfigInput, o as FlatComponentReturn, S as SlotVariantDefinitions, p as SlotComponentConfigInput, q as SlotComponentFunction, M as MultiSlotConfigInput, r as MultiSlotReturn, s as StyleUtils, t as CSSPropertiesWithUtils, G as GlobalStyleTuple, u as FontFaceProps, v as CSSVarRef } from './global-style-tuple-CDbP5BY3.cjs';
export { w as CSSValue, x as ComponentConfig, y as ComponentConfigContext, z as ComponentInternalVarRef, A as ComponentSelections, B as ComponentVarDefinitions, D as ComponentVarDescriptor, E as ComponentVarNode, H as ComponentVarOptions, I as ComponentVarRefTree, J as ComponentVariants, K as DeepPartialTokenValues, L as FlatComponentConfig, N as FlatComponentSelections, O as FlatTokenEntry, P as FontFaceSrc, Q as KeyframeStops, R as SlotComponentConfig, U as SlotStyles, W as StyleDefinitions, X as StyleDefinitionsWithUtils, Y as ThemeConditionNot, Z as VariantOptionStyle, _ as flattenTokenEntries } from './global-style-tuple-CDbP5BY3.cjs';
export { e as ensureDocumentStylesAttached, f as flushSync, g as getRegisteredCss, i as insertRules, r as reset } from './hmr-D5sXuQgK.cjs';
import 'csstype';
/**
* A CSS value that can be a standard value or a token reference (var() string).
* Declare cascade layer order and optionally prepend framework layer names
* (e.g. Bootstrap) so TypeStyles participates in the same ordering graph.
*/
type CSSValue = string | number;
type CascadeLayersObjectInput = {
readonly order: readonly string[];
readonly prependFrameworkLayers?: readonly string[];
};
/** Argument to `createStyles` / `createTokens` / `createTypeStyles` when enabling `@layer`. */
type CascadeLayersInput = readonly string[] | CascadeLayersObjectInput;
/** Normalized cascade layer stack for runtime CSS emission. */
type ResolvedCascadeLayers = {
/** Dedup key for the `@layer a, b, c;` preamble. */
readonly preambleKey: string;
/** Full `@layer …;` order statement (prepend + own layers). */
readonly preambleCss: string;
/** Layers TypeStyles may emit into (excludes `prependFrameworkLayers`). */
readonly ownOrder: readonly string[];
/** Full ordering passed to the preamble. */
readonly fullOrder: readonly string[];
};
/** When present, theme rules are wrapped in `@layer` alongside token `:root` CSS. */
type ThemeEmitLayerContext = {
readonly stack: ResolvedCascadeLayers;
readonly layer: string;
};
declare function condMedia(query: string): ThemeConditionMedia;
declare function condAttr(name: string, value: string, opts: {
scope: 'self' | 'ancestor';
}): ThemeConditionAttr;
declare function condClassName(name: string, opts: {
scope: 'self' | 'ancestor';
}): ThemeConditionClass;
declare function condSelector(selector: string): ThemeConditionSelector;
declare function condAnd(...conditions: ThemeCondition[]): ThemeConditionAnd;
declare function condOr(...conditions: ThemeCondition[]): ThemeConditionOr;
/**
* CSS properties with support for nested selectors and at-rules.
* Extends csstype's Properties with nesting capabilities.
* Negate a condition. Double negation is folded (`not(not(x))` → `x`).
*
* Supported inner shapes (single CSS branch after compile):
* - `when.media` / `when.prefersDark` / `when.prefersLight` → `@media not (…)`
* - `when.attr` / `when.className` with `scope: 'self'` → `:not(…)` on the theme class
* - `when.attr` / `when.className` with `scope: 'ancestor'` → `:root:not(…) .theme-*` (intended when state lives on `html` / `:root`)
*
* Not supported: `when.selector`, `when.or`, combined `@media` + selector, or both ancestor and self selector parts on the same branch. Those log a dev warning and emit no rule.
*/
interface CSSProperties extends CSS.Properties<CSSValue> {
/** Nested selector (e.g., '&:hover', '& .child', '&::before', '&[data-variant]') */
[selector: `&${string}`]: CSSProperties;
/** Attribute selector (e.g., '[data-variant]', '[data-variant="primary"]', '[disabled]') */
[attribute: `[${string}]`]: CSSProperties;
/** At-rule (e.g., '@media (max-width: 768px)', '@container', '@supports') */
[atRule: `@${string}`]: CSSProperties;
}
declare function condNot(condition: ThemeCondition): ThemeCondition;
/**
* Utility function map used by styles.withUtils().
* Each key becomes an extra style property that expands into CSSProperties.
* Condition builders for theme mode layers.
*
* @example
* ```ts
* tokens.when.prefersDark
* tokens.when.media('(prefers-color-scheme: dark)')
* tokens.when.attr('data-color-mode', 'dark', { scope: 'ancestor' })
* tokens.when.or(tokens.when.prefersDark, tokens.when.attr('data-mode', 'dark', { scope: 'self' }))
* ```
*/
type BivariantCallback<Arg, Ret> = {
bivarianceHack(value: Arg): Ret;
}['bivarianceHack'];
type StyleUtils = Record<string, BivariantCallback<unknown, CSSProperties>>;
type UtilityValue<U extends StyleUtils, K extends keyof U> = U[K] extends (value: infer V) => CSSProperties ? V : never;
declare const when: {
readonly media: typeof condMedia;
readonly attr: typeof condAttr;
readonly className: typeof condClassName;
readonly selector: typeof condSelector;
readonly and: typeof condAnd;
readonly or: typeof condOr;
readonly not: typeof condNot;
/** Shorthand for `when.media('(prefers-color-scheme: dark)')`. */
readonly prefersDark: ThemeConditionMedia;
/** Shorthand for `when.media('(prefers-color-scheme: light)')`. */
readonly prefersLight: ThemeConditionMedia;
};
type ColorModeMediaOnlyOptions = {
dark: ThemeOverrides;
};
type ColorModeAttributeOnlyOptions = {
attribute: string;
values: {
dark: string;
light?: string;
};
scope: 'self' | 'ancestor';
dark: ThemeOverrides;
light?: ThemeOverrides;
};
type ColorModeMediaOrAttributeOptions = {
attribute: string;
values: {
dark: string;
light?: string;
system?: string;
};
scope: 'self' | 'ancestor';
dark: ThemeOverrides;
};
type ColorModeSystemWithOverrideOptions = {
attribute: string;
values: {
light: string;
dark: string;
system?: string;
};
scope: 'self' | 'ancestor';
light: ThemeOverrides;
dark: ThemeOverrides;
};
declare function presetMediaOnly(opts: ColorModeMediaOnlyOptions): ThemeModeDefinition[];
declare function presetAttributeOnly(opts: ColorModeAttributeOnlyOptions): ThemeModeDefinition[];
/**
* CSS properties augmented with user-defined utility keys.
* Dark when the OS prefers dark **or** the attribute matches `values.dark`.
*
* **`values.system`** — Optional app-facing token only. No extra CSS rule is emitted for it:
* with `data-*` set to `system`, neither branch of the `or` matches from the attribute side;
* appearance follows the media branch (and your `base` tokens) like OS “system” mode.
*/
type CSSPropertiesWithUtils<U extends StyleUtils> = CSS.Properties<CSSValue> & {
[K in keyof U]?: UtilityValue<U, K>;
} & {
[selector: `&${string}`]: CSSPropertiesWithUtils<U>;
[attribute: `[${string}]`]: CSSPropertiesWithUtils<U>;
[atRule: `@${string}`]: CSSPropertiesWithUtils<U>;
declare function presetMediaOrAttribute(opts: ColorModeMediaOrAttributeOptions): ThemeModeDefinition[];
declare function presetSystemWithLightDarkOverride(opts: ColorModeSystemWithOverrideOptions): ThemeModeDefinition[];
/**
* Color mode presets that expand into `ThemeModeDefinition[]` arrays.
* Use via the `colorMode` property on `tokens.createTheme()`.
*
* @example
* ```ts
* tokens.createTheme('acme', {
* base: lightTokens,
* colorMode: tokens.colorMode.systemWithLightDarkOverride({
* attribute: 'data-color-mode',
* values: { light: 'light', dark: 'dark' },
* scope: 'ancestor',
* light: lightTokens,
* dark: darkTokens,
* }),
* });
* ```
*/
declare const colorMode: {
readonly mediaOnly: typeof presetMediaOnly;
readonly attributeOnly: typeof presetAttributeOnly;
readonly mediaOrAttribute: typeof presetMediaOrAttribute;
readonly systemWithLightDarkOverride: typeof presetSystemWithLightDarkOverride;
};
/**
* A map of style names to utility-aware CSS property definitions.
* Create a themed surface with base token overrides and optional mode layers.
*
* Returns a `ThemeSurface` object whose `className` (and string coercion)
* is a stable, human-readable class name like `"theme-acme"`.
*
* @example
* ```ts
* const acme = tokens.createTheme('acme', {
* base: { color: { text: { primary: '#111827' } } },
* colorMode: tokens.colorMode.mediaOnly({ dark: darkOverrides }),
* });
*
* // acme.className === 'theme-acme'
* // `${acme}` === 'theme-acme'
* ```
*/
type StyleDefinitionsWithUtils<U extends StyleUtils> = Record<string, CSSPropertiesWithUtils<U>>;
declare function createTheme(name: string, config: ThemeConfig, scopeId?: string, layerContext?: ThemeEmitLayerContext): ThemeSurface;
/**
* A map of variant names to their CSS property definitions.
* Shorthand: create a theme surface that applies `darkOverrides` under
* `@media (prefers-color-scheme: dark)`.
*
* Equivalent to:
* ```ts
* tokens.createTheme(name, {
* modes: [{ id: 'dark', overrides: darkOverrides, when: tokens.when.prefersDark }],
* });
* ```
*/
type StyleDefinitions = Record<string, CSSProperties>;
declare function createDarkMode(name: string, darkOverrides: ThemeOverrides, scopeId?: string, layerContext?: ThemeEmitLayerContext): ThemeSurface;
type CreateTokensOptions = {
/**
* Prefix for CSS custom property namespaces and theme class segments so multiple
* packages on one page do not share `--color-*` or `.theme-*` collisions.
*/
scopeId?: string;
/**
* When set with **`tokenLayer`**, `:root` custom properties and theme surfaces are wrapped in
* `@layer tokenLayer { … }`, and a matching `@layer …;` order preamble is registered.
*/
layers?: CascadeLayersInput;
/**
* Default `@layer` from **`layers`** for token and theme CSS (`:root`, themes). Required when **`layers`** is set.
* Override per call: `tokens.create('color', { … }, { layer: '…' })`.
*/
tokenLayer?: string;
};
/**
* A selector function returned by styles.create().
* Accepts variant names (or falsy values for conditional application)
* and returns a composed class name string.
* Design token and theme API bound to an optional `scopeId`.
*/
interface SelectorFunction<K extends string = string> {
(...variants: (K | false | null | undefined)[]): string;
}
type TokensApi = {
/** Same `scopeId` passed to `createTokens`, if any. */
readonly scopeId: string | undefined;
create: <T extends TokenValues>(namespace: string, values: T, options?: {
layer?: string;
}) => TokenRef<T>;
use: <T extends TokenValues = TokenValues>(namespace: string) => TokenRef<T>;
createTheme: (name: string, config: ThemeConfig) => ThemeSurface;
createDarkMode: (name: string, darkOverrides: ThemeOverrides) => ThemeSurface;
when: typeof when;
colorMode: typeof colorMode;
};
/**
* A flat map of token names to their values.
* Create a tokens + theme API for a package or app. Each instance keeps its own
* namespace registry; with `scopeId`, emitted custom properties and theme classes
* are prefixed so they do not collide with other bundles on the same page.
*
* @example
* ```ts
* const tokens = createTokens({ scopeId: 'design-system' });
* const color = tokens.create('color', { primary: '#0066ff' });
* color.primary // var(--design-system-color-primary)
* ```
*/
type TokenValues = Record<string, string>;
declare function createTokens(options?: CreateTokensOptions): TokensApi;
/**
* A typed token reference object. Property access returns var(--namespace-key).
* How generated class names are formed for `styles.class`, `styles.component`,
* and related APIs.
*
* - `semantic` — readable names like `button-base`, `button-intent-primary` (default).
* - `hashed` — stable hash from namespace, variant segment, and declarations, with a short namespace slug for debugging.
* - `atomic` — hash-only names (shortest); same collision properties as `hashed` when `scopeId` differs.
*/
type TokenRef<T extends TokenValues> = {
readonly [K in keyof T]: string;
type ClassNamingMode = 'semantic' | 'hashed' | 'atomic';
type ClassNamingConfig = {
mode: ClassNamingMode;
/** Prefix for hashed / atomic output and for `hashClass`. Default `ts`. */
prefix: string;
/**
* Package, app, or per-file id: same logical `styles.component` / `styles.class` name under different
* scopes produces different classes. In development, re-registering the same scope + component name
* (e.g. HMR) clears prior rules instead of throwing. Use `fileScopeId(import.meta)` for file-local
* isolation (CSS Modules–style).
*/
scopeId: string;
/**
* When set (via `createStyles({ layers: … })`), every `class` / `hashClass` / `component`
* call must pass `{ layer: … }` and emitted rules are wrapped in `@layer`.
*/
cascadeLayers?: ResolvedCascadeLayers;
};
/** Default naming options used by `createStyles()` when no overrides are passed. */
declare const defaultClassNamingConfig: ClassNamingConfig;
declare function mergeClassNaming(partial?: Partial<ClassNamingConfig>): ClassNamingConfig;
/**
* Theme overrides: a map of token namespaces to partial value overrides.
* Stable, short id derived from `import.meta.url` (file path). Use as `createStyles({ scopeId: fileScopeId(import.meta) })`
* so the same logical namespace in different files does not collide (similar to CSS Modules file scope).
*
* @example
* ```ts
* const styles = createStyles({ scopeId: fileScopeId(import.meta) });
* styles.component('button', { base: { padding: '8px' } });
* ```
*/
type ThemeOverrides = Record<string, Partial<TokenValues>>;
declare function fileScopeId(meta: {
url: string;
}): string;
/** CSS custom property namespace segment for `tokens.create` / `createTheme` when `scopeId` is set. */
declare function scopedTokenNamespace(scopeId: string | undefined, logicalNamespace: string): string;
/**
* Keyframe stops: 'from', 'to', or percentage strings mapped to CSS properties.
* Type-level `Array.prototype.join(', ')` for tuple literals — used by {@link has}, {@link is}, {@link where}
* so `[builder(…)]` keys stay **specific template literals** (TypeScript otherwise invents a `string` index
* when mixed with plain CSS longhands unless the key type is narrow).
*/
type KeyframeStops$1 = Record<string, CSSProperties>;
type JoinComma<T extends readonly string[]> = T extends readonly [] ? '' : T extends readonly [infer A extends string] ? A : T extends readonly [infer A extends string, ...infer R extends string[]] ? R['length'] extends 0 ? A : `${A}, ${JoinComma<R>}` : string;
/**
* A map of variant dimensions to their options (each option maps to CSSProperties).
* Type-level `Array.prototype.join(' and ')` for container query condition groups.
*/
type VariantDimensions = Record<string, Record<string, unknown>>;
type VariantDefinitions = Record<string, Record<string, CSSProperties>>;
type SlotStyles<S extends string> = Partial<Record<S, CSSProperties>>;
type SlotVariantDefinitions<S extends string> = Record<string, Record<string, SlotStyles<S>>>;
type VariantOptionKey<V extends VariantDimensions, K extends keyof V> = Extract<keyof V[K], string>;
type VariantSelectionValue<OptionKey extends string> = OptionKey | (Extract<OptionKey, 'true'> extends never ? never : true) | (Extract<OptionKey, 'false'> extends never ? never : false);
type CompoundSelectionValue<OptionKey extends string> = VariantSelectionValue<OptionKey> | readonly VariantSelectionValue<OptionKey>[];
type ComponentSelections<V extends VariantDimensions> = {
[K in keyof V]?: VariantSelectionValue<VariantOptionKey<V, K>> | null | undefined;
};
type JoinAnd<T extends readonly string[]> = T extends readonly [] ? '' : T extends readonly [infer A extends string] ? A : T extends readonly [infer A extends string, ...infer R extends string[]] ? R['length'] extends 0 ? A : `${A} and ${JoinAnd<R>}` : string;
/**
* The full config object passed to styles.component().
* Object key for nested styles: `@container … { … }`.
* Returned by {@link container} for typed container queries (see also raw `@container` strings).
*/
type ComponentConfig<V extends VariantDefinitions> = {
base?: CSSProperties;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: CSSProperties;
}>;
defaultVariants?: ComponentSelections<V>;
};
type ContainerQueryKey = `@container ${string}`;
/**
* The function returned by styles.component().
* Typed `container-name` from {@link createContainerRef} or `styles.containerRef()` (human-readable; use for `containerName` and {@link container}).
*/
type ComponentFunction<V extends VariantDefinitions> = (selections?: ComponentSelections<V>) => string;
type SlotComponentConfig<S extends string, V extends SlotVariantDefinitions<S>> = {
slots: readonly S[];
base?: SlotStyles<S>;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: SlotStyles<S>;
}>;
defaultVariants?: ComponentSelections<V>;
type ContainerNameRef = string & {
readonly __containerNameRef?: true;
};
type SlotComponentFunction<S extends string, V extends SlotVariantDefinitions<S>> = (selections?: ComponentSelections<V>) => Record<S, string>;
/**
* A reference to a CSS custom property created by createVar().
* The string value is `var(--ts-N)` and can be used directly as a CSS value.
* Template literal type provides type safety without a brand.
* Size features for {@link container}. Maps to parenthesis groups joined with `and`.
* Numbers become `px` except `aspectRatio` (emitted as a number or pass a string like `16 / 9`).
*/
type CSSVarRef = `var(--${string})`;
type ContainerQueryFeatures = {
minWidth?: string | number;
maxWidth?: string | number;
minHeight?: string | number;
maxHeight?: string | number;
minInlineSize?: string | number;
maxInlineSize?: string | number;
minBlockSize?: string | number;
maxBlockSize?: string | number;
aspectRatio?: string | number;
orientation?: 'portrait' | 'landscape';
};
/**
* Extract the variant prop types from a ComponentFunction.
*
* @example
* ```ts
* const button = styles.component('button', {
* variants: {
* intent: { primary: {...}, ghost: {...} },
* size: { sm: {...}, lg: {...} },
* },
* });
*
* type ButtonProps = ComponentVariants<typeof button>;
* // { intent?: 'primary' | 'ghost'; size?: 'sm' | 'lg' }
* ```
* Named container + size features (`name` matches `containerName` on an ancestor).
*/
type ComponentVariants<T> = T extends (selections?: ComponentSelections<infer V>) => unknown ? {
[K in keyof V]?: keyof V[K];
} : never;
/**
* Font face property declarations.
*/
type FontFaceProps = {
src: string;
fontWeight?: string | number;
fontStyle?: 'normal' | 'italic' | 'oblique' | string;
fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
fontStretch?: string;
unicodeRange?: string;
type ContainerQueryObject = ContainerQueryFeatures & {
name?: string;
};
type EmitLengthish<V> = V extends 0 ? '0' : V extends number ? `${V}px` : V extends string ? V : never;
type EmitAspect<V> = V extends 0 ? '0' : V extends number ? `${V}` : V extends string ? V : never;
type GMinWidth<F extends ContainerQueryFeatures> = F['minWidth'] extends infer V ? V extends string | number ? [`(min-width: ${EmitLengthish<V>})`] : [] : [];
type GMaxWidth<F extends ContainerQueryFeatures> = F['maxWidth'] extends infer V ? V extends string | number ? [`(max-width: ${EmitLengthish<V>})`] : [] : [];
type GMinHeight<F extends ContainerQueryFeatures> = F['minHeight'] extends infer V ? V extends string | number ? [`(min-height: ${EmitLengthish<V>})`] : [] : [];
type GMaxHeight<F extends ContainerQueryFeatures> = F['maxHeight'] extends infer V ? V extends string | number ? [`(max-height: ${EmitLengthish<V>})`] : [] : [];
type GMinInlineSize<F extends ContainerQueryFeatures> = F['minInlineSize'] extends infer V ? V extends string | number ? [`(min-inline-size: ${EmitLengthish<V>})`] : [] : [];
type GMaxInlineSize<F extends ContainerQueryFeatures> = F['maxInlineSize'] extends infer V ? V extends string | number ? [`(max-inline-size: ${EmitLengthish<V>})`] : [] : [];
type GMinBlockSize<F extends ContainerQueryFeatures> = F['minBlockSize'] extends infer V ? V extends string | number ? [`(min-block-size: ${EmitLengthish<V>})`] : [] : [];
type GMaxBlockSize<F extends ContainerQueryFeatures> = F['maxBlockSize'] extends infer V ? V extends string | number ? [`(max-block-size: ${EmitLengthish<V>})`] : [] : [];
type GAspectRatio<F extends ContainerQueryFeatures> = F['aspectRatio'] extends infer V ? V extends string | number ? [`(aspect-ratio: ${EmitAspect<V>})`] : [] : [];
type GOrientation<F extends ContainerQueryFeatures> = F['orientation'] extends infer V ? V extends 'portrait' | 'landscape' ? [`(orientation: ${V})`] : [] : [];
type ContainerConditionTuple<F extends ContainerQueryFeatures> = [
...GMinWidth<F>,
...GMaxWidth<F>,
...GMinHeight<F>,
...GMaxHeight<F>,
...GMinInlineSize<F>,
...GMaxInlineSize<F>,
...GMinBlockSize<F>,
...GMaxBlockSize<F>,
...GAspectRatio<F>,
...GOrientation<F>
];
type CondFromFeatures<F extends ContainerQueryFeatures> = JoinAnd<ContainerConditionTuple<F>>;
type NamePart<F extends ContainerQueryObject> = F['name'] extends string ? F['name'] extends '' ? '' : F['name'] : '';
/** Narrow `@container` key for {@link container} object form — allows `[container({ … })]` without widening. */
type ContainerObjectKey<F extends ContainerQueryObject> = CondFromFeatures<Omit<F, 'name'>> extends infer B extends string ? B extends '' ? never : NamePart<F> extends '' ? `@container ${B}` : `@container ${NamePart<F>} ${B}` : never;
type CreateContainerRefOptions = {
/**
* When non-empty, the name is `{scopeId}-{label}` (sanitized), same as `createStyles({ scopeId })`.
* When empty, the name is `{prefix}-{label}` instead.
*/
scopeId?: string;
/**
* Used only if **`scopeId`** is empty: `{prefix}-{label}`. Default `ts` (same default as class `prefix`).
*/
prefix?: string;
};
/**
* Create a single class with the given styles. Returns the class name string.
* Use this when you don't need variants — just a class with typed CSS properties.
* Build a **human-readable** `container-name`: share one value between `containerName` and {@link container}’s `name` argument without repeating string literals.
*
* Shape: **`{scopeId}-{label}`** when `scopeId` is set, else **`{prefix}-{label}`** (defaults match `createStyles`).
*
* Prefer **`styles.containerRef(label)`** so `scopeId` / `prefix` come from your instance.
*
* @example
* ```ts
* const card = styles.class('card', {
* padding: '1rem',
* borderRadius: '0.5rem',
* backgroundColor: 'white',
* '&:hover': { boxShadow: '0 4px 6px rgb(0 0 0 / 0.1)' },
* const shell = createContainerRef('product-shell', { scopeId: 'my-app' });
*
* styles.class('shell', {
* containerType: 'inline-size',
* containerName: shell,
* });
*
* <div className={card} /> // class="card"
* styles.class('shell-body', {
* ...styles.atRuleBlock(styles.container(shell, { minWidth: 480 }), { flexDirection: 'row' }),
* });
* ```
*/
declare function createClass(name: string, properties: CSSProperties): string;
declare function createContainerRef(label: string, options?: CreateContainerRefOptions): ContainerNameRef;
/**
* Create a deterministic hashed class from a style object.
* The same style object shape+values always returns the same class name.
* Build a typed `@container` key for use in style objects (same output shape as a manual `'@container …'` string).
*
* Optional `label` is appended as a readable prefix for debugging.
* **Ecosystem notes:** StyleX and Panda usually expose `@container` as string keys (or Panda conditions);
* Vanilla Extract’s `createContainer()` scopes names—here you set `containerName` and pass the same string as `name`.
*
* @example
* @example Size query
* ```ts
* const button = styles.hashClass({
* padding: '8px 12px',
* borderRadius: '8px',
* styles.class('card', {
* containerType: 'inline-size',
* ...styles.atRuleBlock(styles.container({ minWidth: 400 }), { padding: '24px' }),
* });
*
* const danger = styles.hashClass(
* { backgroundColor: 'red', color: 'white' },
* 'danger'
* );
* ```
*/
declare function createHashClass(properties: CSSProperties, label?: string): string;
/**
* Create a style group and return a selector function.
*
* **Two-argument form** (definitions object with 'base' and variants):
* @example Named container
* ```ts
* const button = styles.create('button', {
* base: { padding: '8px 16px' },
* primary: { backgroundColor: '#0066ff' },
* styles.class('item', {
* ...styles.atRuleBlock(styles.container('sidebar', { minWidth: 300 }), {
* flexDirection: 'row',
* }),
* });
* button('base', 'primary') // "button-base button-primary"
* ```
*
* **Three-argument form** (base styles + variants, no 'base' key needed):
* @example Style / scroll / `not` — raw condition after `@container`
* ```ts
* const button = styles.create('button',
* { padding: '8px 16px', borderRadius: '6px' }, // base styles
* {
* default: { backgroundColor: '#0066ff', color: '#fff' },
* outline: { border: '1px solid', backgroundColor: 'transparent' },
* large: { padding: '12px 24px' },
* }
* );
* button('default') // "button-base button-default" — base always included
* button('outline', 'large') // "button-base button-outline button-large"
* ...styles.atRuleBlock(styles.container('style(--theme: dark)'), { color: '#fff' })
* ```
*/
declare function createStyles<K extends string>(namespace: string, definitions: StyleDefinitions & Record<K, CSSProperties>): SelectorFunction<K>;
declare function createStyles(namespace: string, base: CSSProperties, variants: Record<string, CSSProperties>): SelectorFunction<string>;
declare function container<const F extends ContainerQueryObject>(features: F): ContainerObjectKey<F>;
declare function container<const N extends string, const F extends ContainerQueryFeatures>(name: N, features: F): CondFromFeatures<F> extends infer B extends string ? B extends '' ? never : `@container ${N} ${B}` : never;
/** Raw condition after `@container` — literal `S` preserves a narrow key for `[container('…')]`. */
declare function container<const S extends string>(rawCondition: S): `@container ${S}`;
declare function container(rawCondition: string): ContainerQueryKey;
/**
* Compose multiple selector functions or class strings into one.
* Returns a new SelectorFunction that calls all inputs and joins results.
* Returns a one-key object to **spread** into a style map.
*
* TypeScript widens **computed** `[someFn()]` keys to `string`, which clashes with {@link CSSProperties}’s
* `` `@${string}` `` index signature. Spreading `Record<@${string}, CSSProperties>` preserves a narrow key type.
*
* Works for keys from `container()`, literal `'@media (…)'`, `'@supports (…)'`, etc.
*
* @example
* ```ts
* const base = styles.create('base', { padding: '8px' });
* const primary = styles.create('primary', { color: 'blue' });
* const button = styles.compose(base, primary);
*
* button('padding', 'color'); // "base-padding primary-color"
* styles.class('card', {
* padding: '16px',
* ...atRuleBlock(styles.container({ minWidth: 400 }), { padding: '24px' }),
* });
* ```
*/
type AnySelectorFunction = {
(...args: unknown[]): string;
};
declare function compose(...selectors: Array<AnySelectorFunction | string | false | null | undefined>): AnySelectorFunction;
type StylesWithUtilsApi<U extends StyleUtils> = {
class: (name: string, properties: CSSPropertiesWithUtils<U>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, label?: string) => string;
create: {
<K extends string>(namespace: string, definitions: StyleDefinitionsWithUtils<U> & Record<K, CSSPropertiesWithUtils<U>>): SelectorFunction<K>;
(namespace: string, base: CSSPropertiesWithUtils<U>, variants: Record<string, CSSPropertiesWithUtils<U>>): SelectorFunction<string>;
};
compose: typeof compose;
};
declare function atRuleBlock<const K extends `@${string}`>(key: K, block: CSSProperties): Record<K, CSSProperties>;
/**
* Create a utility-aware styles API, similar to Stitches' `utils`.
* Object key for nested styles using {@link has} — compiles to `.base:has(…)`.
* Prefer variadic {@link has} so keys narrow to a single literal (mixes cleanly with longhands).
*/
type HasNestedKey = `&:has(${string})`;
/**
* Object key for nested styles using {@link is} — compiles to `.base:is(…)`.
*/
type IsNestedKey = `&:is(${string})`;
/**
* Object key for nested styles using {@link where} — compiles to `.base:where(…)` (zero-specificity).
*/
type WhereNestedKey = `&:where(${string})`;
/**
* Pseudos often grouped with {@link is} for shared focus/hover styles.
* Plain strings still work; this union improves autocomplete at call sites.
*/
type IsPseudoArg = ':hover' | ':active' | ':focus' | ':focus-visible' | ':focus-within' | ':disabled' | ':enabled' | ':checked' | ':indeterminate' | ':read-only' | ':read-write' | ':placeholder-shown' | ':default' | ':required' | ':optional' | ':valid' | ':invalid' | ':in-range' | ':out-of-range' | ':any-link' | ':link' | ':visited' | ':target' | ':target-within';
/**
* Build a nested style key for `:has()` — parental/descendant-aware styling without leaving the style object.
*
* Accepts a [relative selector list](https://drafts.csswg.org/selectors/#relative-real-selector-list):
* multiple arguments become comma-separated branches inside `:has()`.
*
* **Ecosystem:** StyleX exposes contextual selectors via dedicated `when.*` helpers; Panda/Stitches lean on
* nesting strings. TypeStyles keeps emit as real CSS and adds small builders beside raw `'&:has(…)'` keys.
*
* @example
* ```ts
* const u = createStylesWithUtils({
* marginX: (value: string | number) => ({ marginLeft: value, marginRight: value }),
* size: (value: string | number) => ({ width: value, height: value }),
* styles.class('nav', {
* base: { display: 'flex' },
* [has('.active')]: { borderBottom: '2px solid blue' },
* });
*
* const card = u.class('card', {
* size: 40,
* marginX: 16,
* });
* ```
*/
declare function createStylesWithUtils<U extends StyleUtils>(utils: U): StylesWithUtilsApi<U>;
declare function has<const T extends readonly string[]>(...relativeSelectors: T): `&:has(${JoinComma<T>})`;
/**
* Create design tokens as CSS custom properties.
* Build a nested style key for `:is()` — group pseudos or tags into one branch with the specificity of the
* most specific argument selector.
*
* Generates a :root rule with the custom properties and returns
* a typed object where property access yields var() references.
*
* @example
* ```ts
* const color = createTokens('color', {
* primary: '#0066ff',
* secondary: '#6b7280',
* });
*
* color.primary // "var(--color-primary)"
* [is(':hover', ':focus-visible')]: { outline: '2px solid blue' }
* ```
*/
declare function createTokens<T extends TokenValues>(namespace: string, values: T): TokenRef<T>;
declare function is<const T extends readonly string[]>(...selectors: T): `&:is(${JoinComma<T>})`;
/**
* Reference tokens defined elsewhere without injecting CSS.
* Build a nested style key for `:where()` — **zero-specificity** wrapper so library defaults stay easy for
* consumers to override (unlike `:is()`, which preserves specificity of its arguments).
*
* Returns a typed proxy that produces var() references.
* Useful for consuming shared tokens from a different module.
*
* @example
* ```ts
* const color = useTokens('color');
* color.primary // "var(--color-primary)"
* [where('.nav')]: { display: 'flex', gap: '8px' }
* ```
*/
declare function useTokens<T extends TokenValues = TokenValues>(namespace: string): TokenRef<T>;
declare function where<const T extends readonly string[]>(...selectors: T): `&:where(${JoinComma<T>})`;
/**
* Create a theme class that overrides token values.
* Compose multiple component functions or class strings into one.
* Returns a new function that calls all inputs and joins results.
*
* Returns a class name string. Apply it to any element to override
* token values for that subtree via CSS custom property cascading.
*
* @example
* ```ts
* const dark = createTheme('dark', {
* color: { primary: '#66b3ff', surface: '#1a1a2e' },
* });
* const base = styles.component('base', { base: { padding: '8px' } });
* const primary = styles.component('primary', { base: { color: 'blue' } });
* const button = styles.compose(base, primary);
*
* <div className={dark}> // class="theme-dark"
* button(); // "base-base primary-base"
* ```
*/
declare function createTheme(name: string, overrides: ThemeOverrides): string;
type AnySelectorFunction = {
(...args: unknown[]): string;
};
declare function compose(...selectors: Array<AnySelectorFunction | string | false | null | undefined>): AnySelectorFunction;
type StylesApi = {
/** Resolved naming config for this instance (useful for debugging). */
readonly classNaming: Readonly<ClassNamingConfig>;
/**
* Typed `@container` object keys for nested styles (size features, named containers, or raw conditions).
* Same function as the named export `container` from `typestyles`.
*/
readonly container: typeof container;
/**
* Readable `container-name` for `containerName`: `{scopeId}-{label}` or `{prefix}-{label}` when `scopeId` is empty.
* Same as `createContainerRef(label, { scopeId, prefix })` from this instance’s naming config.
*/
readonly containerRef: (label: string) => ContainerNameRef;
/**
* Build a spreadable `{ [ @key ]: nested }` so computed `@…` keys stay typed (see `atRuleBlock` export).
*/
readonly atRuleBlock: typeof atRuleBlock;
/**
* Nested `&:has(…)` object keys (same helpers as the `has` export).
*/
readonly has: typeof has;
/**
* Nested `&:is(…)` object keys for grouped states (same as the `is` export).
*/
readonly is: typeof is;
/**
* Nested `&:where(…)` keys — zero-specificity defaults (same as the `where` export).
*/
readonly where: typeof where;
class: (name: string, properties: CSSProperties) => string;
hashClass: (properties: CSSProperties, label?: string) => string;
component: {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>): MultiSlotReturn<Slots>;
};
withUtils: <U extends StyleUtils>(utils: U) => StylesWithUtilsApi<U>;
compose: typeof compose;
};
/** Options argument for styles when `createStyles({ layers })` is used. */
type LayerOption<L extends string = string> = {
readonly layer: L;
};
type CreateStylesInput = Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers?: CascadeLayersInput;
/**
* Only applies when using `createTokens` / `createTypeStyles` for `:root` and theme CSS.
* Ignored by `createStyles` alone (passing it here avoids repeating the key at the factory).
*/
tokenLayer?: string;
};
type LayeredComponentFn<L extends string> = {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>, options: LayerOption<L>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>, options: LayerOption<L>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>, options: LayerOption<L>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>, options: LayerOption<L>): MultiSlotReturn<Slots>;
};
type LayeredComponentFnWithUtils<L extends string> = {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>, options: LayerOption<L>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>, options: LayerOption<L>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>, options: LayerOption<L>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>, options: LayerOption<L>): MultiSlotReturn<Slots>;
};
type StylesWithUtilsApiLayered<U extends StyleUtils, L extends string> = Omit<StylesWithUtilsApi<U>, 'class' | 'hashClass' | 'component'> & {
class: (name: string, properties: CSSPropertiesWithUtils<U>, options: LayerOption<L>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, options: LayerOption<L> & {
label?: string;
}) => string;
component: LayeredComponentFnWithUtils<L>;
compose: typeof compose;
};
type StylesApiWithLayers<L extends string> = Omit<StylesApi, 'class' | 'hashClass' | 'component' | 'withUtils'> & {
class: (name: string, properties: CSSProperties, options: LayerOption<L>) => string;
hashClass: (properties: CSSProperties, options: LayerOption<L> & {
label?: string;
}) => string;
component: LayeredComponentFn<L>;
withUtils: <U extends StyleUtils>(utils: U) => StylesWithUtilsApiLayered<U, L>;
};
/**
* Create a styles API with its own class naming config (scope, mode, prefix).
* Use one instance per package or micro-frontend so hashed names stay isolated without global mutation.
* Pass **`scopeId`** (or `fileScopeId(import.meta)` per module) so duplicate logical namespaces across
* files do not collide; in development, registering the same name twice under one scope throws.
*
* Pass **`layers`** to enable CSS cascade layers: a tuple (or `{ order, prependFrameworkLayers? }`)
* defines a single `@layer a, b, c;` preamble, and every `class` / `hashClass` / `component` call
* must pass `{ layer: … }` with a name from that stack.
*/
declare function createStyles<const L extends readonly string[]>(options: Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers: L;
tokenLayer?: L[number];
}): StylesApiWithLayers<L[number]>;
declare function createStyles(options: Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers: CascadeLayersObjectInput;
tokenLayer?: string;
}): StylesApiWithLayers<string>;
declare function createStyles(options?: CreateStylesInput): StylesApi;
type StylesWithUtilsApi<U extends StyleUtils> = {
readonly container: typeof container;
readonly containerRef: (label: string) => ContainerNameRef;
readonly atRuleBlock: typeof atRuleBlock;
readonly has: typeof has;
readonly is: typeof is;
readonly where: typeof where;
class: (name: string, properties: CSSPropertiesWithUtils<U>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, label?: string) => string;
component: {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>): MultiSlotReturn<Slots>;
};
compose: typeof compose;
};
type CreateGlobalOptions = {
/**
* Prefixes inserted rule keys so globals from different bundles dedupe independently.
* Within one scope, each `selector` (+ optional `layer`) maps to a single rule: a second
* `global.style('body', …)` with different properties is ignored; non-production builds warn.
*/
scopeId?: string;
};
type CreateGlobalWithLayers = CreateGlobalOptions & {
layers: CascadeLayersInput;
/**
* Default `@layer` for `style()` when the call (or recipe tuple) omits `{ layer }`.
* Must be one of the stack’s own layer names (not a prepended framework layer).
*/
globalLayer?: string;
};
type GlobalApiUnlayered = {
readonly cascadeLayers: undefined;
style(tuple: GlobalStyleTuple): void;
style(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
/** Apply multiple recipe tuples (e.g. {@link reset} from `typestyles/globals`). */
apply(...tuples: GlobalStyleTuple[]): void;
fontFace(family: string, props: FontFaceProps): void;
};
type GlobalApiLayered = {
readonly cascadeLayers: ResolvedCascadeLayers;
style(tuple: GlobalStyleTuple): void;
style(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
apply(...tuples: GlobalStyleTuple[]): void;
fontFace(family: string, props: FontFaceProps): void;
};
declare function createGlobal(options?: CreateGlobalOptions): GlobalApiUnlayered;
declare function createGlobal(options: CreateGlobalWithLayers): GlobalApiLayered;
type NamingPartial = Partial<Omit<ClassNamingConfig, 'cascadeLayers'>>;
type GlobalLayerOption<L extends string = string> = {
/**
* Default `@layer` for `global.style()` when using `layers`.
* Omit to require `{ layer }` on each `global.style` call or recipe tuple.
* Per-call override: `global.style(selector, props, { layer: '…' })` or `body(props, { layer: '…' })`.
*/
globalLayer?: L;
};
/** Unified factory: one `scopeId`, shared cascade layer stack for both class rules and token/theme CSS. */
declare function createTypeStyles(options: NamingPartial): {
styles: StylesApi;
tokens: TokensApi;
global: GlobalApiUnlayered;
};
declare function createTypeStyles<const L extends readonly [string, ...string[]]>(options: NamingPartial & {
layers: L;
tokenLayer: L[number];
} & GlobalLayerOption<L[number]>): {
styles: StylesApiWithLayers<L[number]>;
tokens: TokensApi;
global: GlobalApiLayered;
};
declare function createTypeStyles(options: NamingPartial & {
layers: CascadeLayersObjectInput;
tokenLayer: string;
} & GlobalLayerOption): {
styles: StylesApiWithLayers<string>;
tokens: TokensApi;
global: GlobalApiLayered;
};
/**

@@ -327,3 +704,3 @@ * A keyframe stop is either 'from', 'to', or a percentage like '50%'.

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { animation: `${fadeIn} 300ms ease` },

@@ -478,38 +855,2 @@ * });

/**
* Create a multi-variant component style and return a selector function.
*
* Class naming convention (default `semantic` mode; see `configureClassNaming`):
* base → `{namespace}-base`
* variants.intent.primary → `{namespace}-intent-primary`
* compoundVariants[0] → `{namespace}-compound-0`
*
* @example
* ```ts
* const button = styles.component('button', {
* base: { padding: '8px 16px' },
* variants: {
* intent: {
* primary: { backgroundColor: '#0066ff', color: '#fff' },
* ghost: { backgroundColor: 'transparent', border: '1px solid currentColor' },
* },
* size: {
* sm: { fontSize: '12px' },
* lg: { fontSize: '18px' },
* },
* },
* compoundVariants: [
* { variants: { intent: 'primary', size: 'lg' }, style: { fontWeight: 700 } },
* ],
* defaultVariants: { intent: 'primary', size: 'sm' },
* });
*
* button() // "button-base button-intent-primary button-size-sm"
* button({ intent: 'ghost' }) // "button-base button-intent-ghost button-size-sm"
* button({ intent: 'primary', size: 'lg' }) // includes compound class
* ```
*/
declare function createComponent<V extends VariantDefinitions>(namespace: string, config: ComponentConfig<V>): ComponentFunction<V>;
declare function createComponent<S extends string, V extends SlotVariantDefinitions<S>>(namespace: string, config: SlotComponentConfig<S, V>): SlotComponentFunction<S, V>;
/**
* Apply styles to an arbitrary CSS selector.

@@ -526,4 +867,20 @@ *

* ```
*
* Also accepts a tuple from `typestyles/globals` recipes:
*
* ```ts
* import { boxSizing, body } from 'typestyles/globals';
* global.style(boxSizing());
* global.style(body({ margin: 0 }));
* ```
*
* Optional `{ layer }` on the tuple or as a third argument is ignored on the root `global` object —
* use `createGlobal({ layers })` or `createTypeStyles({ layers }).global` for `@layer`.
*/
declare function globalStyle(selector: string, properties: CSSProperties): void;
declare function globalStyle(tuple: GlobalStyleTuple): void;
declare function globalStyle(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
/** Apply multiple `typestyles/globals` tuples (e.g. {@link reset}) in one call. */
declare function globalApply(...tuples: GlobalStyleTuple[]): void;
/**

@@ -534,3 +891,3 @@ * Declare a `@font-face` rule to load a custom font.

* this function multiple times with different `src` values — each call is
* deduplicated by `family + src`.
* deduplicated by `family +` normalized `src`.
*

@@ -553,2 +910,19 @@ * @example

* ```
*
* @example Variable font (weight range)
* ```ts
* global.fontFace('InterVar', {
* src: "url('/fonts/Inter.var.woff2') format('woff2')",
* fontWeight: '100 900',
* fontDisplay: 'swap',
* });
* ```
*
* @example Multiple `src` entries (e.g. `local()` then remote)
* ```ts
* global.fontFace('Inter', {
* src: [`local('Inter')`, "url('/fonts/Inter.woff2') format('woff2')"],
* fontDisplay: 'swap',
* });
* ```
*/

@@ -567,3 +941,3 @@ declare function globalFontFace(family: string, props: FontFaceProps): void;

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { background: cardBg, padding: '16px' },

@@ -592,52 +966,92 @@ * });

/**
* How generated class names are formed for `styles.create`, `styles.class`,
* `styles.component`, and related APIs.
* Join class name parts, filtering out falsy values.
*
* - `semantic` — readable names like `button-base`, `button-intent-primary` (default).
* - `hashed` — stable hash from namespace, variant segment, and declarations, with a short namespace slug for debugging.
* - `atomic` — hash-only names (shortest); same collision properties as `hashed` when `scopeId` differs.
* A lightweight utility for combining TypeStyles classes, external class
* strings, and conditional expressions into a single `className` string.
*
* @example
* ```ts
* import { cx } from 'typestyles';
*
* cx('card', isActive && 'active', className);
* // => "card active my-external-class"
*
* cx(button('base', 'primary'), 'extra');
* // => "button-base button-primary extra"
* ```
*/
type ClassNamingMode = 'semantic' | 'hashed' | 'atomic';
type ClassNamingConfig = {
mode: ClassNamingMode;
/** Prefix for hashed / atomic output and for `hashClass`. Default `ts`. */
prefix: string;
/**
* Optional package or app id mixed into hash input so identical logical
* names from different packages do not produce the same class string.
*/
scopeId: string;
};
declare function getClassNamingConfig(): Readonly<ClassNamingConfig>;
declare function cx(...parts: Array<string | undefined | null | false | 0 | ''>): string;
/**
* Set global class naming options. Call once at app or package entry
* (e.g. design-system `index.ts`) for per-package adoption in a monorepo.
* Helpers for CSS `calc()` and `clamp()` that keep the function parentheses in one place.
* Values are plain strings at runtime — no validation of inner syntax.
*/
declare function configureClassNaming(partial: Partial<ClassNamingConfig>): void;
/** Restore defaults (primarily for tests). */
declare function resetClassNaming(): void;
/** Token refs, lengths, percentages, etc. */
type CssMathValue = string | number;
/**
* Tagged template: wraps the interpolated expression in `calc(...)`.
*
* @example
* ```ts
* import { calc } from 'typestyles';
*
* calc`100vh - 2 * ${t.space[4]}`
* // => "calc(100vh - 2 * var(--space-4))"
* ```
*/
declare function calc(strings: TemplateStringsArray, ...values: CssMathValue[]): string;
/**
* CSS `clamp(MIN, PREFERRED, MAX)`.
*
* @example
* ```ts
* import { clamp } from 'typestyles';
*
* clamp('1rem', '5vw', '3rem')
* // => "clamp(1rem, 5vw, 3rem)"
* ```
*/
declare function clamp(min: CssMathValue, preferred: CssMathValue, max: CssMathValue): string;
/**
* Style creation API.
* Helper for CSS `content` string values. Emits a double-quoted CSS string; values are plain strings
* at runtime — same spirit as `calc` / `clamp` in css-math.
*/
/**
* Wrap `text` in a CSS string (`content: "…";`). `null` / `undefined` yield `''` (omit the property
* or pair with a conditional if you need no declaration).
*
* @example
* ```ts
* const button = styles.create('button', {
* import { content } from 'typestyles';
*
* content() // => '' (skip property or use a conditional if you want no rule)
* content('') // => '""' → valid `content: "";` for an empty pseudo-element box
* content('*') // => '"*"' → `content: "*";`
* ```
*/
declare function content(text?: string | null): string;
/**
* Default style API (semantic class names, empty `scopeId`). Prefer `createStyles({ scopeId, mode, prefix })`
* per package or micro-frontend for isolation.
*
* @example
* ```ts
* // Multi-variant component (CVA-style)
* const button = styles.component('button', {
* base: { padding: '8px 16px' },
* primary: { backgroundColor: '#0066ff' },
* variants: {
* intent: { primary: { backgroundColor: '#0066ff' } },
* size: { sm: { fontSize: '14px' }, lg: { fontSize: '18px' } },
* },
* defaultVariants: { intent: 'primary', size: 'sm' },
* });
*
* const hashed = styles.hashClass({ display: 'inline-flex' }, 'button');
* button({ intent: 'primary', size: 'lg' })
*
* <button className={`${button('base', 'primary')} ${hashed}`}>
* const card = styles.class('card', { padding: '1rem' });
* ```
*/
declare const styles: {
readonly create: typeof createStyles;
readonly class: typeof createClass;
readonly hashClass: typeof createHashClass;
readonly component: typeof createComponent;
readonly withUtils: typeof createStylesWithUtils;
readonly compose: typeof compose;
};
declare const styles: StylesApi;
/**

@@ -649,3 +1063,5 @@ * Global CSS API for arbitrary selectors and font-face declarations.

* global.style('body', { margin: 0 });
* global.apply(...reset());
* global.fontFace('Inter', { src: "url('/Inter.woff2') format('woff2')", fontWeight: 400 });
* global.fontFace('Inter', { src: [`local('Inter')`, "url('/Inter.woff2') format('woff2')"] });
* ```

@@ -655,21 +1071,21 @@ */

readonly style: typeof globalStyle;
readonly apply: typeof globalApply;
readonly fontFace: typeof globalFontFace;
};
/**
* Design token API using CSS custom properties.
* Default token API (unscoped custom properties). Prefer `createTokens({ scopeId })` when multiple
* bundles share a page.
*
* @example
* ```ts
* const color = tokens.create('color', {
* primary: '#0066ff',
* const color = tokens.create('color', { primary: '#0066ff' });
* color.primary // "var(--color-primary)"
*
* const acme = tokens.createTheme('acme', {
* base: { color: { primary: '#ff6600' } },
* colorMode: tokens.colorMode.mediaOnly({ dark: darkOverrides }),
* });
*
* color.primary // "var(--color-primary)"
* ```
*/
declare const tokens: {
readonly create: typeof createTokens;
readonly use: typeof useTokens;
readonly createTheme: typeof createTheme;
};
declare const tokens: TokensApi;
/**

@@ -685,3 +1101,3 @@ * Keyframe animation API.

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { animation: `${fadeIn} 300ms ease` },

@@ -711,2 +1127,2 @@ * });

export { type CSSProperties, type CSSPropertiesWithUtils, type CSSValue, type CSSVarRef, type ClassNamingConfig, type ClassNamingMode, type ColorMixSpace, type ComponentConfig, type ComponentFunction, type ComponentVariants, type FontFaceProps, type KeyframeStops$1 as KeyframeStops, type SelectorFunction, type SlotComponentConfig, type SlotComponentFunction, type SlotStyles, type SlotVariantDefinitions, type StyleDefinitions, type StyleDefinitionsWithUtils, type StyleUtils, type ThemeOverrides, type TokenRef, type TokenValues, type VariantDefinitions, assignVars, color, configureClassNaming, createVar, getClassNamingConfig, global, keyframes, resetClassNaming, styles, tokens };
export { CSSProperties, CSSPropertiesWithUtils, CSSVarRef, type CascadeLayersInput, type CascadeLayersObjectInput, type ClassNamingConfig, type ClassNamingMode, type ColorMixSpace, ComponentConfigInput, ComponentReturn, type ContainerNameRef, type ContainerObjectKey, type ContainerQueryFeatures, type ContainerQueryKey, type ContainerQueryObject, type CreateContainerRefOptions, type CreateStylesInput, type CreateTokensOptions, type CssMathValue, FlatComponentConfigInput, FlatComponentReturn, FontFaceProps, type GlobalApiLayered, type GlobalApiUnlayered, GlobalStyleTuple, type HasNestedKey, type IsNestedKey, type IsPseudoArg, type LayerOption, type LayeredComponentFn, MultiSlotConfigInput, type ResolvedCascadeLayers, SlotComponentConfigInput, SlotComponentFunction, SlotVariantDefinitions, StyleUtils, type StylesApi, type StylesApiWithLayers, ThemeCondition, ThemeConditionAnd, ThemeConditionAttr, ThemeConditionClass, ThemeConditionMedia, ThemeConditionOr, ThemeConditionSelector, ThemeConfig, type ThemeEmitLayerContext, ThemeModeDefinition, ThemeOverrides, ThemeSurface, TokenRef, TokenValues, type TokensApi, VariantDefinitions, type WhereNestedKey, assignVars, atRuleBlock, calc, clamp, color, colorMode, container, content, createContainerRef, createDarkMode, createGlobal, createStyles, createTheme, createTokens, createTypeStyles, createVar, cx, defaultClassNamingConfig, fileScopeId, global, has, is, keyframes, mergeClassNaming, scopedTokenNamespace, styles, tokens, when, where };

@@ -1,310 +0,687 @@

import * as CSS from 'csstype';
export { f as flushSync, g as getRegisteredCss, i as insertRules, r as reset } from './hmr-BACAnP4Y.js';
import { T as ThemeConditionMedia, a as ThemeConditionAttr, b as ThemeConditionClass, c as ThemeConditionSelector, d as ThemeCondition, e as ThemeConditionAnd, f as ThemeConditionOr, g as ThemeOverrides, h as ThemeModeDefinition, i as ThemeSurface, j as ThemeConfig, k as TokenValues, l as TokenRef, C as CSSProperties, V as VariantDefinitions, m as ComponentConfigInput, n as ComponentReturn, F as FlatComponentConfigInput, o as FlatComponentReturn, S as SlotVariantDefinitions, p as SlotComponentConfigInput, q as SlotComponentFunction, M as MultiSlotConfigInput, r as MultiSlotReturn, s as StyleUtils, t as CSSPropertiesWithUtils, G as GlobalStyleTuple, u as FontFaceProps, v as CSSVarRef } from './global-style-tuple-CDbP5BY3.js';
export { w as CSSValue, x as ComponentConfig, y as ComponentConfigContext, z as ComponentInternalVarRef, A as ComponentSelections, B as ComponentVarDefinitions, D as ComponentVarDescriptor, E as ComponentVarNode, H as ComponentVarOptions, I as ComponentVarRefTree, J as ComponentVariants, K as DeepPartialTokenValues, L as FlatComponentConfig, N as FlatComponentSelections, O as FlatTokenEntry, P as FontFaceSrc, Q as KeyframeStops, R as SlotComponentConfig, U as SlotStyles, W as StyleDefinitions, X as StyleDefinitionsWithUtils, Y as ThemeConditionNot, Z as VariantOptionStyle, _ as flattenTokenEntries } from './global-style-tuple-CDbP5BY3.js';
export { e as ensureDocumentStylesAttached, f as flushSync, g as getRegisteredCss, i as insertRules, r as reset } from './hmr-D5sXuQgK.js';
import 'csstype';
/**
* A CSS value that can be a standard value or a token reference (var() string).
* Declare cascade layer order and optionally prepend framework layer names
* (e.g. Bootstrap) so TypeStyles participates in the same ordering graph.
*/
type CSSValue = string | number;
type CascadeLayersObjectInput = {
readonly order: readonly string[];
readonly prependFrameworkLayers?: readonly string[];
};
/** Argument to `createStyles` / `createTokens` / `createTypeStyles` when enabling `@layer`. */
type CascadeLayersInput = readonly string[] | CascadeLayersObjectInput;
/** Normalized cascade layer stack for runtime CSS emission. */
type ResolvedCascadeLayers = {
/** Dedup key for the `@layer a, b, c;` preamble. */
readonly preambleKey: string;
/** Full `@layer …;` order statement (prepend + own layers). */
readonly preambleCss: string;
/** Layers TypeStyles may emit into (excludes `prependFrameworkLayers`). */
readonly ownOrder: readonly string[];
/** Full ordering passed to the preamble. */
readonly fullOrder: readonly string[];
};
/** When present, theme rules are wrapped in `@layer` alongside token `:root` CSS. */
type ThemeEmitLayerContext = {
readonly stack: ResolvedCascadeLayers;
readonly layer: string;
};
declare function condMedia(query: string): ThemeConditionMedia;
declare function condAttr(name: string, value: string, opts: {
scope: 'self' | 'ancestor';
}): ThemeConditionAttr;
declare function condClassName(name: string, opts: {
scope: 'self' | 'ancestor';
}): ThemeConditionClass;
declare function condSelector(selector: string): ThemeConditionSelector;
declare function condAnd(...conditions: ThemeCondition[]): ThemeConditionAnd;
declare function condOr(...conditions: ThemeCondition[]): ThemeConditionOr;
/**
* CSS properties with support for nested selectors and at-rules.
* Extends csstype's Properties with nesting capabilities.
* Negate a condition. Double negation is folded (`not(not(x))` → `x`).
*
* Supported inner shapes (single CSS branch after compile):
* - `when.media` / `when.prefersDark` / `when.prefersLight` → `@media not (…)`
* - `when.attr` / `when.className` with `scope: 'self'` → `:not(…)` on the theme class
* - `when.attr` / `when.className` with `scope: 'ancestor'` → `:root:not(…) .theme-*` (intended when state lives on `html` / `:root`)
*
* Not supported: `when.selector`, `when.or`, combined `@media` + selector, or both ancestor and self selector parts on the same branch. Those log a dev warning and emit no rule.
*/
interface CSSProperties extends CSS.Properties<CSSValue> {
/** Nested selector (e.g., '&:hover', '& .child', '&::before', '&[data-variant]') */
[selector: `&${string}`]: CSSProperties;
/** Attribute selector (e.g., '[data-variant]', '[data-variant="primary"]', '[disabled]') */
[attribute: `[${string}]`]: CSSProperties;
/** At-rule (e.g., '@media (max-width: 768px)', '@container', '@supports') */
[atRule: `@${string}`]: CSSProperties;
}
declare function condNot(condition: ThemeCondition): ThemeCondition;
/**
* Utility function map used by styles.withUtils().
* Each key becomes an extra style property that expands into CSSProperties.
* Condition builders for theme mode layers.
*
* @example
* ```ts
* tokens.when.prefersDark
* tokens.when.media('(prefers-color-scheme: dark)')
* tokens.when.attr('data-color-mode', 'dark', { scope: 'ancestor' })
* tokens.when.or(tokens.when.prefersDark, tokens.when.attr('data-mode', 'dark', { scope: 'self' }))
* ```
*/
type BivariantCallback<Arg, Ret> = {
bivarianceHack(value: Arg): Ret;
}['bivarianceHack'];
type StyleUtils = Record<string, BivariantCallback<unknown, CSSProperties>>;
type UtilityValue<U extends StyleUtils, K extends keyof U> = U[K] extends (value: infer V) => CSSProperties ? V : never;
declare const when: {
readonly media: typeof condMedia;
readonly attr: typeof condAttr;
readonly className: typeof condClassName;
readonly selector: typeof condSelector;
readonly and: typeof condAnd;
readonly or: typeof condOr;
readonly not: typeof condNot;
/** Shorthand for `when.media('(prefers-color-scheme: dark)')`. */
readonly prefersDark: ThemeConditionMedia;
/** Shorthand for `when.media('(prefers-color-scheme: light)')`. */
readonly prefersLight: ThemeConditionMedia;
};
type ColorModeMediaOnlyOptions = {
dark: ThemeOverrides;
};
type ColorModeAttributeOnlyOptions = {
attribute: string;
values: {
dark: string;
light?: string;
};
scope: 'self' | 'ancestor';
dark: ThemeOverrides;
light?: ThemeOverrides;
};
type ColorModeMediaOrAttributeOptions = {
attribute: string;
values: {
dark: string;
light?: string;
system?: string;
};
scope: 'self' | 'ancestor';
dark: ThemeOverrides;
};
type ColorModeSystemWithOverrideOptions = {
attribute: string;
values: {
light: string;
dark: string;
system?: string;
};
scope: 'self' | 'ancestor';
light: ThemeOverrides;
dark: ThemeOverrides;
};
declare function presetMediaOnly(opts: ColorModeMediaOnlyOptions): ThemeModeDefinition[];
declare function presetAttributeOnly(opts: ColorModeAttributeOnlyOptions): ThemeModeDefinition[];
/**
* CSS properties augmented with user-defined utility keys.
* Dark when the OS prefers dark **or** the attribute matches `values.dark`.
*
* **`values.system`** — Optional app-facing token only. No extra CSS rule is emitted for it:
* with `data-*` set to `system`, neither branch of the `or` matches from the attribute side;
* appearance follows the media branch (and your `base` tokens) like OS “system” mode.
*/
type CSSPropertiesWithUtils<U extends StyleUtils> = CSS.Properties<CSSValue> & {
[K in keyof U]?: UtilityValue<U, K>;
} & {
[selector: `&${string}`]: CSSPropertiesWithUtils<U>;
[attribute: `[${string}]`]: CSSPropertiesWithUtils<U>;
[atRule: `@${string}`]: CSSPropertiesWithUtils<U>;
declare function presetMediaOrAttribute(opts: ColorModeMediaOrAttributeOptions): ThemeModeDefinition[];
declare function presetSystemWithLightDarkOverride(opts: ColorModeSystemWithOverrideOptions): ThemeModeDefinition[];
/**
* Color mode presets that expand into `ThemeModeDefinition[]` arrays.
* Use via the `colorMode` property on `tokens.createTheme()`.
*
* @example
* ```ts
* tokens.createTheme('acme', {
* base: lightTokens,
* colorMode: tokens.colorMode.systemWithLightDarkOverride({
* attribute: 'data-color-mode',
* values: { light: 'light', dark: 'dark' },
* scope: 'ancestor',
* light: lightTokens,
* dark: darkTokens,
* }),
* });
* ```
*/
declare const colorMode: {
readonly mediaOnly: typeof presetMediaOnly;
readonly attributeOnly: typeof presetAttributeOnly;
readonly mediaOrAttribute: typeof presetMediaOrAttribute;
readonly systemWithLightDarkOverride: typeof presetSystemWithLightDarkOverride;
};
/**
* A map of style names to utility-aware CSS property definitions.
* Create a themed surface with base token overrides and optional mode layers.
*
* Returns a `ThemeSurface` object whose `className` (and string coercion)
* is a stable, human-readable class name like `"theme-acme"`.
*
* @example
* ```ts
* const acme = tokens.createTheme('acme', {
* base: { color: { text: { primary: '#111827' } } },
* colorMode: tokens.colorMode.mediaOnly({ dark: darkOverrides }),
* });
*
* // acme.className === 'theme-acme'
* // `${acme}` === 'theme-acme'
* ```
*/
type StyleDefinitionsWithUtils<U extends StyleUtils> = Record<string, CSSPropertiesWithUtils<U>>;
declare function createTheme(name: string, config: ThemeConfig, scopeId?: string, layerContext?: ThemeEmitLayerContext): ThemeSurface;
/**
* A map of variant names to their CSS property definitions.
* Shorthand: create a theme surface that applies `darkOverrides` under
* `@media (prefers-color-scheme: dark)`.
*
* Equivalent to:
* ```ts
* tokens.createTheme(name, {
* modes: [{ id: 'dark', overrides: darkOverrides, when: tokens.when.prefersDark }],
* });
* ```
*/
type StyleDefinitions = Record<string, CSSProperties>;
declare function createDarkMode(name: string, darkOverrides: ThemeOverrides, scopeId?: string, layerContext?: ThemeEmitLayerContext): ThemeSurface;
type CreateTokensOptions = {
/**
* Prefix for CSS custom property namespaces and theme class segments so multiple
* packages on one page do not share `--color-*` or `.theme-*` collisions.
*/
scopeId?: string;
/**
* When set with **`tokenLayer`**, `:root` custom properties and theme surfaces are wrapped in
* `@layer tokenLayer { … }`, and a matching `@layer …;` order preamble is registered.
*/
layers?: CascadeLayersInput;
/**
* Default `@layer` from **`layers`** for token and theme CSS (`:root`, themes). Required when **`layers`** is set.
* Override per call: `tokens.create('color', { … }, { layer: '…' })`.
*/
tokenLayer?: string;
};
/**
* A selector function returned by styles.create().
* Accepts variant names (or falsy values for conditional application)
* and returns a composed class name string.
* Design token and theme API bound to an optional `scopeId`.
*/
interface SelectorFunction<K extends string = string> {
(...variants: (K | false | null | undefined)[]): string;
}
type TokensApi = {
/** Same `scopeId` passed to `createTokens`, if any. */
readonly scopeId: string | undefined;
create: <T extends TokenValues>(namespace: string, values: T, options?: {
layer?: string;
}) => TokenRef<T>;
use: <T extends TokenValues = TokenValues>(namespace: string) => TokenRef<T>;
createTheme: (name: string, config: ThemeConfig) => ThemeSurface;
createDarkMode: (name: string, darkOverrides: ThemeOverrides) => ThemeSurface;
when: typeof when;
colorMode: typeof colorMode;
};
/**
* A flat map of token names to their values.
* Create a tokens + theme API for a package or app. Each instance keeps its own
* namespace registry; with `scopeId`, emitted custom properties and theme classes
* are prefixed so they do not collide with other bundles on the same page.
*
* @example
* ```ts
* const tokens = createTokens({ scopeId: 'design-system' });
* const color = tokens.create('color', { primary: '#0066ff' });
* color.primary // var(--design-system-color-primary)
* ```
*/
type TokenValues = Record<string, string>;
declare function createTokens(options?: CreateTokensOptions): TokensApi;
/**
* A typed token reference object. Property access returns var(--namespace-key).
* How generated class names are formed for `styles.class`, `styles.component`,
* and related APIs.
*
* - `semantic` — readable names like `button-base`, `button-intent-primary` (default).
* - `hashed` — stable hash from namespace, variant segment, and declarations, with a short namespace slug for debugging.
* - `atomic` — hash-only names (shortest); same collision properties as `hashed` when `scopeId` differs.
*/
type TokenRef<T extends TokenValues> = {
readonly [K in keyof T]: string;
type ClassNamingMode = 'semantic' | 'hashed' | 'atomic';
type ClassNamingConfig = {
mode: ClassNamingMode;
/** Prefix for hashed / atomic output and for `hashClass`. Default `ts`. */
prefix: string;
/**
* Package, app, or per-file id: same logical `styles.component` / `styles.class` name under different
* scopes produces different classes. In development, re-registering the same scope + component name
* (e.g. HMR) clears prior rules instead of throwing. Use `fileScopeId(import.meta)` for file-local
* isolation (CSS Modules–style).
*/
scopeId: string;
/**
* When set (via `createStyles({ layers: … })`), every `class` / `hashClass` / `component`
* call must pass `{ layer: … }` and emitted rules are wrapped in `@layer`.
*/
cascadeLayers?: ResolvedCascadeLayers;
};
/** Default naming options used by `createStyles()` when no overrides are passed. */
declare const defaultClassNamingConfig: ClassNamingConfig;
declare function mergeClassNaming(partial?: Partial<ClassNamingConfig>): ClassNamingConfig;
/**
* Theme overrides: a map of token namespaces to partial value overrides.
* Stable, short id derived from `import.meta.url` (file path). Use as `createStyles({ scopeId: fileScopeId(import.meta) })`
* so the same logical namespace in different files does not collide (similar to CSS Modules file scope).
*
* @example
* ```ts
* const styles = createStyles({ scopeId: fileScopeId(import.meta) });
* styles.component('button', { base: { padding: '8px' } });
* ```
*/
type ThemeOverrides = Record<string, Partial<TokenValues>>;
declare function fileScopeId(meta: {
url: string;
}): string;
/** CSS custom property namespace segment for `tokens.create` / `createTheme` when `scopeId` is set. */
declare function scopedTokenNamespace(scopeId: string | undefined, logicalNamespace: string): string;
/**
* Keyframe stops: 'from', 'to', or percentage strings mapped to CSS properties.
* Type-level `Array.prototype.join(', ')` for tuple literals — used by {@link has}, {@link is}, {@link where}
* so `[builder(…)]` keys stay **specific template literals** (TypeScript otherwise invents a `string` index
* when mixed with plain CSS longhands unless the key type is narrow).
*/
type KeyframeStops$1 = Record<string, CSSProperties>;
type JoinComma<T extends readonly string[]> = T extends readonly [] ? '' : T extends readonly [infer A extends string] ? A : T extends readonly [infer A extends string, ...infer R extends string[]] ? R['length'] extends 0 ? A : `${A}, ${JoinComma<R>}` : string;
/**
* A map of variant dimensions to their options (each option maps to CSSProperties).
* Type-level `Array.prototype.join(' and ')` for container query condition groups.
*/
type VariantDimensions = Record<string, Record<string, unknown>>;
type VariantDefinitions = Record<string, Record<string, CSSProperties>>;
type SlotStyles<S extends string> = Partial<Record<S, CSSProperties>>;
type SlotVariantDefinitions<S extends string> = Record<string, Record<string, SlotStyles<S>>>;
type VariantOptionKey<V extends VariantDimensions, K extends keyof V> = Extract<keyof V[K], string>;
type VariantSelectionValue<OptionKey extends string> = OptionKey | (Extract<OptionKey, 'true'> extends never ? never : true) | (Extract<OptionKey, 'false'> extends never ? never : false);
type CompoundSelectionValue<OptionKey extends string> = VariantSelectionValue<OptionKey> | readonly VariantSelectionValue<OptionKey>[];
type ComponentSelections<V extends VariantDimensions> = {
[K in keyof V]?: VariantSelectionValue<VariantOptionKey<V, K>> | null | undefined;
};
type JoinAnd<T extends readonly string[]> = T extends readonly [] ? '' : T extends readonly [infer A extends string] ? A : T extends readonly [infer A extends string, ...infer R extends string[]] ? R['length'] extends 0 ? A : `${A} and ${JoinAnd<R>}` : string;
/**
* The full config object passed to styles.component().
* Object key for nested styles: `@container … { … }`.
* Returned by {@link container} for typed container queries (see also raw `@container` strings).
*/
type ComponentConfig<V extends VariantDefinitions> = {
base?: CSSProperties;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: CSSProperties;
}>;
defaultVariants?: ComponentSelections<V>;
};
type ContainerQueryKey = `@container ${string}`;
/**
* The function returned by styles.component().
* Typed `container-name` from {@link createContainerRef} or `styles.containerRef()` (human-readable; use for `containerName` and {@link container}).
*/
type ComponentFunction<V extends VariantDefinitions> = (selections?: ComponentSelections<V>) => string;
type SlotComponentConfig<S extends string, V extends SlotVariantDefinitions<S>> = {
slots: readonly S[];
base?: SlotStyles<S>;
variants?: V;
compoundVariants?: Array<{
variants: {
[K in keyof V]?: CompoundSelectionValue<VariantOptionKey<V, K>>;
};
style: SlotStyles<S>;
}>;
defaultVariants?: ComponentSelections<V>;
type ContainerNameRef = string & {
readonly __containerNameRef?: true;
};
type SlotComponentFunction<S extends string, V extends SlotVariantDefinitions<S>> = (selections?: ComponentSelections<V>) => Record<S, string>;
/**
* A reference to a CSS custom property created by createVar().
* The string value is `var(--ts-N)` and can be used directly as a CSS value.
* Template literal type provides type safety without a brand.
* Size features for {@link container}. Maps to parenthesis groups joined with `and`.
* Numbers become `px` except `aspectRatio` (emitted as a number or pass a string like `16 / 9`).
*/
type CSSVarRef = `var(--${string})`;
type ContainerQueryFeatures = {
minWidth?: string | number;
maxWidth?: string | number;
minHeight?: string | number;
maxHeight?: string | number;
minInlineSize?: string | number;
maxInlineSize?: string | number;
minBlockSize?: string | number;
maxBlockSize?: string | number;
aspectRatio?: string | number;
orientation?: 'portrait' | 'landscape';
};
/**
* Extract the variant prop types from a ComponentFunction.
*
* @example
* ```ts
* const button = styles.component('button', {
* variants: {
* intent: { primary: {...}, ghost: {...} },
* size: { sm: {...}, lg: {...} },
* },
* });
*
* type ButtonProps = ComponentVariants<typeof button>;
* // { intent?: 'primary' | 'ghost'; size?: 'sm' | 'lg' }
* ```
* Named container + size features (`name` matches `containerName` on an ancestor).
*/
type ComponentVariants<T> = T extends (selections?: ComponentSelections<infer V>) => unknown ? {
[K in keyof V]?: keyof V[K];
} : never;
/**
* Font face property declarations.
*/
type FontFaceProps = {
src: string;
fontWeight?: string | number;
fontStyle?: 'normal' | 'italic' | 'oblique' | string;
fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
fontStretch?: string;
unicodeRange?: string;
type ContainerQueryObject = ContainerQueryFeatures & {
name?: string;
};
type EmitLengthish<V> = V extends 0 ? '0' : V extends number ? `${V}px` : V extends string ? V : never;
type EmitAspect<V> = V extends 0 ? '0' : V extends number ? `${V}` : V extends string ? V : never;
type GMinWidth<F extends ContainerQueryFeatures> = F['minWidth'] extends infer V ? V extends string | number ? [`(min-width: ${EmitLengthish<V>})`] : [] : [];
type GMaxWidth<F extends ContainerQueryFeatures> = F['maxWidth'] extends infer V ? V extends string | number ? [`(max-width: ${EmitLengthish<V>})`] : [] : [];
type GMinHeight<F extends ContainerQueryFeatures> = F['minHeight'] extends infer V ? V extends string | number ? [`(min-height: ${EmitLengthish<V>})`] : [] : [];
type GMaxHeight<F extends ContainerQueryFeatures> = F['maxHeight'] extends infer V ? V extends string | number ? [`(max-height: ${EmitLengthish<V>})`] : [] : [];
type GMinInlineSize<F extends ContainerQueryFeatures> = F['minInlineSize'] extends infer V ? V extends string | number ? [`(min-inline-size: ${EmitLengthish<V>})`] : [] : [];
type GMaxInlineSize<F extends ContainerQueryFeatures> = F['maxInlineSize'] extends infer V ? V extends string | number ? [`(max-inline-size: ${EmitLengthish<V>})`] : [] : [];
type GMinBlockSize<F extends ContainerQueryFeatures> = F['minBlockSize'] extends infer V ? V extends string | number ? [`(min-block-size: ${EmitLengthish<V>})`] : [] : [];
type GMaxBlockSize<F extends ContainerQueryFeatures> = F['maxBlockSize'] extends infer V ? V extends string | number ? [`(max-block-size: ${EmitLengthish<V>})`] : [] : [];
type GAspectRatio<F extends ContainerQueryFeatures> = F['aspectRatio'] extends infer V ? V extends string | number ? [`(aspect-ratio: ${EmitAspect<V>})`] : [] : [];
type GOrientation<F extends ContainerQueryFeatures> = F['orientation'] extends infer V ? V extends 'portrait' | 'landscape' ? [`(orientation: ${V})`] : [] : [];
type ContainerConditionTuple<F extends ContainerQueryFeatures> = [
...GMinWidth<F>,
...GMaxWidth<F>,
...GMinHeight<F>,
...GMaxHeight<F>,
...GMinInlineSize<F>,
...GMaxInlineSize<F>,
...GMinBlockSize<F>,
...GMaxBlockSize<F>,
...GAspectRatio<F>,
...GOrientation<F>
];
type CondFromFeatures<F extends ContainerQueryFeatures> = JoinAnd<ContainerConditionTuple<F>>;
type NamePart<F extends ContainerQueryObject> = F['name'] extends string ? F['name'] extends '' ? '' : F['name'] : '';
/** Narrow `@container` key for {@link container} object form — allows `[container({ … })]` without widening. */
type ContainerObjectKey<F extends ContainerQueryObject> = CondFromFeatures<Omit<F, 'name'>> extends infer B extends string ? B extends '' ? never : NamePart<F> extends '' ? `@container ${B}` : `@container ${NamePart<F>} ${B}` : never;
type CreateContainerRefOptions = {
/**
* When non-empty, the name is `{scopeId}-{label}` (sanitized), same as `createStyles({ scopeId })`.
* When empty, the name is `{prefix}-{label}` instead.
*/
scopeId?: string;
/**
* Used only if **`scopeId`** is empty: `{prefix}-{label}`. Default `ts` (same default as class `prefix`).
*/
prefix?: string;
};
/**
* Create a single class with the given styles. Returns the class name string.
* Use this when you don't need variants — just a class with typed CSS properties.
* Build a **human-readable** `container-name`: share one value between `containerName` and {@link container}’s `name` argument without repeating string literals.
*
* Shape: **`{scopeId}-{label}`** when `scopeId` is set, else **`{prefix}-{label}`** (defaults match `createStyles`).
*
* Prefer **`styles.containerRef(label)`** so `scopeId` / `prefix` come from your instance.
*
* @example
* ```ts
* const card = styles.class('card', {
* padding: '1rem',
* borderRadius: '0.5rem',
* backgroundColor: 'white',
* '&:hover': { boxShadow: '0 4px 6px rgb(0 0 0 / 0.1)' },
* const shell = createContainerRef('product-shell', { scopeId: 'my-app' });
*
* styles.class('shell', {
* containerType: 'inline-size',
* containerName: shell,
* });
*
* <div className={card} /> // class="card"
* styles.class('shell-body', {
* ...styles.atRuleBlock(styles.container(shell, { minWidth: 480 }), { flexDirection: 'row' }),
* });
* ```
*/
declare function createClass(name: string, properties: CSSProperties): string;
declare function createContainerRef(label: string, options?: CreateContainerRefOptions): ContainerNameRef;
/**
* Create a deterministic hashed class from a style object.
* The same style object shape+values always returns the same class name.
* Build a typed `@container` key for use in style objects (same output shape as a manual `'@container …'` string).
*
* Optional `label` is appended as a readable prefix for debugging.
* **Ecosystem notes:** StyleX and Panda usually expose `@container` as string keys (or Panda conditions);
* Vanilla Extract’s `createContainer()` scopes names—here you set `containerName` and pass the same string as `name`.
*
* @example
* @example Size query
* ```ts
* const button = styles.hashClass({
* padding: '8px 12px',
* borderRadius: '8px',
* styles.class('card', {
* containerType: 'inline-size',
* ...styles.atRuleBlock(styles.container({ minWidth: 400 }), { padding: '24px' }),
* });
*
* const danger = styles.hashClass(
* { backgroundColor: 'red', color: 'white' },
* 'danger'
* );
* ```
*/
declare function createHashClass(properties: CSSProperties, label?: string): string;
/**
* Create a style group and return a selector function.
*
* **Two-argument form** (definitions object with 'base' and variants):
* @example Named container
* ```ts
* const button = styles.create('button', {
* base: { padding: '8px 16px' },
* primary: { backgroundColor: '#0066ff' },
* styles.class('item', {
* ...styles.atRuleBlock(styles.container('sidebar', { minWidth: 300 }), {
* flexDirection: 'row',
* }),
* });
* button('base', 'primary') // "button-base button-primary"
* ```
*
* **Three-argument form** (base styles + variants, no 'base' key needed):
* @example Style / scroll / `not` — raw condition after `@container`
* ```ts
* const button = styles.create('button',
* { padding: '8px 16px', borderRadius: '6px' }, // base styles
* {
* default: { backgroundColor: '#0066ff', color: '#fff' },
* outline: { border: '1px solid', backgroundColor: 'transparent' },
* large: { padding: '12px 24px' },
* }
* );
* button('default') // "button-base button-default" — base always included
* button('outline', 'large') // "button-base button-outline button-large"
* ...styles.atRuleBlock(styles.container('style(--theme: dark)'), { color: '#fff' })
* ```
*/
declare function createStyles<K extends string>(namespace: string, definitions: StyleDefinitions & Record<K, CSSProperties>): SelectorFunction<K>;
declare function createStyles(namespace: string, base: CSSProperties, variants: Record<string, CSSProperties>): SelectorFunction<string>;
declare function container<const F extends ContainerQueryObject>(features: F): ContainerObjectKey<F>;
declare function container<const N extends string, const F extends ContainerQueryFeatures>(name: N, features: F): CondFromFeatures<F> extends infer B extends string ? B extends '' ? never : `@container ${N} ${B}` : never;
/** Raw condition after `@container` — literal `S` preserves a narrow key for `[container('…')]`. */
declare function container<const S extends string>(rawCondition: S): `@container ${S}`;
declare function container(rawCondition: string): ContainerQueryKey;
/**
* Compose multiple selector functions or class strings into one.
* Returns a new SelectorFunction that calls all inputs and joins results.
* Returns a one-key object to **spread** into a style map.
*
* TypeScript widens **computed** `[someFn()]` keys to `string`, which clashes with {@link CSSProperties}’s
* `` `@${string}` `` index signature. Spreading `Record<@${string}, CSSProperties>` preserves a narrow key type.
*
* Works for keys from `container()`, literal `'@media (…)'`, `'@supports (…)'`, etc.
*
* @example
* ```ts
* const base = styles.create('base', { padding: '8px' });
* const primary = styles.create('primary', { color: 'blue' });
* const button = styles.compose(base, primary);
*
* button('padding', 'color'); // "base-padding primary-color"
* styles.class('card', {
* padding: '16px',
* ...atRuleBlock(styles.container({ minWidth: 400 }), { padding: '24px' }),
* });
* ```
*/
type AnySelectorFunction = {
(...args: unknown[]): string;
};
declare function compose(...selectors: Array<AnySelectorFunction | string | false | null | undefined>): AnySelectorFunction;
type StylesWithUtilsApi<U extends StyleUtils> = {
class: (name: string, properties: CSSPropertiesWithUtils<U>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, label?: string) => string;
create: {
<K extends string>(namespace: string, definitions: StyleDefinitionsWithUtils<U> & Record<K, CSSPropertiesWithUtils<U>>): SelectorFunction<K>;
(namespace: string, base: CSSPropertiesWithUtils<U>, variants: Record<string, CSSPropertiesWithUtils<U>>): SelectorFunction<string>;
};
compose: typeof compose;
};
declare function atRuleBlock<const K extends `@${string}`>(key: K, block: CSSProperties): Record<K, CSSProperties>;
/**
* Create a utility-aware styles API, similar to Stitches' `utils`.
* Object key for nested styles using {@link has} — compiles to `.base:has(…)`.
* Prefer variadic {@link has} so keys narrow to a single literal (mixes cleanly with longhands).
*/
type HasNestedKey = `&:has(${string})`;
/**
* Object key for nested styles using {@link is} — compiles to `.base:is(…)`.
*/
type IsNestedKey = `&:is(${string})`;
/**
* Object key for nested styles using {@link where} — compiles to `.base:where(…)` (zero-specificity).
*/
type WhereNestedKey = `&:where(${string})`;
/**
* Pseudos often grouped with {@link is} for shared focus/hover styles.
* Plain strings still work; this union improves autocomplete at call sites.
*/
type IsPseudoArg = ':hover' | ':active' | ':focus' | ':focus-visible' | ':focus-within' | ':disabled' | ':enabled' | ':checked' | ':indeterminate' | ':read-only' | ':read-write' | ':placeholder-shown' | ':default' | ':required' | ':optional' | ':valid' | ':invalid' | ':in-range' | ':out-of-range' | ':any-link' | ':link' | ':visited' | ':target' | ':target-within';
/**
* Build a nested style key for `:has()` — parental/descendant-aware styling without leaving the style object.
*
* Accepts a [relative selector list](https://drafts.csswg.org/selectors/#relative-real-selector-list):
* multiple arguments become comma-separated branches inside `:has()`.
*
* **Ecosystem:** StyleX exposes contextual selectors via dedicated `when.*` helpers; Panda/Stitches lean on
* nesting strings. TypeStyles keeps emit as real CSS and adds small builders beside raw `'&:has(…)'` keys.
*
* @example
* ```ts
* const u = createStylesWithUtils({
* marginX: (value: string | number) => ({ marginLeft: value, marginRight: value }),
* size: (value: string | number) => ({ width: value, height: value }),
* styles.class('nav', {
* base: { display: 'flex' },
* [has('.active')]: { borderBottom: '2px solid blue' },
* });
*
* const card = u.class('card', {
* size: 40,
* marginX: 16,
* });
* ```
*/
declare function createStylesWithUtils<U extends StyleUtils>(utils: U): StylesWithUtilsApi<U>;
declare function has<const T extends readonly string[]>(...relativeSelectors: T): `&:has(${JoinComma<T>})`;
/**
* Create design tokens as CSS custom properties.
* Build a nested style key for `:is()` — group pseudos or tags into one branch with the specificity of the
* most specific argument selector.
*
* Generates a :root rule with the custom properties and returns
* a typed object where property access yields var() references.
*
* @example
* ```ts
* const color = createTokens('color', {
* primary: '#0066ff',
* secondary: '#6b7280',
* });
*
* color.primary // "var(--color-primary)"
* [is(':hover', ':focus-visible')]: { outline: '2px solid blue' }
* ```
*/
declare function createTokens<T extends TokenValues>(namespace: string, values: T): TokenRef<T>;
declare function is<const T extends readonly string[]>(...selectors: T): `&:is(${JoinComma<T>})`;
/**
* Reference tokens defined elsewhere without injecting CSS.
* Build a nested style key for `:where()` — **zero-specificity** wrapper so library defaults stay easy for
* consumers to override (unlike `:is()`, which preserves specificity of its arguments).
*
* Returns a typed proxy that produces var() references.
* Useful for consuming shared tokens from a different module.
*
* @example
* ```ts
* const color = useTokens('color');
* color.primary // "var(--color-primary)"
* [where('.nav')]: { display: 'flex', gap: '8px' }
* ```
*/
declare function useTokens<T extends TokenValues = TokenValues>(namespace: string): TokenRef<T>;
declare function where<const T extends readonly string[]>(...selectors: T): `&:where(${JoinComma<T>})`;
/**
* Create a theme class that overrides token values.
* Compose multiple component functions or class strings into one.
* Returns a new function that calls all inputs and joins results.
*
* Returns a class name string. Apply it to any element to override
* token values for that subtree via CSS custom property cascading.
*
* @example
* ```ts
* const dark = createTheme('dark', {
* color: { primary: '#66b3ff', surface: '#1a1a2e' },
* });
* const base = styles.component('base', { base: { padding: '8px' } });
* const primary = styles.component('primary', { base: { color: 'blue' } });
* const button = styles.compose(base, primary);
*
* <div className={dark}> // class="theme-dark"
* button(); // "base-base primary-base"
* ```
*/
declare function createTheme(name: string, overrides: ThemeOverrides): string;
type AnySelectorFunction = {
(...args: unknown[]): string;
};
declare function compose(...selectors: Array<AnySelectorFunction | string | false | null | undefined>): AnySelectorFunction;
type StylesApi = {
/** Resolved naming config for this instance (useful for debugging). */
readonly classNaming: Readonly<ClassNamingConfig>;
/**
* Typed `@container` object keys for nested styles (size features, named containers, or raw conditions).
* Same function as the named export `container` from `typestyles`.
*/
readonly container: typeof container;
/**
* Readable `container-name` for `containerName`: `{scopeId}-{label}` or `{prefix}-{label}` when `scopeId` is empty.
* Same as `createContainerRef(label, { scopeId, prefix })` from this instance’s naming config.
*/
readonly containerRef: (label: string) => ContainerNameRef;
/**
* Build a spreadable `{ [ @key ]: nested }` so computed `@…` keys stay typed (see `atRuleBlock` export).
*/
readonly atRuleBlock: typeof atRuleBlock;
/**
* Nested `&:has(…)` object keys (same helpers as the `has` export).
*/
readonly has: typeof has;
/**
* Nested `&:is(…)` object keys for grouped states (same as the `is` export).
*/
readonly is: typeof is;
/**
* Nested `&:where(…)` keys — zero-specificity defaults (same as the `where` export).
*/
readonly where: typeof where;
class: (name: string, properties: CSSProperties) => string;
hashClass: (properties: CSSProperties, label?: string) => string;
component: {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>): MultiSlotReturn<Slots>;
};
withUtils: <U extends StyleUtils>(utils: U) => StylesWithUtilsApi<U>;
compose: typeof compose;
};
/** Options argument for styles when `createStyles({ layers })` is used. */
type LayerOption<L extends string = string> = {
readonly layer: L;
};
type CreateStylesInput = Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers?: CascadeLayersInput;
/**
* Only applies when using `createTokens` / `createTypeStyles` for `:root` and theme CSS.
* Ignored by `createStyles` alone (passing it here avoids repeating the key at the factory).
*/
tokenLayer?: string;
};
type LayeredComponentFn<L extends string> = {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>, options: LayerOption<L>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>, options: LayerOption<L>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>, options: LayerOption<L>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>, options: LayerOption<L>): MultiSlotReturn<Slots>;
};
type LayeredComponentFnWithUtils<L extends string> = {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>, options: LayerOption<L>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>, options: LayerOption<L>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>, options: LayerOption<L>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>, options: LayerOption<L>): MultiSlotReturn<Slots>;
};
type StylesWithUtilsApiLayered<U extends StyleUtils, L extends string> = Omit<StylesWithUtilsApi<U>, 'class' | 'hashClass' | 'component'> & {
class: (name: string, properties: CSSPropertiesWithUtils<U>, options: LayerOption<L>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, options: LayerOption<L> & {
label?: string;
}) => string;
component: LayeredComponentFnWithUtils<L>;
compose: typeof compose;
};
type StylesApiWithLayers<L extends string> = Omit<StylesApi, 'class' | 'hashClass' | 'component' | 'withUtils'> & {
class: (name: string, properties: CSSProperties, options: LayerOption<L>) => string;
hashClass: (properties: CSSProperties, options: LayerOption<L> & {
label?: string;
}) => string;
component: LayeredComponentFn<L>;
withUtils: <U extends StyleUtils>(utils: U) => StylesWithUtilsApiLayered<U, L>;
};
/**
* Create a styles API with its own class naming config (scope, mode, prefix).
* Use one instance per package or micro-frontend so hashed names stay isolated without global mutation.
* Pass **`scopeId`** (or `fileScopeId(import.meta)` per module) so duplicate logical namespaces across
* files do not collide; in development, registering the same name twice under one scope throws.
*
* Pass **`layers`** to enable CSS cascade layers: a tuple (or `{ order, prependFrameworkLayers? }`)
* defines a single `@layer a, b, c;` preamble, and every `class` / `hashClass` / `component` call
* must pass `{ layer: … }` with a name from that stack.
*/
declare function createStyles<const L extends readonly string[]>(options: Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers: L;
tokenLayer?: L[number];
}): StylesApiWithLayers<L[number]>;
declare function createStyles(options: Partial<Omit<ClassNamingConfig, 'cascadeLayers'>> & {
layers: CascadeLayersObjectInput;
tokenLayer?: string;
}): StylesApiWithLayers<string>;
declare function createStyles(options?: CreateStylesInput): StylesApi;
type StylesWithUtilsApi<U extends StyleUtils> = {
readonly container: typeof container;
readonly containerRef: (label: string) => ContainerNameRef;
readonly atRuleBlock: typeof atRuleBlock;
readonly has: typeof has;
readonly is: typeof is;
readonly where: typeof where;
class: (name: string, properties: CSSPropertiesWithUtils<U>) => string;
hashClass: (properties: CSSPropertiesWithUtils<U>, label?: string) => string;
component: {
<const V extends VariantDefinitions>(namespace: string, config: ComponentConfigInput<V>): ComponentReturn<V>;
<const K extends string>(namespace: string, config: FlatComponentConfigInput<K>): FlatComponentReturn<K>;
<const Slots extends readonly string[], V extends SlotVariantDefinitions<Slots[number]>>(namespace: string, config: SlotComponentConfigInput<Slots, V>): SlotComponentFunction<Slots, V>;
<const Slots extends readonly string[]>(namespace: string, config: MultiSlotConfigInput<Slots>): MultiSlotReturn<Slots>;
};
compose: typeof compose;
};
type CreateGlobalOptions = {
/**
* Prefixes inserted rule keys so globals from different bundles dedupe independently.
* Within one scope, each `selector` (+ optional `layer`) maps to a single rule: a second
* `global.style('body', …)` with different properties is ignored; non-production builds warn.
*/
scopeId?: string;
};
type CreateGlobalWithLayers = CreateGlobalOptions & {
layers: CascadeLayersInput;
/**
* Default `@layer` for `style()` when the call (or recipe tuple) omits `{ layer }`.
* Must be one of the stack’s own layer names (not a prepended framework layer).
*/
globalLayer?: string;
};
type GlobalApiUnlayered = {
readonly cascadeLayers: undefined;
style(tuple: GlobalStyleTuple): void;
style(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
/** Apply multiple recipe tuples (e.g. {@link reset} from `typestyles/globals`). */
apply(...tuples: GlobalStyleTuple[]): void;
fontFace(family: string, props: FontFaceProps): void;
};
type GlobalApiLayered = {
readonly cascadeLayers: ResolvedCascadeLayers;
style(tuple: GlobalStyleTuple): void;
style(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
apply(...tuples: GlobalStyleTuple[]): void;
fontFace(family: string, props: FontFaceProps): void;
};
declare function createGlobal(options?: CreateGlobalOptions): GlobalApiUnlayered;
declare function createGlobal(options: CreateGlobalWithLayers): GlobalApiLayered;
type NamingPartial = Partial<Omit<ClassNamingConfig, 'cascadeLayers'>>;
type GlobalLayerOption<L extends string = string> = {
/**
* Default `@layer` for `global.style()` when using `layers`.
* Omit to require `{ layer }` on each `global.style` call or recipe tuple.
* Per-call override: `global.style(selector, props, { layer: '…' })` or `body(props, { layer: '…' })`.
*/
globalLayer?: L;
};
/** Unified factory: one `scopeId`, shared cascade layer stack for both class rules and token/theme CSS. */
declare function createTypeStyles(options: NamingPartial): {
styles: StylesApi;
tokens: TokensApi;
global: GlobalApiUnlayered;
};
declare function createTypeStyles<const L extends readonly [string, ...string[]]>(options: NamingPartial & {
layers: L;
tokenLayer: L[number];
} & GlobalLayerOption<L[number]>): {
styles: StylesApiWithLayers<L[number]>;
tokens: TokensApi;
global: GlobalApiLayered;
};
declare function createTypeStyles(options: NamingPartial & {
layers: CascadeLayersObjectInput;
tokenLayer: string;
} & GlobalLayerOption): {
styles: StylesApiWithLayers<string>;
tokens: TokensApi;
global: GlobalApiLayered;
};
/**

@@ -327,3 +704,3 @@ * A keyframe stop is either 'from', 'to', or a percentage like '50%'.

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { animation: `${fadeIn} 300ms ease` },

@@ -478,38 +855,2 @@ * });

/**
* Create a multi-variant component style and return a selector function.
*
* Class naming convention (default `semantic` mode; see `configureClassNaming`):
* base → `{namespace}-base`
* variants.intent.primary → `{namespace}-intent-primary`
* compoundVariants[0] → `{namespace}-compound-0`
*
* @example
* ```ts
* const button = styles.component('button', {
* base: { padding: '8px 16px' },
* variants: {
* intent: {
* primary: { backgroundColor: '#0066ff', color: '#fff' },
* ghost: { backgroundColor: 'transparent', border: '1px solid currentColor' },
* },
* size: {
* sm: { fontSize: '12px' },
* lg: { fontSize: '18px' },
* },
* },
* compoundVariants: [
* { variants: { intent: 'primary', size: 'lg' }, style: { fontWeight: 700 } },
* ],
* defaultVariants: { intent: 'primary', size: 'sm' },
* });
*
* button() // "button-base button-intent-primary button-size-sm"
* button({ intent: 'ghost' }) // "button-base button-intent-ghost button-size-sm"
* button({ intent: 'primary', size: 'lg' }) // includes compound class
* ```
*/
declare function createComponent<V extends VariantDefinitions>(namespace: string, config: ComponentConfig<V>): ComponentFunction<V>;
declare function createComponent<S extends string, V extends SlotVariantDefinitions<S>>(namespace: string, config: SlotComponentConfig<S, V>): SlotComponentFunction<S, V>;
/**
* Apply styles to an arbitrary CSS selector.

@@ -526,4 +867,20 @@ *

* ```
*
* Also accepts a tuple from `typestyles/globals` recipes:
*
* ```ts
* import { boxSizing, body } from 'typestyles/globals';
* global.style(boxSizing());
* global.style(body({ margin: 0 }));
* ```
*
* Optional `{ layer }` on the tuple or as a third argument is ignored on the root `global` object —
* use `createGlobal({ layers })` or `createTypeStyles({ layers }).global` for `@layer`.
*/
declare function globalStyle(selector: string, properties: CSSProperties): void;
declare function globalStyle(tuple: GlobalStyleTuple): void;
declare function globalStyle(selector: string, properties: CSSProperties, options?: {
layer?: string;
}): void;
/** Apply multiple `typestyles/globals` tuples (e.g. {@link reset}) in one call. */
declare function globalApply(...tuples: GlobalStyleTuple[]): void;
/**

@@ -534,3 +891,3 @@ * Declare a `@font-face` rule to load a custom font.

* this function multiple times with different `src` values — each call is
* deduplicated by `family + src`.
* deduplicated by `family +` normalized `src`.
*

@@ -553,2 +910,19 @@ * @example

* ```
*
* @example Variable font (weight range)
* ```ts
* global.fontFace('InterVar', {
* src: "url('/fonts/Inter.var.woff2') format('woff2')",
* fontWeight: '100 900',
* fontDisplay: 'swap',
* });
* ```
*
* @example Multiple `src` entries (e.g. `local()` then remote)
* ```ts
* global.fontFace('Inter', {
* src: [`local('Inter')`, "url('/fonts/Inter.woff2') format('woff2')"],
* fontDisplay: 'swap',
* });
* ```
*/

@@ -567,3 +941,3 @@ declare function globalFontFace(family: string, props: FontFaceProps): void;

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { background: cardBg, padding: '16px' },

@@ -592,52 +966,92 @@ * });

/**
* How generated class names are formed for `styles.create`, `styles.class`,
* `styles.component`, and related APIs.
* Join class name parts, filtering out falsy values.
*
* - `semantic` — readable names like `button-base`, `button-intent-primary` (default).
* - `hashed` — stable hash from namespace, variant segment, and declarations, with a short namespace slug for debugging.
* - `atomic` — hash-only names (shortest); same collision properties as `hashed` when `scopeId` differs.
* A lightweight utility for combining TypeStyles classes, external class
* strings, and conditional expressions into a single `className` string.
*
* @example
* ```ts
* import { cx } from 'typestyles';
*
* cx('card', isActive && 'active', className);
* // => "card active my-external-class"
*
* cx(button('base', 'primary'), 'extra');
* // => "button-base button-primary extra"
* ```
*/
type ClassNamingMode = 'semantic' | 'hashed' | 'atomic';
type ClassNamingConfig = {
mode: ClassNamingMode;
/** Prefix for hashed / atomic output and for `hashClass`. Default `ts`. */
prefix: string;
/**
* Optional package or app id mixed into hash input so identical logical
* names from different packages do not produce the same class string.
*/
scopeId: string;
};
declare function getClassNamingConfig(): Readonly<ClassNamingConfig>;
declare function cx(...parts: Array<string | undefined | null | false | 0 | ''>): string;
/**
* Set global class naming options. Call once at app or package entry
* (e.g. design-system `index.ts`) for per-package adoption in a monorepo.
* Helpers for CSS `calc()` and `clamp()` that keep the function parentheses in one place.
* Values are plain strings at runtime — no validation of inner syntax.
*/
declare function configureClassNaming(partial: Partial<ClassNamingConfig>): void;
/** Restore defaults (primarily for tests). */
declare function resetClassNaming(): void;
/** Token refs, lengths, percentages, etc. */
type CssMathValue = string | number;
/**
* Tagged template: wraps the interpolated expression in `calc(...)`.
*
* @example
* ```ts
* import { calc } from 'typestyles';
*
* calc`100vh - 2 * ${t.space[4]}`
* // => "calc(100vh - 2 * var(--space-4))"
* ```
*/
declare function calc(strings: TemplateStringsArray, ...values: CssMathValue[]): string;
/**
* CSS `clamp(MIN, PREFERRED, MAX)`.
*
* @example
* ```ts
* import { clamp } from 'typestyles';
*
* clamp('1rem', '5vw', '3rem')
* // => "clamp(1rem, 5vw, 3rem)"
* ```
*/
declare function clamp(min: CssMathValue, preferred: CssMathValue, max: CssMathValue): string;
/**
* Style creation API.
* Helper for CSS `content` string values. Emits a double-quoted CSS string; values are plain strings
* at runtime — same spirit as `calc` / `clamp` in css-math.
*/
/**
* Wrap `text` in a CSS string (`content: "…";`). `null` / `undefined` yield `''` (omit the property
* or pair with a conditional if you need no declaration).
*
* @example
* ```ts
* const button = styles.create('button', {
* import { content } from 'typestyles';
*
* content() // => '' (skip property or use a conditional if you want no rule)
* content('') // => '""' → valid `content: "";` for an empty pseudo-element box
* content('*') // => '"*"' → `content: "*";`
* ```
*/
declare function content(text?: string | null): string;
/**
* Default style API (semantic class names, empty `scopeId`). Prefer `createStyles({ scopeId, mode, prefix })`
* per package or micro-frontend for isolation.
*
* @example
* ```ts
* // Multi-variant component (CVA-style)
* const button = styles.component('button', {
* base: { padding: '8px 16px' },
* primary: { backgroundColor: '#0066ff' },
* variants: {
* intent: { primary: { backgroundColor: '#0066ff' } },
* size: { sm: { fontSize: '14px' }, lg: { fontSize: '18px' } },
* },
* defaultVariants: { intent: 'primary', size: 'sm' },
* });
*
* const hashed = styles.hashClass({ display: 'inline-flex' }, 'button');
* button({ intent: 'primary', size: 'lg' })
*
* <button className={`${button('base', 'primary')} ${hashed}`}>
* const card = styles.class('card', { padding: '1rem' });
* ```
*/
declare const styles: {
readonly create: typeof createStyles;
readonly class: typeof createClass;
readonly hashClass: typeof createHashClass;
readonly component: typeof createComponent;
readonly withUtils: typeof createStylesWithUtils;
readonly compose: typeof compose;
};
declare const styles: StylesApi;
/**

@@ -649,3 +1063,5 @@ * Global CSS API for arbitrary selectors and font-face declarations.

* global.style('body', { margin: 0 });
* global.apply(...reset());
* global.fontFace('Inter', { src: "url('/Inter.woff2') format('woff2')", fontWeight: 400 });
* global.fontFace('Inter', { src: [`local('Inter')`, "url('/Inter.woff2') format('woff2')"] });
* ```

@@ -655,21 +1071,21 @@ */

readonly style: typeof globalStyle;
readonly apply: typeof globalApply;
readonly fontFace: typeof globalFontFace;
};
/**
* Design token API using CSS custom properties.
* Default token API (unscoped custom properties). Prefer `createTokens({ scopeId })` when multiple
* bundles share a page.
*
* @example
* ```ts
* const color = tokens.create('color', {
* primary: '#0066ff',
* const color = tokens.create('color', { primary: '#0066ff' });
* color.primary // "var(--color-primary)"
*
* const acme = tokens.createTheme('acme', {
* base: { color: { primary: '#ff6600' } },
* colorMode: tokens.colorMode.mediaOnly({ dark: darkOverrides }),
* });
*
* color.primary // "var(--color-primary)"
* ```
*/
declare const tokens: {
readonly create: typeof createTokens;
readonly use: typeof useTokens;
readonly createTheme: typeof createTheme;
};
declare const tokens: TokensApi;
/**

@@ -685,3 +1101,3 @@ * Keyframe animation API.

*
* const card = styles.create('card', {
* const card = styles.component('card', {
* base: { animation: `${fadeIn} 300ms ease` },

@@ -711,2 +1127,2 @@ * });

export { type CSSProperties, type CSSPropertiesWithUtils, type CSSValue, type CSSVarRef, type ClassNamingConfig, type ClassNamingMode, type ColorMixSpace, type ComponentConfig, type ComponentFunction, type ComponentVariants, type FontFaceProps, type KeyframeStops$1 as KeyframeStops, type SelectorFunction, type SlotComponentConfig, type SlotComponentFunction, type SlotStyles, type SlotVariantDefinitions, type StyleDefinitions, type StyleDefinitionsWithUtils, type StyleUtils, type ThemeOverrides, type TokenRef, type TokenValues, type VariantDefinitions, assignVars, color, configureClassNaming, createVar, getClassNamingConfig, global, keyframes, resetClassNaming, styles, tokens };
export { CSSProperties, CSSPropertiesWithUtils, CSSVarRef, type CascadeLayersInput, type CascadeLayersObjectInput, type ClassNamingConfig, type ClassNamingMode, type ColorMixSpace, ComponentConfigInput, ComponentReturn, type ContainerNameRef, type ContainerObjectKey, type ContainerQueryFeatures, type ContainerQueryKey, type ContainerQueryObject, type CreateContainerRefOptions, type CreateStylesInput, type CreateTokensOptions, type CssMathValue, FlatComponentConfigInput, FlatComponentReturn, FontFaceProps, type GlobalApiLayered, type GlobalApiUnlayered, GlobalStyleTuple, type HasNestedKey, type IsNestedKey, type IsPseudoArg, type LayerOption, type LayeredComponentFn, MultiSlotConfigInput, type ResolvedCascadeLayers, SlotComponentConfigInput, SlotComponentFunction, SlotVariantDefinitions, StyleUtils, type StylesApi, type StylesApiWithLayers, ThemeCondition, ThemeConditionAnd, ThemeConditionAttr, ThemeConditionClass, ThemeConditionMedia, ThemeConditionOr, ThemeConditionSelector, ThemeConfig, type ThemeEmitLayerContext, ThemeModeDefinition, ThemeOverrides, ThemeSurface, TokenRef, TokenValues, type TokensApi, VariantDefinitions, type WhereNestedKey, assignVars, atRuleBlock, calc, clamp, color, colorMode, container, content, createContainerRef, createDarkMode, createGlobal, createStyles, createTheme, createTokens, createTypeStyles, createVar, cx, defaultClassNamingConfig, fileScopeId, global, has, is, keyframes, mergeClassNaming, scopedTokenNamespace, styles, tokens, when, where };

@@ -5,3 +5,7 @@ 'use strict';

var STYLE_ELEMENT_ID = "typestyles";
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true";
function readNextPublicRuntimeDisabled() {
if (typeof process === "undefined" || !process.env) return false;
return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === "true";
}
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true" || readNextPublicRuntimeDisabled();
var pendingRules = [];

@@ -12,8 +16,26 @@ var allRules = [];

var isBrowser = typeof document !== "undefined" && typeof window !== "undefined";
function writeAllRulesToStyleElement(el) {
if (RUNTIME_DISABLED || allRules.length === 0) return;
const sheet = el.sheet;
if (sheet) {
for (const css of allRules) {
try {
sheet.insertRule(css, sheet.cssRules.length);
} catch {
el.appendChild(document.createTextNode(css));
}
}
} else {
el.appendChild(document.createTextNode(allRules.join("\n")));
}
}
function getStyleElement() {
let reconnectAfterDetach = false;
if (styleElement && !styleElement.isConnected) {
reconnectAfterDetach = true;
styleElement = null;
}
if (styleElement) return styleElement;
const existing = document.getElementById(
STYLE_ELEMENT_ID
);
if (existing) {
const existing = document.getElementById(STYLE_ELEMENT_ID);
if (existing?.isConnected) {
styleElement = existing;

@@ -25,2 +47,5 @@ return styleElement;

document.head.appendChild(styleElement);
if (reconnectAfterDetach && allRules.length > 0) {
writeAllRulesToStyleElement(styleElement);
}
return styleElement;

@@ -27,0 +52,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/sheet.ts","../src/server.ts"],"names":[],"mappings":";;;AAAA,IAAM,gBAAA,GAAmB,YAAA;AAazB,IAAM,gBAAA,GACJ,OAAO,+BAAA,KAAoC,WAAA,IAC3C,+BAAA,KAAoC,MAAA;AAKtC,IAAI,eAAyB,EAAC;AAO9B,IAAM,WAAqB,EAAC;AAU5B,IAAI,YAAA,GAAwC,IAAA;AAK5C,IAAI,SAAA,GAA6B,IAAA;AAKjC,IAAM,SAAA,GACJ,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,MAAA,KAAW,WAAA;AAEvD,SAAS,eAAA,GAAoC;AAC3C,EAAA,IAAI,cAAc,OAAO,YAAA;AAGzB,EAAA,MAAM,WAAW,QAAA,CAAS,cAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,YAAA,GAAe,QAAA;AACf,IAAA,OAAO,YAAA;AAAA,EACT;AAGA,EAAA,YAAA,GAAe,QAAA,CAAS,cAAc,OAAO,CAAA;AAC7C,EAAA,YAAA,CAAa,EAAA,GAAK,gBAAA;AAClB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,YAAY,CAAA;AACtC,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,KAAA,GAAc;AAErB,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE/B,EAAA,MAAM,KAAA,GAAQ,YAAA;AACd,EAAA,YAAA,GAAe,EAAC;AAEhB,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,SAAA,CAAU,IAAA,CAAK,GAAG,KAAK,CAAA;AACvB,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,aAAa,gBAAA,EAAkB;AAEpC,EAAA,MAAM,KAAK,eAAA,EAAgB;AAC3B,EAAA,MAAM,QAAQ,EAAA,CAAG,KAAA;AAEjB,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI;AACF,QAAA,KAAA,CAAM,UAAA,CAAW,IAAA,EAAM,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAEN,QAAA,EAAA,CAAG,WAAA,CAAY,QAAA,CAAS,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AAEL,IAAA,EAAA,CAAG,YAAY,QAAA,CAAS,cAAA,CAAe,MAAM,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA;AAAA,EAC1D;AACF;AAuEO,SAAS,eAAA,GAAgC;AAC9C,EAAA,SAAA,GAAY,EAAC;AACb,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,GAAA,GAAM,SAAA,GAAY,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,EAAA;AAC/C,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AACF;AAsBO,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAC3B;AAoBO,SAAS,SAAA,GAAkB;AAChC,EAAA,KAAA,EAAM;AACR;;;ACjMO,SAAS,cAAiB,QAAA,EAA6C;AAC5E,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,MAAM,OAAO,QAAA,EAAS;AACtB,EAAA,SAAA,EAAU;AACV,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,OAAO,EAAE,MAAM,GAAA,EAAI;AACrB","file":"server.cjs","sourcesContent":["const STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nconst RUNTIME_DISABLED =\n typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true';\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser =\n typeof document !== 'undefined' && typeof window !== 'undefined';\n\nfunction getStyleElement(): HTMLStyleElement {\n if (styleElement) return styleElement;\n\n // Check for an existing element (e.g., from SSR)\n const existing = document.getElementById(\n STYLE_ELEMENT_ID\n ) as HTMLStyleElement | null;\n if (existing) {\n styleElement = existing;\n return styleElement;\n }\n\n // Create a new one\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n return styleElement;\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) continue;\n insertedRules.add(key);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.create`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return (\n rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`)\n );\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color -> :root rule with --color- custom properties\n const namespace = key.slice('tokens:'.length);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n","import { startCollection, flushSync, getRegisteredCss } from './sheet.js';\n\nexport { getRegisteredCss };\n\n/**\n * Collect all CSS generated during a render pass (for SSR).\n *\n * Wraps a synchronous render function and captures all CSS that would\n * normally be injected into the DOM. Returns both the render result\n * and the collected CSS string.\n *\n * For frameworks where you need the CSS separately from the render pass\n * (e.g. TanStack Start's `head()`, Next.js metadata), use the simpler\n * `getRegisteredCss()` instead.\n *\n * @example\n * ```ts\n * import { collectStyles } from 'typestyles/server';\n * import { renderToString } from 'react-dom/server';\n *\n * const { html, css } = collectStyles(() => renderToString(<App />));\n *\n * const fullHtml = `\n * <html>\n * <head><style id=\"typestyles\">${css}</style></head>\n * <body>${html}</body>\n * </html>\n * `;\n * ```\n */\nexport function collectStyles<T>(renderFn: () => T): { html: T; css: string } {\n const endCollection = startCollection();\n\n const html = renderFn();\n flushSync();\n const css = endCollection();\n\n return { html, css };\n}\n"]}
{"version":3,"sources":["../src/sheet.ts","../src/server.ts"],"names":[],"mappings":"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","file":"server.cjs","sourcesContent":["import {\n namespacesFromTypestylesHmrPrefixes,\n releaseReservedNamespacesForComponentOrClassNames,\n} from './registry';\n\nconst STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Last emitted CSS per dedupe key (see {@link warnIfDuplicateRuleKeyConflict}).\n * Cleared with {@link reset} and kept in sync when keys are invalidated.\n */\nconst ruleCssByKey = new Map<string, string>();\n\nfunction duplicateRuleKeyConflictWarningsEnabled(): boolean {\n if (typeof process === 'undefined') return true;\n return process.env.NODE_ENV !== 'production';\n}\n\n/**\n * When the same key is registered again with different CSS, the second rule is skipped\n * (idempotency / HMR). In non-production builds, surface that so overlapping globals\n * (e.g. reset `body` + app `body` in the same scope) are not silent failures.\n */\nfunction warnIfDuplicateRuleKeyConflict(\n key: string,\n previousCss: string,\n ignoredCss: string,\n): void {\n if (!duplicateRuleKeyConflictWarningsEnabled()) return;\n const prevShort = previousCss.length > 220 ? `${previousCss.slice(0, 220)}…` : previousCss;\n const nextShort = ignoredCss.length > 220 ? `${ignoredCss.slice(0, 220)}…` : ignoredCss;\n console.warn(\n `[typestyles] Skipped a rule: dedupe key \"${key}\" already exists with different CSS. ` +\n `Only the first registration is kept. For globals, merge into one \\`global.style\\`, ` +\n `or use a distinct selector (e.g. \\`html body\\` after reset’s \\`body\\`).\\n` +\n ` Existing: ${prevShort}\\n` +\n ` Skipped: ${nextShort}`,\n );\n}\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n *\n * `@typestyles/next/build` `withTypestylesExtract` sets `NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED`\n * via `next.config` `env` so Turbopack and webpack both inline the flag (DefinePlugin\n * alone does not run under Turbopack).\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nfunction readNextPublicRuntimeDisabled(): boolean {\n if (typeof process === 'undefined' || !process.env) return false;\n return process.env.NEXT_PUBLIC_TYPESTYLES_RUNTIME_DISABLED === 'true';\n}\nconst RUNTIME_DISABLED =\n (typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true') ||\n readNextPublicRuntimeDisabled();\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser = typeof document !== 'undefined' && typeof window !== 'undefined';\n\n/**\n * Re-insert every registered rule into a (usually fresh) <style> element.\n * Used when the live element was detached (e.g. Astro view transitions replacing <head>).\n */\nfunction writeAllRulesToStyleElement(el: HTMLStyleElement): void {\n if (RUNTIME_DISABLED || allRules.length === 0) return;\n const sheet = el.sheet;\n if (sheet) {\n for (const css of allRules) {\n try {\n sheet.insertRule(css, sheet.cssRules.length);\n } catch {\n el.appendChild(document.createTextNode(css));\n }\n }\n } else {\n el.appendChild(document.createTextNode(allRules.join('\\n')));\n }\n}\n\nfunction getStyleElement(): HTMLStyleElement {\n let reconnectAfterDetach = false;\n if (styleElement && !styleElement.isConnected) {\n reconnectAfterDetach = true;\n styleElement = null;\n }\n if (styleElement) return styleElement;\n\n // Prefer an element actually in the document (SSR or another copy on the page).\n const existing = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement | null;\n if (existing?.isConnected) {\n styleElement = existing;\n return styleElement;\n }\n\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n\n // After a doc swap, we have a new empty sheet but insertRule() won't re-queue (deduped keys).\n if (reconnectAfterDetach && allRules.length > 0) {\n writeAllRulesToStyleElement(styleElement);\n }\n\n return styleElement;\n}\n\n/**\n * Ensure the managed <style id=\"typestyles\"> is attached to the current document and populated.\n * Call after SPA-style navigation (e.g. Astro `astro:after-swap`) when runtime injection is enabled.\n */\nexport function ensureDocumentStylesAttached(): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n getStyleElement();\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Register a single `@layer a, b, c;` preamble so layer **order** is defined before any\n * `@layer name { … }` blocks. Inserts at the front of the virtual sheet and at CSSOM index 0\n * when injecting into the document.\n */\nexport function registerCascadeLayerOrder(preambleKey: string, css: string): void {\n const key = `typestyles:@layer-order:${preambleKey}`;\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n\n allRules.unshift(css);\n\n if (ssrBuffer) {\n ssrBuffer.unshift(css);\n return;\n }\n\n if (RUNTIME_DISABLED) return;\n\n if (!isBrowser) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n try {\n sheet.insertRule(css, 0);\n } catch {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n } else {\n el.insertBefore(document.createTextNode(`${css}\\n`), el.firstChild);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n return;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) {\n const prev = ruleCssByKey.get(key);\n if (prev != null && prev !== css) {\n warnIfDuplicateRuleKeyConflict(key, prev, css);\n }\n continue;\n }\n insertedRules.add(key);\n ruleCssByKey.set(key, css);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.component`, `styles.class`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n ruleCssByKey.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes([prefix]));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n ruleCssByKey.delete(key);\n }\n }\n }\n\n releaseReservedNamespacesForComponentOrClassNames(namespacesFromTypestylesHmrPrefixes(prefixes));\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Drop every rule key tied to a `styles.component('namespace', …)` registration, including\n * `@layer`-wrapped keys (`layer:….:.namespace-…`), and release reserved namespace entries.\n * Used for Vite HMR and for dev recovery when a module re-runs before `hot.dispose`.\n */\nexport function invalidateComponentNamespaceForDev(namespace: string): void {\n const selectorInfix = `.${namespace}-`;\n const keysToDrop: string[] = [];\n for (const k of insertedRules) {\n if (k.includes(selectorInfix)) {\n keysToDrop.push(k);\n }\n }\n invalidateKeys(keysToDrop, [selectorInfix]);\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`);\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color or tokens:color@layerName -> :root rule with --color- custom properties\n const rest = key.slice('tokens:'.length);\n const at = rest.lastIndexOf('@');\n const namespace = at === -1 ? rest : rest.slice(0, at);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n","import { startCollection, flushSync, getRegisteredCss } from './sheet';\n\nexport { getRegisteredCss };\n\n/**\n * Collect all CSS generated during a render pass (for SSR).\n *\n * Wraps a synchronous render function and captures all CSS that would\n * normally be injected into the DOM. Returns both the render result\n * and the collected CSS string.\n *\n * For frameworks where you need the CSS separately from the render pass\n * (e.g. TanStack Start's `head()`, Next.js metadata), use the simpler\n * `getRegisteredCss()` instead.\n *\n * @example\n * ```ts\n * import { collectStyles } from 'typestyles/server';\n * import { renderToString } from 'react-dom/server';\n *\n * const { html, css } = collectStyles(() => renderToString(<App />));\n *\n * const fullHtml = `\n * <html>\n * <head><style id=\"typestyles\">${css}</style></head>\n * <body>${html}</body>\n * </html>\n * `;\n * ```\n */\nexport function collectStyles<T>(renderFn: () => T): { html: T; css: string } {\n const endCollection = startCollection();\n\n const html = renderFn();\n flushSync();\n const css = endCollection();\n\n return { html, css };\n}\n"]}

@@ -1,2 +0,2 @@

export { g as getRegisteredCss } from './hmr-BACAnP4Y.cjs';
export { g as getRegisteredCss } from './hmr-D5sXuQgK.cjs';

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

export { g as getRegisteredCss } from './hmr-BACAnP4Y.js';
export { g as getRegisteredCss } from './hmr-D5sXuQgK.js';

@@ -3,0 +3,0 @@ /**

@@ -1,3 +0,4 @@

import { startCollection, flushSync } from './chunk-AYFIQGCF.js';
export { getRegisteredCss } from './chunk-AYFIQGCF.js';
import { startCollection, flushSync } from './chunk-G6ATUNEZ.js';
export { getRegisteredCss } from './chunk-G6ATUNEZ.js';
import './chunk-PZ5AY32C.js';

@@ -4,0 +5,0 @@ // src/server.ts

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/server.ts"],"names":[],"mappings":";;;;AA8BO,SAAS,cAAiB,QAAA,EAA6C;AAC5E,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,MAAM,OAAO,QAAA,EAAS;AACtB,EAAA,SAAA,EAAU;AACV,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,OAAO,EAAE,MAAM,GAAA,EAAI;AACrB","file":"server.js","sourcesContent":["import { startCollection, flushSync, getRegisteredCss } from './sheet.js';\n\nexport { getRegisteredCss };\n\n/**\n * Collect all CSS generated during a render pass (for SSR).\n *\n * Wraps a synchronous render function and captures all CSS that would\n * normally be injected into the DOM. Returns both the render result\n * and the collected CSS string.\n *\n * For frameworks where you need the CSS separately from the render pass\n * (e.g. TanStack Start's `head()`, Next.js metadata), use the simpler\n * `getRegisteredCss()` instead.\n *\n * @example\n * ```ts\n * import { collectStyles } from 'typestyles/server';\n * import { renderToString } from 'react-dom/server';\n *\n * const { html, css } = collectStyles(() => renderToString(<App />));\n *\n * const fullHtml = `\n * <html>\n * <head><style id=\"typestyles\">${css}</style></head>\n * <body>${html}</body>\n * </html>\n * `;\n * ```\n */\nexport function collectStyles<T>(renderFn: () => T): { html: T; css: string } {\n const endCollection = startCollection();\n\n const html = renderFn();\n flushSync();\n const css = endCollection();\n\n return { html, css };\n}\n"]}
{"version":3,"sources":["../src/server.ts"],"names":[],"mappings":";;;;;AA8BO,SAAS,cAAiB,QAAA,EAA6C;AAC5E,EAAA,MAAM,gBAAgB,eAAA,EAAgB;AAEtC,EAAA,MAAM,OAAO,QAAA,EAAS;AACtB,EAAA,SAAA,EAAU;AACV,EAAA,MAAM,MAAM,aAAA,EAAc;AAE1B,EAAA,OAAO,EAAE,MAAM,GAAA,EAAI;AACrB","file":"server.js","sourcesContent":["import { startCollection, flushSync, getRegisteredCss } from './sheet';\n\nexport { getRegisteredCss };\n\n/**\n * Collect all CSS generated during a render pass (for SSR).\n *\n * Wraps a synchronous render function and captures all CSS that would\n * normally be injected into the DOM. Returns both the render result\n * and the collected CSS string.\n *\n * For frameworks where you need the CSS separately from the render pass\n * (e.g. TanStack Start's `head()`, Next.js metadata), use the simpler\n * `getRegisteredCss()` instead.\n *\n * @example\n * ```ts\n * import { collectStyles } from 'typestyles/server';\n * import { renderToString } from 'react-dom/server';\n *\n * const { html, css } = collectStyles(() => renderToString(<App />));\n *\n * const fullHtml = `\n * <html>\n * <head><style id=\"typestyles\">${css}</style></head>\n * <body>${html}</body>\n * </html>\n * `;\n * ```\n */\nexport function collectStyles<T>(renderFn: () => T): { html: T; css: string } {\n const endCollection = startCollection();\n\n const html = renderFn();\n flushSync();\n const css = endCollection();\n\n return { html, css };\n}\n"]}
{
"name": "typestyles",
"version": "0.4.0",
"version": "0.5.0",
"description": "CSS-in-TypeScript that embraces CSS instead of hiding from it",

@@ -49,2 +49,12 @@ "type": "module",

}
},
"./globals": {
"import": {
"types": "./dist/globals.d.ts",
"default": "./dist/globals.js"
},
"require": {
"types": "./dist/globals.d.cts",
"default": "./dist/globals.cjs"
}
}

@@ -76,2 +86,3 @@ },

"@vitest/coverage-v8": "^3.0.0",
"eslint": "^9.39.2",
"jsdom": "^25.0.0",

@@ -87,4 +98,5 @@ "tsup": "^8.0.0",

"test:watch": "vitest",
"lint": "eslint .",
"typecheck": "tsc --noEmit"
}
}
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/sheet.ts
var STYLE_ELEMENT_ID = "typestyles";
var insertedRules = /* @__PURE__ */ new Set();
var RUNTIME_DISABLED = typeof __TYPESTYLES_RUNTIME_DISABLED__ !== "undefined" && __TYPESTYLES_RUNTIME_DISABLED__ === "true";
var pendingRules = [];
var allRules = [];
var flushScheduled = false;
var styleElement = null;
var ssrBuffer = null;
var isBrowser = typeof document !== "undefined" && typeof window !== "undefined";
function getStyleElement() {
if (styleElement) return styleElement;
const existing = document.getElementById(
STYLE_ELEMENT_ID
);
if (existing) {
styleElement = existing;
return styleElement;
}
styleElement = document.createElement("style");
styleElement.id = STYLE_ELEMENT_ID;
document.head.appendChild(styleElement);
return styleElement;
}
function flush() {
flushScheduled = false;
if (pendingRules.length === 0) return;
const rules = pendingRules;
pendingRules = [];
if (ssrBuffer) {
ssrBuffer.push(...rules);
return;
}
if (!isBrowser || RUNTIME_DISABLED) return;
const el = getStyleElement();
const sheet = el.sheet;
if (sheet) {
for (const rule of rules) {
try {
sheet.insertRule(rule, sheet.cssRules.length);
} catch {
el.appendChild(document.createTextNode(rule));
}
}
} else {
el.appendChild(document.createTextNode(rules.join("\n")));
}
}
function scheduleFlush() {
if (flushScheduled) return;
flushScheduled = true;
if (ssrBuffer) {
flush();
return;
}
if (isBrowser && !RUNTIME_DISABLED) {
queueMicrotask(flush);
}
}
function insertRule(key, css) {
if (insertedRules.has(key)) return;
insertedRules.add(key);
allRules.push(css);
if (RUNTIME_DISABLED && !ssrBuffer) return;
pendingRules.push(css);
scheduleFlush();
}
function insertRules(rules) {
let added = false;
for (const { key, css } of rules) {
if (insertedRules.has(key)) continue;
insertedRules.add(key);
allRules.push(css);
if (!RUNTIME_DISABLED || ssrBuffer) {
pendingRules.push(css);
added = true;
}
}
if (added) scheduleFlush();
}
function startCollection() {
ssrBuffer = [];
return () => {
const css = ssrBuffer ? ssrBuffer.join("\n") : "";
ssrBuffer = null;
return css;
};
}
function getRegisteredCss() {
return allRules.join("\n");
}
function reset() {
insertedRules.clear();
pendingRules = [];
allRules.length = 0;
flushScheduled = false;
ssrBuffer = null;
if (isBrowser && styleElement) {
styleElement.remove();
styleElement = null;
}
}
function flushSync() {
flush();
}
function invalidatePrefix(prefix) {
for (const key of insertedRules) {
if (key.startsWith(prefix)) {
insertedRules.delete(key);
}
}
if (!isBrowser) return;
const el = styleElement;
if (!el) return;
const sheet = el.sheet;
if (!sheet) return;
for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
const rule = sheet.cssRules[i];
if (ruleMatchesPrefix(rule, prefix)) {
sheet.deleteRule(i);
}
}
}
function invalidateKeys(keys, prefixes) {
for (const key of keys) {
insertedRules.delete(key);
}
for (const prefix of prefixes) {
for (const key of insertedRules) {
if (key.startsWith(prefix)) {
insertedRules.delete(key);
}
}
}
if (!isBrowser) return;
const el = styleElement;
if (!el) return;
const sheet = el.sheet;
if (!sheet) return;
const keySet = new Set(keys);
for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
const rule = sheet.cssRules[i];
let shouldRemove = false;
for (const prefix of prefixes) {
if (ruleMatchesPrefix(rule, prefix)) {
shouldRemove = true;
break;
}
}
if (!shouldRemove) {
const ruleText = rule.cssText;
for (const key of keySet) {
if (ruleMatchesKey(ruleText, key)) {
shouldRemove = true;
break;
}
}
}
if (shouldRemove) {
sheet.deleteRule(i);
}
}
}
function ruleMatchesPrefix(rule, prefix) {
if (prefix.startsWith("font-face:")) {
const family = prefix.slice("font-face:".length).split(":")[0];
if (rule.cssText.includes("@font-face")) {
return rule.cssText.includes(`"${family}"`) || rule.cssText.includes(`'${family}'`);
}
return false;
}
if ("selectorText" in rule) {
return rule.selectorText.startsWith(prefix);
}
if ("name" in rule && prefix.startsWith("keyframes:")) {
return rule.name === prefix.slice("keyframes:".length);
}
if ("cssRules" in rule) {
const innerRules = rule.cssRules;
for (let i = 0; i < innerRules.length; i++) {
if (ruleMatchesPrefix(innerRules[i], prefix)) return true;
}
}
return false;
}
function ruleMatchesKey(cssText, key) {
if (key.startsWith("tokens:")) {
const namespace = key.slice("tokens:".length);
return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);
}
if (key.startsWith("theme:")) {
const name = key.slice("theme:".length);
return cssText.includes(`.theme-${name}`);
}
if (key.startsWith("keyframes:")) {
const name = key.slice("keyframes:".length);
return cssText.includes(`@keyframes ${name}`);
}
return false;
}
export { __export, flushSync, getRegisteredCss, insertRule, insertRules, invalidateKeys, invalidatePrefix, reset, startCollection };
//# sourceMappingURL=chunk-AYFIQGCF.js.map
//# sourceMappingURL=chunk-AYFIQGCF.js.map
{"version":3,"sources":["../src/sheet.ts"],"names":[],"mappings":"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","file":"chunk-AYFIQGCF.js","sourcesContent":["const STYLE_ELEMENT_ID = 'typestyles';\n\n/**\n * Tracks which CSS rules have been inserted to avoid duplicates.\n */\nconst insertedRules = new Set<string>();\n\n/**\n * Whether runtime DOM insertion is disabled (for build-time/zero-runtime mode).\n * The Vite plugin (mode: 'build') defines __TYPESTYLES_RUNTIME_DISABLED__ as the\n * string \"true\" at build time, so this is true in production and no <style> is created.\n */\ndeclare const __TYPESTYLES_RUNTIME_DISABLED__: string | undefined;\nconst RUNTIME_DISABLED =\n typeof __TYPESTYLES_RUNTIME_DISABLED__ !== 'undefined' &&\n __TYPESTYLES_RUNTIME_DISABLED__ === 'true';\n\n/**\n * Buffer of CSS rules waiting to be flushed.\n */\nlet pendingRules: string[] = [];\n\n/**\n * All CSS rules ever registered (for SSR extraction).\n * Unlike pendingRules (which is cleared on flush), this retains every rule\n * so getRegisteredCss() can return the full stylesheet at any point.\n */\nconst allRules: string[] = [];\n\n/**\n * Whether a flush is scheduled.\n */\nlet flushScheduled = false;\n\n/**\n * The managed <style> element, lazily created.\n */\nlet styleElement: HTMLStyleElement | null = null;\n\n/**\n * When in SSR collection mode, CSS is captured here instead of injected.\n */\nlet ssrBuffer: string[] | null = null;\n\n/**\n * Whether we're running in a browser environment.\n */\nconst isBrowser =\n typeof document !== 'undefined' && typeof window !== 'undefined';\n\nfunction getStyleElement(): HTMLStyleElement {\n if (styleElement) return styleElement;\n\n // Check for an existing element (e.g., from SSR)\n const existing = document.getElementById(\n STYLE_ELEMENT_ID\n ) as HTMLStyleElement | null;\n if (existing) {\n styleElement = existing;\n return styleElement;\n }\n\n // Create a new one\n styleElement = document.createElement('style');\n styleElement.id = STYLE_ELEMENT_ID;\n document.head.appendChild(styleElement);\n return styleElement;\n}\n\nfunction flush(): void {\n flushScheduled = false;\n if (pendingRules.length === 0) return;\n\n const rules = pendingRules;\n pendingRules = [];\n\n if (ssrBuffer) {\n ssrBuffer.push(...rules);\n return;\n }\n\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n const el = getStyleElement();\n const sheet = el.sheet;\n\n if (sheet) {\n for (const rule of rules) {\n try {\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch {\n // Fallback: append as text (handles edge cases with certain selectors)\n el.appendChild(document.createTextNode(rule));\n }\n }\n } else {\n // Sheet not available yet, append as text\n el.appendChild(document.createTextNode(rules.join('\\n')));\n }\n}\n\nfunction scheduleFlush(): void {\n if (flushScheduled) return;\n flushScheduled = true;\n\n if (ssrBuffer) {\n // In SSR mode, flush synchronously\n flush();\n return;\n }\n\n if (isBrowser && !RUNTIME_DISABLED) {\n // Use microtask for fast, batched insertion\n queueMicrotask(flush);\n }\n}\n\n/**\n * Insert a CSS rule. Deduplicates by rule key.\n */\nexport function insertRule(key: string, css: string): void {\n if (insertedRules.has(key)) return;\n insertedRules.add(key);\n allRules.push(css);\n if (RUNTIME_DISABLED && !ssrBuffer) return;\n pendingRules.push(css);\n scheduleFlush();\n}\n\n/**\n * Insert multiple CSS rules at once.\n */\nexport function insertRules(rules: Array<{ key: string; css: string }>): void {\n let added = false;\n for (const { key, css } of rules) {\n if (insertedRules.has(key)) continue;\n insertedRules.add(key);\n allRules.push(css);\n if (!RUNTIME_DISABLED || ssrBuffer) {\n pendingRules.push(css);\n added = true;\n }\n }\n if (added) scheduleFlush();\n}\n\n/**\n * Replace a CSS rule (used for HMR). Removes the old rule and inserts the new one.\n */\nexport function replaceRule(key: string, css: string): void {\n if (!isBrowser || RUNTIME_DISABLED) return;\n\n insertedRules.delete(key);\n\n // Remove existing rule from the sheet if possible\n const el = getStyleElement();\n const sheet = el.sheet;\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n // We can't reliably match by key in CSSOM, so for HMR we fall back to\n // clearing and re-inserting. This is fine since HMR is dev-only.\n }\n }\n\n insertRule(key, css);\n}\n\n/**\n * Start collecting CSS for SSR. Returns a function to stop collection and get the CSS.\n */\nexport function startCollection(): () => string {\n ssrBuffer = [];\n return () => {\n const css = ssrBuffer ? ssrBuffer.join('\\n') : '';\n ssrBuffer = null;\n return css;\n };\n}\n\n/**\n * Return all registered CSS as a string.\n *\n * Unlike `collectStyles`, this doesn't require wrapping a render function.\n * It simply returns every CSS rule that has been registered via\n * `styles.create`, `tokens.create`, `keyframes.create`, etc.\n *\n * Ideal for SSR frameworks that need the CSS separately from the render\n * pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).\n *\n * @example\n * ```ts\n * import { getRegisteredCss } from 'typestyles/server';\n *\n * // In a route's head/meta function:\n * export const head = () => ({\n * styles: [{ id: 'typestyles', children: getRegisteredCss() }],\n * });\n * ```\n */\nexport function getRegisteredCss(): string {\n return allRules.join('\\n');\n}\n\n/**\n * Reset all state (useful for testing).\n */\nexport function reset(): void {\n insertedRules.clear();\n pendingRules = [];\n allRules.length = 0;\n flushScheduled = false;\n ssrBuffer = null;\n if (isBrowser && styleElement) {\n styleElement.remove();\n styleElement = null;\n }\n}\n\n/**\n * Flush all pending rules synchronously. Used for SSR and testing.\n */\nexport function flushSync(): void {\n flush();\n}\n\n/**\n * Invalidate all dedup keys that start with the given prefix.\n * Also removes matching rules from the live stylesheet.\n * Used for HMR — allows modules to re-register their styles after editing.\n */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n if (ruleMatchesPrefix(rule, prefix)) {\n sheet.deleteRule(i);\n }\n }\n}\n\n/**\n * Invalidate a list of exact keys or prefixes.\n * Each entry in `keys` is treated as an exact key match.\n * Each entry in `prefixes` is treated as a prefix match.\n * Used for HMR to invalidate all styles from a module at once.\n */\nexport function invalidateKeys(keys: string[], prefixes: string[]): void {\n for (const key of keys) {\n insertedRules.delete(key);\n }\n for (const prefix of prefixes) {\n for (const key of insertedRules) {\n if (key.startsWith(prefix)) {\n insertedRules.delete(key);\n }\n }\n }\n\n if (!isBrowser) return;\n\n const el = styleElement;\n if (!el) return;\n const sheet = el.sheet;\n if (!sheet) return;\n\n const keySet = new Set(keys);\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n const rule = sheet.cssRules[i];\n let shouldRemove = false;\n\n for (const prefix of prefixes) {\n if (ruleMatchesPrefix(rule, prefix)) {\n shouldRemove = true;\n break;\n }\n }\n\n if (!shouldRemove) {\n // Check exact key matches — for tokens/themes/keyframes,\n // we match based on rule content patterns\n const ruleText = rule.cssText;\n for (const key of keySet) {\n if (ruleMatchesKey(ruleText, key)) {\n shouldRemove = true;\n break;\n }\n }\n }\n\n if (shouldRemove) {\n sheet.deleteRule(i);\n }\n }\n}\n\nfunction ruleMatchesPrefix(rule: CSSRule, prefix: string): boolean {\n if (prefix.startsWith('font-face:')) {\n const family = prefix.slice('font-face:'.length).split(':')[0];\n // CSSFontFaceRule has type 5 and cssText contains @font-face\n if (rule.cssText.includes('@font-face')) {\n return (\n rule.cssText.includes(`\"${family}\"`) || rule.cssText.includes(`'${family}'`)\n );\n }\n return false;\n }\n if ('selectorText' in rule) {\n return (rule as CSSStyleRule).selectorText.startsWith(prefix);\n }\n if ('name' in rule && prefix.startsWith('keyframes:')) {\n return (rule as CSSKeyframesRule).name === prefix.slice('keyframes:'.length);\n }\n // For at-rules wrapping style rules, check inner rules\n if ('cssRules' in rule) {\n const innerRules = (rule as CSSGroupingRule).cssRules;\n for (let i = 0; i < innerRules.length; i++) {\n if (ruleMatchesPrefix(innerRules[i], prefix)) return true;\n }\n }\n return false;\n}\n\nfunction ruleMatchesKey(cssText: string, key: string): boolean {\n if (key.startsWith('tokens:')) {\n // tokens:color -> :root rule with --color- custom properties\n const namespace = key.slice('tokens:'.length);\n return cssText.includes(`:root`) && cssText.includes(`--${namespace}-`);\n }\n if (key.startsWith('theme:')) {\n // theme:dark -> .theme-dark selector\n const name = key.slice('theme:'.length);\n return cssText.includes(`.theme-${name}`);\n }\n if (key.startsWith('keyframes:')) {\n const name = key.slice('keyframes:'.length);\n return cssText.includes(`@keyframes ${name}`);\n }\n return false;\n}\n"]}
/**
* Insert multiple CSS rules at once.
*/
declare function insertRules(rules: Array<{
key: string;
css: string;
}>): void;
/**
* Return all registered CSS as a string.
*
* Unlike `collectStyles`, this doesn't require wrapping a render function.
* It simply returns every CSS rule that has been registered via
* `styles.create`, `tokens.create`, `keyframes.create`, etc.
*
* Ideal for SSR frameworks that need the CSS separately from the render
* pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).
*
* @example
* ```ts
* import { getRegisteredCss } from 'typestyles/server';
*
* // In a route's head/meta function:
* export const head = () => ({
* styles: [{ id: 'typestyles', children: getRegisteredCss() }],
* });
* ```
*/
declare function getRegisteredCss(): string;
/**
* Reset all state (useful for testing).
*/
declare function reset(): void;
/**
* Flush all pending rules synchronously. Used for SSR and testing.
*/
declare function flushSync(): void;
/**
* Invalidate all dedup keys that start with the given prefix.
* Also removes matching rules from the live stylesheet.
* Used for HMR — allows modules to re-register their styles after editing.
*/
declare function invalidatePrefix(prefix: string): void;
/**
* Invalidate a list of exact keys or prefixes.
* Each entry in `keys` is treated as an exact key match.
* Each entry in `prefixes` is treated as a prefix match.
* Used for HMR to invalidate all styles from a module at once.
*/
declare function invalidateKeys(keys: string[], prefixes: string[]): void;
export { invalidateKeys as a, invalidatePrefix as b, flushSync as f, getRegisteredCss as g, insertRules as i, reset as r };
/**
* Insert multiple CSS rules at once.
*/
declare function insertRules(rules: Array<{
key: string;
css: string;
}>): void;
/**
* Return all registered CSS as a string.
*
* Unlike `collectStyles`, this doesn't require wrapping a render function.
* It simply returns every CSS rule that has been registered via
* `styles.create`, `tokens.create`, `keyframes.create`, etc.
*
* Ideal for SSR frameworks that need the CSS separately from the render
* pass (e.g. TanStack Start's `head()`, Next.js metadata, Remix links).
*
* @example
* ```ts
* import { getRegisteredCss } from 'typestyles/server';
*
* // In a route's head/meta function:
* export const head = () => ({
* styles: [{ id: 'typestyles', children: getRegisteredCss() }],
* });
* ```
*/
declare function getRegisteredCss(): string;
/**
* Reset all state (useful for testing).
*/
declare function reset(): void;
/**
* Flush all pending rules synchronously. Used for SSR and testing.
*/
declare function flushSync(): void;
/**
* Invalidate all dedup keys that start with the given prefix.
* Also removes matching rules from the live stylesheet.
* Used for HMR — allows modules to re-register their styles after editing.
*/
declare function invalidatePrefix(prefix: string): void;
/**
* Invalidate a list of exact keys or prefixes.
* Each entry in `keys` is treated as an exact key match.
* Each entry in `prefixes` is treated as a prefix match.
* Used for HMR to invalidate all styles from a module at once.
*/
declare function invalidateKeys(keys: string[], prefixes: string[]): void;
export { invalidateKeys as a, invalidatePrefix as b, flushSync as f, getRegisteredCss as g, insertRules as i, reset as r };

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display