var()A token is its var() already, so var(--name) is not written. css.var(token, fallback?) is the call that adds a fallback: css.var(t.space.sm, "4px") is var(--space-sm, 4px). The result has the token's type, and the fallback is checked as a value of it (a string or a Typed OM value, in the types and at build time). Its first argument is a token, never a name.
import * as import csscss from "cssints" with { type: "cssints" };
const const t: css.Tokens<{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}, undefined, {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
t = import csscss.const createTokens: <{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>(tokens: {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
} & ValidGroup<{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}, undefined, {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>, name?: (path: readonly string[]) => string | TokenName) => css.Tokens<...>
Tokens from an inline DTCG-shaped `const` object: `$type` is inherited through groups, a leaf is `{ $value }`, a value is
a DTCG value or a CSS string of the type's grammar, an alias is `"{group.token}"`. The variable is the kebab-case path
(`--color-bg`), or what the mapper returns for the path.createTokens({
color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
} & ValidGroup<{
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
}, "color", {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
color: { $type: "color"$type: "color", accent: {
readonly $value: "red";
}
accent: { $value: "red"$value: "red" } },
space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
} & ValidGroup<{
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
}, "dimension", {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
space: { $type: "dimension"$type: "dimension", sm: {
readonly $value: "8px";
}
sm: { $value: "8px"$value: "8px" } },
});
export const const a: css.Stylea = import csscss.const padding: <readonly [css.CSSStyleValue<"length">]>(parts_0: css.CSSStyleValue<"length">) => css.Style`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)padding(import csscss.var<"length", "4px">(token: Token<"length", boolean, string>, fallback?: "4px" | css.CSSStyleValue<"length" | `${string}()`> | undefined): css.CSSStyleValue<"length">
export var
`var( <custom-property-name> , <declaration-value>? )`. Chrome 49, Edge 15, Firefox 31, Safari 9.1, iOS 9.3, Android 49. [MDN](https://developer.mozilla.org/docs/Web/CSS/var)var(const t: css.Tokens<{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}, undefined, {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
t.space: css.Tokens<{
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
}, "dimension", {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
space.sm: Token<"length", true, "8px">sm, "4px")); // padding: var(--space-sm, 4px)
export const const b: css.Styleb = import csscss.const color: <readonly [css.CSSStyleValue<"color">]>(parts_0: css.CSSStyleValue<"color">) => css.Style`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color(import csscss.var<"color", string>(token: Token<"color", boolean, string>, fallback?: `color: unexpected "${string}" in "${string}", grammar <color>` | css.CSSStyleValue<"color" | `${string}()`> | undefined): css.CSSStyleValue<"color">
export var
`var( <custom-property-name> , <declaration-value>? )`. Chrome 49, Edge 15, Firefox 31, Safari 9.1, iOS 9.3, Android 49. [MDN](https://developer.mozilla.org/docs/Web/CSS/var)var(const t: css.Tokens<{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}, undefined, {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
t.color: css.Tokens<{
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
}, "color", {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
color.accent: Token<"color", true, "red">accent, import csscss.const rgb: <readonly [0, 0, 0]>(parts_0: 0, parts_1: 0, parts_2: 0) => css.CSSStyleValue<"rgb()">`rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? ) | rgb( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? )`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color_value/rgb)rgb(0, 0, 0)));
export const const c: css.Stylec = import csscss.const padding: <readonly [css.CSSStyleValue<"length">]>(parts_0: css.CSSStyleValue<"length">) => css.Style`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)padding(import csscss.var<"length", "red">(token: Token<"length", boolean, string>, fallback?: css.CSSStyleValue<"length" | `${string}()`> | "length: unexpected \"red\" in \"red\", grammar <length>" | undefined): css.CSSStyleValue<"length">
export var
`var( <custom-property-name> , <declaration-value>? )`. Chrome 49, Edge 15, Firefox 31, Safari 9.1, iOS 9.3, Android 49. [MDN](https://developer.mozilla.org/docs/Web/CSS/var)var(const t: css.Tokens<{
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}, undefined, {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
t.space: css.Tokens<{
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
}, "dimension", {
readonly color: {
readonly $type: "color";
readonly accent: {
readonly $value: "red";
};
};
readonly space: {
readonly $type: "dimension";
readonly sm: {
readonly $value: "8px";
};
};
}>
space.sm: Token<"length", true, "8px">sm, "red")); // error: the fallback is a lengthexport const const d: css.Styled = import csscss.const color: <readonly [css.CSSStyleValue<"length">]>(parts_0: "color: unexpected \"⟨length⟩\" in \"⟨length⟩\", grammar <color>") => css.Style`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color(css.var(t.space.sm)); // error: a length is not a colourA string that writes var(--space-sm) is a build warning that names the token to pass; the var() of a custom property that is no token is left alone (see "Tokens"). --_x custom properties of a scope's kernels are not checked.
A plugin author makes a function of their own with a value member of a scope() ({ args, value }):
import { class CSSColorValueCSSColorValue } from "cssints";
import { function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
// `args` is the grammar of the parts, joined by a space: `value` gets each one as text, a token as its var(--name).
export const { const tint: <const P extends readonly Part[]>(...parts: CheckIn<"tint", "<color> <percentage>", false, P>) => CSSColorValuetint, const step: <const P extends readonly Part[]>(...parts: CheckIn<"step", "<number>", false, P>) => stringstep } = scope<"units", {
readonly tint: {
readonly args: "<color> <percentage>";
readonly value: ([color, share]: string[]) => CSSColorValue;
};
readonly step: {
readonly args: "<number>";
readonly value: ([n]: string[]) => string;
};
}>(name: "units", table: {
readonly tint: {
readonly args: "<color> <percentage>";
readonly value: ([color, share]: string[]) => CSSColorValue;
};
readonly step: {
readonly args: "<number>";
readonly value: ([n]: string[]) => string;
};
} & Valid<"units", {
readonly tint: {
readonly args: "<color> <percentage>";
readonly value: ([color, share]: string[]) => CSSColorValue;
};
readonly step: {
readonly args: "<number>";
readonly value: ([n]: string[]) => string;
};
}>): Scope<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("units", {
tint: {
readonly args: "<color> <percentage>";
readonly value: ([color, share]: string[]) => CSSColorValue;
}
tint: {
args: "<color> <percentage>"args: "<color> <percentage>",
value: ([color, share]: string[]) => CSSColorValuevalue: ([color: string | undefinedcolor, share: string | undefinedshare]) => new new CSSColorValue(value: string): CSSColorValueCSSColorValue(`color-mix(in oklab, ${color: string | undefinedcolor}, white ${share: string | undefinedshare})`),
},
step: {
readonly args: "<number>";
readonly value: ([n]: string[]) => string;
}
step: { args: "<number>"args: "<number>", value: ([n]: string[]) => stringvalue: ([n: string | undefinedn]) => `${var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.Number(n: string | undefinedn) * 4}px` },
}).Scope<"units", { readonly tint: { readonly args: "<color> <percentage>"; readonly value: ([color, share]: string[]) => CSSColorValue; }; readonly step: { readonly args: "<number>"; readonly value: ([n]: string[]) => string; }; }>.export(): Members<{
readonly tint: {
readonly args: "<color> <percentage>";
readonly value: ([color, share]: string[]) => CSSColorValue;
};
readonly step: {
readonly args: "<number>";
readonly value: ([n]: string[]) => string;
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();
const tint: <readonly ["red", "20%"]>(parts_0: "red", parts_1: "20%") => CSSColorValuetint("red", "20%");
const tint: <readonly ["red", "solid"]>(parts_0: "tint: unexpected \"red\" in \"red solid\", grammar <color> <percentage>", parts_1: "solid") => CSSColorValuetint("red", "solid"); // error: not a percentageconst step: <readonly [2]>(parts_0: 2) => stringstep(2);args takes what a call member's does: a grammar, arg<T>(), or a tuple of positional arguments with an object of named leaves at the end, checked by the same types and at build time by the same code. A table cannot type value from the args beside it, so a member with a tuple or arg<T>() is written fn({ args, value }) (from cssints/plugin), and value gets an array of the arguments as build would: grammar parts as checked text, arg<T>() as T, the object as an object ({} when left out). The types reject such a member written without fn(). A boolean option is arg<boolean>().label names the member in its errors in place of its key: a key is a name (no dots), so a member exported as fluid.container is a key of its own, attached by hand, with label: "fluid.container".import { const arg: <T>() => Typed<T>`arg<T>()`: one value of the TypeScript type `T`.arg, const fn: <const D extends ArgsDef, R extends string | CSSStyleValue, const L extends string = never>(def: {
args: D;
label?: L;
value: (args: Params<D>) => R;
}) => {
args: D;
label?: L;
value(args: never): R;
}
A value member whose `args` is a tuple or `arg<T>()`: `value` gets the arguments as a call member's `build` does. A
table cannot type `value` from the `args` beside it (as `build()` does for call members); this call can.fn, function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
export const { const shade: <const P extends readonly [unknown, unknown?]>(...args: P & CheckAll<"tint.shade", Own<{
readonly shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
};
}>, readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}], P>) => string
shade } = scope<"shades", {
readonly shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
};
}>(name: "shades", table: {
readonly shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
};
} & Valid<"shades", {
readonly shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
};
}>): Scope<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("shades", {
shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
}
shade: fn<readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}], `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`, "tint.shade">(def: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value: (args: [string, {} & {
by?: string | undefined;
dark?: boolean | undefined;
}]) => `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
}): {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
}
A value member whose `args` is a tuple or `arg<T>()`: `value` gets the arguments as a call member's `build` does. A
table cannot type `value` from the `args` beside it (as `build()` does for call members); this call can.fn({
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}]
args: ["<color>", { "by?": "<percentage>", "dark?": arg<boolean>(): Typed<boolean>`arg<T>()`: one value of the TypeScript type `T`.arg<boolean>() }],
label?: "tint.shade" | undefinedlabel: "tint.shade",
value: (args: [string, {} & {
by?: string | undefined;
dark?: boolean | undefined;
}]) => `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`
value: ([color: stringcolor, { by: stringby = "10%", dark: boolean | undefineddark }]) => `color-mix(in oklab, ${color: stringcolor}, ${dark: boolean | undefineddark ? "black" : "white"} ${by: stringby})`,
}),
}).Scope<"shades", { readonly shade: { args: readonly ["<color>", { readonly "by?": "<percentage>"; readonly "dark?": Typed<boolean>; }]; label?: "tint.shade" | undefined; value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`; }; }>.export(): Members<{
readonly shade: {
args: readonly ["<color>", {
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}];
label?: "tint.shade" | undefined;
value(args: never): `color-mix(in oklab, ${string}, black ${string})` | `color-mix(in oklab, ${string}, white ${string})`;
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();
const shade: <readonly ["red"]>(args_0: "red") => stringshade("red");
const shade: <readonly ["red", {
readonly by: "20%";
readonly dark: true;
}]>(...args: readonly ["red", {
readonly by: "20%";
readonly dark: true;
}] & readonly ["red", {
readonly by: "20%";
readonly dark: true;
} & Req<{
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}>]) => string
shade("red", { by: "20%"by: "20%", dark: truedark: true });
const shade: <readonly ["red", {
readonly by: "red";
}]>(...args: readonly ["red", {
readonly by: "red";
}] & readonly ["red", {
readonly by: Err<"tint.shade.by: unexpected \"red\" in \"red\", grammar <percentage>">;
} & Req<{
readonly "by?": "<percentage>";
readonly "dark?": Typed<boolean>;
}>]) => string
shade("red", { by: "red" }); // error: tint.shade(2).by: unexpected "red"value returns is what the call returns. A Typed OM value (CSSColorValue, CSS.rem(1)) keeps its type: tint(...) is a <color> in the types and goes only where a colour goes. A string, a literal or a template literal too (`color-mix(in oklab, ${c}, white)`), is opaque to the types, which accept it anywhere, and it is checked at build time in the declaration it lands in, as any value is. Return a Typed OM value when you know the type.cssints are CSS (CSS.px, rem, em, percent, number), CSSUnitValue, CSSColorValue and CSSImageValue (an <image>: a gradient, a url()), each holding its CSS text, and CSSStyleValue<T>, the base to subclass for another type (class Clamp extends CSSStyleValue<"length"> with a toString()). A module that only runs at build time, as a plugin's does, imports them from "cssints" without the attribute; a module that reaches the client imports them with it, and each constructor there becomes its CSS text.value runs in the Module Runner, once per call, and the call is replaced by its CSS text ("_1hjzi3b" for a class, "color-mix(...)" for a call of its own); the function and its module do not reach the client.MemberError values with the file, site and offset of the call, and pluginName is the scope: tint: unexpected "solid" in "red solid", expected <percentage> for the parts (the label is the member's label, else its key; a tuple's message names the position, tint.shade(2).by: ...); a value that throws (cssints: boom: no luck, any Error) or returns something else than a string or a Typed OM value (cssints: tint() value must return a string or a Typed OM value). A result that does not fit the property is that property's error, at the same site (width: unexpected "color-mix(in" in "color-mix(in oklab, red, blue)"): the engine cannot know the property a function is used for.args, the parts are joined with a space, so it cannot tell the arguments apart (<color> <color> takes "red", "blue" and "red blue"; check parts.length in value, or use a tuple). A token is checked as the values of its type, so a wrong one is named by its value: unexpected "1px" in "oklab 1px red". The css functions above are not value members: lightDark(a, b) is the text light-dark(a, b), whose choice is the browser's at the element.