Socket
Socket
Sign inDemoInstall

twind

Package Overview
Dependencies
Maintainers
2
Versions
159
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

twind - npm Package Compare versions

Comparing version 0.0.0-experimental-1 to 0.0.0-next-20221114103805

CHANGELOG.md

106

package.json
{
"name": "twind",
"version": "0.0.0-experimental-1",
"description": "compiles tailwind like shorthand syntax into css at runtime",
"version": "0.0.0-next-20221114103805",
"description": "The core engine without any presets.",
"type": "module",
"homepage": "https://twind.style",
"bugs": {
"url": "https://github.com/tw-in-js/twind/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tw-in-js/twind.git",
"directory": "packages/twind"
},
"keywords": [
"twind",
"tw-in-js",
"tailwind",
"tw-in-js",
"tailwindcss",
"tailwind-in-js"
],
"homepage": "https://github.com/tw-in-js/twind#readme",
"bugs": "https://github.com/tw-in-js/twind/issues",
"repository": "github:tw-in-js/twind",
"license": "MIT",
"contributors": [
"Luke Jackson (lukejacksonn.github.io)",
"Sascha Tandel (https://github.com/sastan)"
"author": {
"name": "Sascha Tandel",
"url": "https://github.com/sastan"
},
"funding": [
{
"type": "Open Collective",
"url": "https://opencollective.com/twind"
},
{
"type": "Github Sponsor",
"url": "https://github.com/sponsors/tw-in-js"
}
],
"engines": {
"node": ">=14.15.0"
},
"main": "./twind.cjs",
"exports": {
".": {
"node": "./twind.cjs",
"script": "./twind.umd.js",
"types": "./twind.d.ts",
"development": {
"esnext": "./twind.esnext.dev.js",
"module": "./twind.dev.js",
"browser": "./twind.browser.dev.js",
"script": "./twind.global.dev.js",
"node": {
"import": "./twind.dev.mjs",
"require": "./twind.dev.cjs"
},
"default": "./twind.dev.js"
},
"esnext": "./twind.esnext.js",
"module": "./twind.js",
"browser": "./twind.browser.js",
"script": "./twind.global.js",
"node": {
"import": "./twind.mjs",
"require": "./twind.cjs"
},
"default": "./twind.js"
},
"./shim": {
"node": "./shim/shim.cjs",
"script": "./shim/shim.umd.js",
"types": "./shim/shim.d.ts",
"default": "./shim/shim.js"
},
"./shim/auto": {
"node": "./shim/auto/auto.cjs",
"script": "./shim/auto/auto.umd.js",
"types": "./shim/auto/auto.d.ts",
"default": "./shim/auto/auto.js"
},
"./package.json": "./package.json",
"./*": "./*",
"./": "./"
"./package.json": "./package.json"
},
"sideEffects": [
"./dist/shim/auto/auto.js"
],
"sideEffects": false,
"dependencies": {
"csstype": "^3.0.5",
"tiny-css-prefixer": "^1.1.4"
"csstype": "^3.1.1",
"@swc/helpers": "^0.4.11"
},
"peerDependencies": {
"typescript": "^4.8.4"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.com/"
"access": "public"
},
"engines": {
"node": ">=10.13"
},
"module": "./twind.js",
"unpkg": "./twind.umd.js",
"esnext": "./twind.esnext.js",
"unpkg": "./twind.global.js",
"jsdelivr": "./twind.global.js",
"browser": "./twind.browser.js",
"types": "./twind.d.ts"
}
}

@@ -1,90 +0,31 @@

# twind
# twind [![MIT License](https://flat.badgen.net/github/license/tw-in-js/twind)](https://github.com/tw-in-js/twind/blob/next/LICENSE) [![Latest Release](https://flat.badgen.net/npm/v/twind/next?icon=npm&label&cache=10800&color=blue)](https://www.npmjs.com/package/twind/v/next) [![Github](https://flat.badgen.net/badge/icon/tw-in-js%2Ftwind%23twind?icon=github&label)](https://github.com/tw-in-js/twind/tree/next/packages/twind)
> the smallest, fastest, most feature complete Tailwind-in-JS solution ever
Utility-first CSS without any build step right in the browser or any other environment like Node.js, deno, workers, ...
[![MIT License](https://badgen.net/github/license/tw-in-js/twind)](https://github.com/tw-in-js/twind/blob/main/LICENSE)
[![Latest Release](https://flat.badgen.net/npm/v/twind?icon=npm&label)](https://www.npmjs.com/package/twind)
[![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/twind?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=twind 'gzip bundle size (including dependencies)')
[![Package Size](https://flat.badgen.net/badgesize/brotli/https:/unpkg.com/twind/module/twind.js?icon=jsdelivr&label&color=blue)](https://unpkg.com/twind/module/twind.js 'brotli package size (without dependencies)')
[![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/twind/types/index.d.ts)
[![Github](https://flat.badgen.net/badge/icon/tw-in-js%2Ftwind?icon=github&label)](https://github.com/tw-in-js/twind)
[![CI](https://github.com/tw-in-js/twind/workflows/CI/badge.svg)](https://github.com/tw-in-js/twind/actions?query=workflow%3Aci)
[![Coverage Status](https://flat.badgen.net/coveralls/c/github/tw-in-js/twind/main?icon=codecov&label)](https://coveralls.io/github/tw-in-js/twind?branch=main)
[![PRs Welcome](https://flat.badgen.net/badge/PRs/welcome/purple)](http://makeapullrequest.com)
- 📖 Study [the documentation](https://twind.style)
- 🤖 Try [the playground](https://twind.run)
- 🧭 Explore [the examples](https://twind.style/examples)
- 📓 Consult [the API reference](https://twind.style/packages/twind)
- 📜 Read [the changelog](https://github.com/tw-in-js/twind/tree/next/packages/twind/CHANGELOG.md)
---
## 📖 Documentation
If you are here then the likelihood is that you have heard of and are interested in, or have used both Tailwind and CSS-in-JS libraries such as styled components, emotion or goober before. These packages have revolutionized web development and for one reason or another, have proved overwhelmingly popular with the community.
The full documentation is available at [twind.style](https://twind.style).
The purpose of this project is to create and maintain the smallest, fastest, most feature complete Tailwind-in-JS solution in the world. Exercising the flexibility of CSS-in-JS within the constraints of the Tailwind API.
## 💬 Community
We aim to create a place for likeminded people to discuss issues and share implementations around this idea.
For help, discussion about best practices, or any other conversation that would benefit from being searchable use [Github Discussions](https://github.com/tw-in-js/twind/discussions).
## Quickstart
To ask questions and discuss with other Twind users in real time use [Discord Chat](https://chat.twind.style).
If you would like to get started with twind right away then copy paste this code into your favorite sandbox.
## 🧱 Contribute
> ⚡️ Alternatively try the [live and interactive demo](https://esm.codes/#aW1wb3J0IHsgdHcsIHNldHVwIH0gZnJvbSAnaHR0cHM6Ly9jZG4uc2t5cGFjay5kZXYvdHdpbmQnCgpkb2N1bWVudC5ib2R5LmlubmVySFRNTCA9IGAKICA8bWFpbiBjbGFzcz0iJHt0d2BiZy1ibGFjayB0ZXh0LXdoaXRlYH0iPgogICAgPGgxIGNsYXNzPSIke3R3YHRleHQteGxgfSI+VGhpcyBpcyBUYWlsd2luZCBpbiBKUyE8L2gxPgogIDwvbWFpbj4KYA==)
See the [Contributing Guide](../../CONTRIBUTING.md) for information on how to contribute to this project.
```js
import { tw, setup } from 'https://cdn.skypack.dev/twind'
## 📜 Changelog
document.body.innerHTML = `
<main class="${tw`bg-black text-white`}">
<h1 class="${tw`text-xl`}">This is Tailwind in JS!</h1>
</main>
`
```
The Changelog for this package is [available on GitHub](https://github.com/tw-in-js/twind/tree/next/packages/twind/CHANGELOG.md).
For further instruction on usage please [read the documentation](docs)!
## ⚖️ License
## Rational
This project was started by the authors of two similar libraries – [oceanwind](https://github.com/lukejacksonn/oceanwind) and [beamwind](https://github.com/kenoxa/beamwind) – who chose to collaborate rather than compete with each other in this space. The open source community is full of fragmentation but we wanted to see cohesion here. We hope that combining efforts helps us coin standards for certain aspects of the implementation; things like input parsing, [grouping syntax](./docs/grouping.md) and prescedence calculation.
## Challenges
The core problems we are trying to solve here are as follows:
1. Parsing Input: taking input and normalizing it to create a comprehendable set of Tailwind rules
2. Merging Themes: combining JSON themes which configure and constrain the compiler
3. Compiling Rules: taking a set of Tailwind rules and translating them into appropriate CSS rules
4. Injecting Styles: taking CSS rules and generating classes that get append to a stylesheet in the DOM
5. Custom Plugins: taking functions and using them to extend the capabilities of the compiler
This has to happen in a performant way at runtime, whilst adhering to Tailwind V2 as a language specification. All grammars that exist in Tailwind should be covered by this implementation.
## Opportunities
Simply recreating a tailwind like experience at runtime might seem like a futile exercise but we'd like to believe it opens up the doors to some exciting new possibilities. There is always going to be a tradeoff between compiling at ahead of time and compiling _just in time_, however we are confident the upsides here are significant enough to persue a runtime implementation and the results have been promising so far.
> Note it is still possible to remove all runtime overhead via a prepass either at serve or built time
The flexible nature of a runtime first approach affords us possibilities like:
- Dynamic Theming: generating new themes on the fly without the need to recompile anything
- Unlimited Variants: enabling every variant combination by default because unused rules are never generated
- Enhanced Syntax: taking advantage of macros within template literals to create more terse rules
- Error Handling: warning the developer about duplicate and missing variants or directives
- Hashing Classes: reducing the overall output size and eliminating conflicts via deterministic hashing
- Inline Plugins: extending the capabilities of the compiler with simple functions at runtime
Another big advantage we see of shipping the interpreter compiler itself (rather than pre-compiled output) is that the effective size of the CSS for your whole app is deterministic and fixed. The weight of the compiler itself along with your theme file is all that users will ever download, no matter how many styles you use.
Currently the compiler weighs around 10KB which is smaller than styled-components and the average tailwind output.
## Inspiration
It goes without saying that the primary inspiration here comes from Tailwind. It is a revolutionary take on styling the web which has proven popular by designers and developers alike. All the core plugins here, abide by the rules painstakingly thought out, implemented and popularized by Adam Wathan et al. making us forever in his debt.
> I've wanted to do a CSS-in-JS flavor of Tailwind for over 2 years because of all the neat benefits you get there so it's cool to see projects like this! – [@adamwathan](https://twitter.com/adamwathan/status/1320370489408225282)
We hope one day we will get the chance to collaborate together on an official implementation!
Another big motivator was seeing [htm](https://www.npmjs.com/package/htm) by Jason Miller at Google, compiling JSX at runtime with performance characteristics that were comparable to code that was transpile ahead of time with babel.
We'd like to call ourselves the htm of the css world but that awards goes to [goober](https://www.npmjs.com/package/goober) which is an inspiringly small and efficient CSS-in-JS library by Cristian Bote a member of the core preact team.
## License
[MIT](https://github.com/tw-in-js/twind/blob/main/LICENSE)
The [MIT license](https://github.com/tw-in-js/twind/blob/main/LICENSE) governs your use of Twind.

@@ -1,299 +0,1087 @@

import { SimplePseudos, PropertiesFallback, PropertiesHyphenFallback } from 'csstype';
import * as CSS$1 from 'csstype';
declare type Falsy = '' | 0 | -0 | false | null | undefined;
/**
* Pseudo class
* watch out for ':root' - that could use '*' instead
*/
declare type CSSSimplePseudos = {
[K in SimplePseudos as `&${string & K}`]?: CSSRules;
declare type Falsey = false | null | undefined | void | '';
declare type MaybeArray<T> = T | T[];
declare type MaybeThunk<T, Theme extends BaseTheme = BaseTheme> = T | ((context: Context<Theme>) => T);
declare type TypedAtRulesKeys = `@layer ${'defaults' | 'base' | 'components' | 'shortcuts' | 'utilities' | 'overrides'}` | `@media screen(${string})` | `@media ${string}` | `@keyframes ${string}`;
declare type TypedAtRules = {
[key in TypedAtRulesKeys]?: key extends `@layer ${string}` ? MaybeArray<CSSBase> : CSSBase;
};
interface CSSPseudos extends CSSSimplePseudos {
'&:nth-child(2n)'?: CSSRules;
'&:nth-child(odd)'?: CSSRules;
interface BaseProperties extends TypedAtRules {
'@import'?: MaybeArray<string | Falsey>;
'@font-face'?: MaybeArray<CSSFontFace>;
}
interface CSSCustomProperties {
'--tw-rotate'?: string;
'--tw-gradient-stops'?: string;
interface CustomProperties {
label?: string;
'@apply'?: MaybeArray<string> | Falsey;
}
interface CSSProperties extends PropertiesFallback<string, string>, PropertiesHyphenFallback<string, string>, CSSCustomProperties {
declare type CSSProperties = CSS$1.PropertiesFallback<string | Falsey, string | Falsey> & CSS$1.PropertiesHyphenFallback<string | Falsey, string | Falsey> & Partial<CustomProperties>;
declare type CSSFontFace = CSS$1.AtRule.FontFaceFallback & CSS$1.AtRule.FontFaceHyphenFallback;
interface CSSNested extends Record<string, CSSProperties | MaybeArray<CSSObject | string> | Falsey> {
}
declare type CSSAtKeyframes = Record<string, CSSProperties>;
declare type CSSAtMedia = Record<string, CSSRules>;
declare type CSSAtSupports = Record<string, CSSRules>;
declare type CSSBase = BaseProperties & CSSNested;
declare type CSSObject = CSSProperties & CSSBase;
declare type CSSValue = string | number | bigint | Falsey | StringLike;
declare type StringLike = {
toString(): string;
} & string;
declare type Preflight = CSSBase | string;
interface TwindRule {
/** The calculated precedence taking all variants into account. */
p: number;
o: number;
/** Additional classNames to propagate, does not include name */
c?: string;
/** The rulesets (selectors and at-rules). expanded variants `@media ...`, `@supports ...`, `&:focus`, `.dark &` */
r: string[];
/** The name to use for `&` expansion in selectors. Maybe empty for at-rules like `@import`, `@font-face`, `@media`, ... */
n?: string;
/** The stringified declarations. */
d?: string;
}
declare type RestoreSnapshot = () => void;
interface Twind<Theme extends BaseTheme = BaseTheme, Target = unknown> {
(tokens: StringLike): string;
readonly target: Target;
readonly theme: ThemeFunction<ExtractUserTheme<Theme>>;
readonly config: TwindConfig<Theme>;
snapshot(): RestoreSnapshot;
/** Clears all CSS rules from the sheet. */
clear(): void;
destroy(): void;
}
interface Context<Theme extends BaseTheme = BaseTheme> {
/** Allows to resolve theme values. */
theme: ThemeFunction<Theme>;
/** escapes given string for use in a CSS selector or variable */
e: (value: string) => string;
/** create hash of given string — may be no-op eg returning the same input */
h: (value: string) => string;
/**
* returns the dark color
*
* @private
*/
d(section: string, key: string, color: ColorValue): ColorValue | Falsey;
/**
* resolves a variant
*
* @private
*/
v: (value: string) => MaybeArray<string>;
/**
* resolves a rule
*
* @private
*/
r: (value: string, isDark?: boolean) => RuleResult;
/**
* stringifies a CSS property and value to a declaration
*
* @private
*/
s: (property: string, value: string) => string;
}
declare type ThemeValue<T> = T extends Record<string, infer V> ? Exclude<V, Record<string, V>> : T;
declare type KebabCase<S> = S extends `${infer C}${infer T}` ? KebabCase<T> extends infer U ? U extends string ? T extends Uncapitalize<T> ? `${Uncapitalize<C>}${U}` : `${Uncapitalize<C>}-${U}` : never : never : S;
interface ThemeFunction<Theme extends BaseTheme = BaseTheme> {
(): Theme;
<Section extends keyof Theme & string>(section: Section | KebabCase<Section>): Theme[Section];
<Section extends keyof Theme & string, Key extends keyof Theme[Section]>(section: Section | KebabCase<Section>, key: Key): ThemeValue<Theme[Section]> | undefined;
<Section extends keyof Theme & string>(section: Section | KebabCase<Section>, key: string): ThemeValue<Theme[Section]> | undefined;
<Section extends keyof Theme & string, Key extends keyof Theme[Section]>(section: Section | KebabCase<Section>, key: Key, defaultValue: ThemeValue<Theme[Section]>): ThemeValue<Theme[Section]>;
<Section extends keyof Theme & string>(section: Section | KebabCase<Section>, key: string, defaultValue: ThemeValue<Theme[Section]>): ThemeValue<Theme[Section]>;
<Section extends keyof Theme & string>(key: `${Section}.${string}`): ThemeValue<Theme[Section]>;
<Section extends keyof Theme & string>(key: `${Section}.${string}`, defaultValue: ThemeValue<Theme[Section]>): ThemeValue<Theme[Section]>;
(section: string): unknown | undefined;
(section: string, key: string): unknown | string | undefined;
<T>(section: string, key: string, defaultValue: T): T | string;
<T>(key: string, defaultValue: T): T | string;
}
declare type RuleResult = string | CSSObject | Falsey | Partial<TwindRule>[];
declare type RuleResolver<Theme extends BaseTheme = BaseTheme, Match extends MatchResult = MatchResult> = (match: Match, context: Context<Theme>) => RuleResult;
declare type Rule<Theme extends BaseTheme = BaseTheme> = string | RegExp | [pattern: MaybeArray<string | RegExp>, alias: string & {}] | [pattern: MaybeArray<string | RegExp>, css: CSSObject] | [pattern: MaybeArray<string | RegExp>, resolve: RuleResolver<Theme>] | [pattern: MaybeArray<string | RegExp>, property: keyof CSSProperties] | [
pattern: MaybeArray<string | RegExp>,
property: keyof CSSProperties,
convert: MatchConverter<Theme>
];
declare type VariantResult = MaybeArray<string> | Falsey;
declare type VariantResolver<Theme extends BaseTheme = BaseTheme> = (match: MatchResult, context: Context<Theme>) => VariantResult;
declare type Variant<Theme extends BaseTheme = BaseTheme> = [
condition: MaybeArray<string | RegExp>,
resolve: string | VariantResolver<Theme>
];
declare type MatchResult = RegExpExecArray & {
/** The substring following the most recent match */
$$: string;
/** Can be used to propagate a value like a theme value */
dark?: boolean;
};
interface SheetRule {
/** The calculated precedence taking all variants into account. */
p: number;
o: number;
/** The name to use for `&` expansion in selectors. Maybe empty for at-rules like `@import`, `@font-face`, `@media`, ... */
n?: string | null;
}
interface Sheet<Target = unknown> {
readonly target: Target;
insert(cssText: string, index: number, rule: SheetRule): void;
snapshot(): RestoreSnapshot;
/** Clears all CSS rules from the sheet. */
clear(): void;
destroy(): void;
resume(addClassName: (className: string) => void, insert: (cssText: string, rule: SheetRule) => void): void;
}
declare type StringifyDeclaration<Theme extends BaseTheme = BaseTheme> = (property: string, value: string, context: Context<Theme>) => string;
declare type PreflightThunk<Theme extends BaseTheme = BaseTheme> = (context: Context<Theme>) => Preflight | Falsey;
declare type HashFunction = (value: string, defaultHash: (value: string) => string) => string;
declare type DarkModeConfig = 'media' | 'class' | (string & {}) | boolean | undefined | [mode: 'class', selector: string];
/**
* See: https://drafts.csswg.org/css-nesting/#nest-selector
* Allows to return a dark color for the given light color.
*
* ```js
* {
* // 50 -> 900, 100 -> 800, ..., 800 -> 100, 900 -> 50
* darkColor: autoDarkColor
* // custom resolvers
* darkColor: (section, key, { theme }) => theme(`${section}.${key}-dark`) as ColorValue
* darkColor: (section, key, { theme }) => theme(`dark.${section}.${key}`) as ColorValue
* darkColor: (section, key, { theme }) => theme(`${section}.dark.${key}`) as ColorValue
* darkColor: (section, key, context, lightColor) => generateDarkColor(lightColor),
* }
* ```
* "& > * + *": {
* marginLeft: 16
* },
*
* // In a comma-separated list, each individual selector shall start with "&"
* "&:focus, &:active": {
* outline: "solid"
* },
* Or use the light color to generate a dark color
*
* // Self-references are also supported
* "& + &": {
* color: "green"
* ```js
* {
* darkColor: (section, key, context, color) => generateDark(color)
* }
* ```
* @param section the theme section
* @param key the theme key within section — maybe an arbitrary value `[...]`
* @param context the context
* @param color the current color
* @returns the dark color to use
*/
interface CSSRules {
/** Global defaults */
[key: string]: CSSProperties | CSSAtMedia | CSSAtSupports | CSSAtKeyframes | CSSRules | string | string[] | Falsy;
declare type DarkColor<Theme extends BaseTheme> = (section: string, key: string, context: Context<Theme>, color: ColorValue) => ColorValue | Falsey;
interface TwindConfig<Theme extends BaseTheme = BaseTheme> {
/** Allows to change how the `dark` variant is used (default: `"media"`) */
darkMode?: DarkModeConfig;
darkColor?: DarkColor<Theme>;
theme: ThemeConfig<Theme>;
preflight: false | MaybeThunk<Preflight | Falsey, Theme>[];
variants: Variant<Theme>[];
rules: Rule<Theme>[];
hash?: boolean | undefined | HashFunction;
stringify: StringifyDeclaration<Theme>;
ignorelist: (string | RegExp)[];
}
interface ThemeResolver {
<Section extends keyof Theme>(section: Section): Record<string, ThemeSectionType<Theme[Section]>>;
<Section extends keyof Theme>(section: Section, key: string | string[]): ThemeSectionType<Theme[Section]> | undefined;
<Section extends keyof Theme>(section: Section, key: string | string[], defaultValue: NonNullable<ThemeSectionType<Theme[Section]>>): NonNullable<ThemeSectionType<Theme[Section]>>;
declare type ArrayType<T> = T extends (infer Item)[] ? Item : T;
declare type ExtractTheme<T> = T extends Preset<infer Theme> ? Theme : T;
declare type ExtractUserTheme<T> = {
[key in keyof T]: key extends 'extend' ? never : T[key] extends ThemeSectionResolver<infer Value, T & BaseTheme> ? Value : T[key];
} & BaseTheme;
/** @experimental */
declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
declare type ExtractThemes<Theme, Presets extends Preset<any>[]> = UnionToIntersection<ExtractTheme<ExtractUserTheme<Theme> | BaseTheme | ArrayType<Presets>>>;
interface TwindPresetConfig<Theme = BaseTheme> {
/** Allows to change how the `dark` variant is used (default: `"media"`) */
darkMode?: DarkModeConfig;
darkColor?: DarkColor<Theme & BaseTheme>;
theme?: ThemeConfig<Theme & BaseTheme>;
preflight?: false | MaybeArray<Preflight | PreflightThunk<Theme & BaseTheme>>;
variants?: Variant<Theme & BaseTheme>[];
rules?: Rule<Theme & BaseTheme>[];
hash?: boolean | undefined | HashFunction;
stringify?: StringifyDeclaration<Theme & BaseTheme>;
ignorelist?: MaybeArray<string | RegExp>;
}
declare type Unwrap<T> = T extends string[] ? string : T extends Record<string, infer R> ? R : T;
declare type ThemeSectionType<T> = T extends ThemeSection<infer R> ? Unwrap<R> : Exclude<T, ThemeSectionResolver<T>>;
interface ThemeSectionResolverContext {
interface TwindUserConfig<Theme = BaseTheme, Presets extends Preset<any>[] = Preset[]> {
presets?: Presets;
/** Allows to change how the `dark` variant is used (default: `"media"`) */
darkMode?: DarkModeConfig;
darkColor?: DarkColor<BaseTheme & ExtractThemes<Theme, Presets>>;
theme?: Theme | ThemeConfig<BaseTheme & ExtractThemes<Theme, Presets>>;
preflight?: false | MaybeArray<Preflight | PreflightThunk<BaseTheme & ExtractThemes<Theme, Presets>>>;
variants?: Variant<BaseTheme & ExtractThemes<Theme, Presets>>[];
rules?: Rule<BaseTheme & ExtractThemes<Theme, Presets>>[];
/**
* No-op function as negated values are automatically infered and do _not_ not to be in the theme.
* Enables hashing of all classes (default: `false`).
*
* If a function is given it can be used to hash only certain classes:
*
* ```js
* {
* hash(className, defaultHash) {
* if (/^[~@]\(/.test(className)) {
* // a shortcut like `~(...)` or apply like `@(...)`
* return defaultHash(className)
* }
* return className
* }
* }
*```
*/
readonly negative: (records: Record<string, string | undefined>) => Record<string, string | undefined>;
readonly breakpoints: (records: Record<string, string | undefined>) => Record<string, string | undefined>;
hash?: boolean | undefined | HashFunction;
stringify?: StringifyDeclaration<BaseTheme & ExtractThemes<Theme, Presets>>;
ignorelist?: MaybeArray<string | RegExp>;
}
declare type ThemeSectionRecord<T = string> = Record<string, T | undefined>;
declare type ThemeSectionResolver<T = string> = (theme: <T>(keypath: string, defaultValue?: T) => T, context: ThemeSectionResolverContext) => ThemeSectionRecord<T>;
declare type ThemeSection<T = string> = ThemeSectionRecord<T> | ThemeSectionResolver<T>;
interface ThemeContainer {
screens?: Record<string, string | undefined>;
center?: boolean;
padding?: string | Record<string, string | undefined>;
interface BaseTheme {
screens: Record<string, MaybeArray<ScreenValue>>;
colors: Record<string, MaybeColorValue>;
}
declare type ThemeColor = string | Record<string, string>;
declare type ThemeFontSize = string | [size: string, lineHeight: string] | [size: string, options: {
lineHeight?: string;
letterSpacing?: string;
}];
declare type ThemeOutline = [outline: string, offset: string];
interface Theme {
colors: ThemeSection<ThemeColor>;
spacing: ThemeSection;
durations: ThemeSection<string | string[]>;
screens: ThemeSection;
animation: ThemeSection<string | string[]>;
backgroundColor: ThemeSection<ThemeColor>;
backgroundImage: ThemeSection<string | string[]>;
backgroundOpacity: ThemeSection;
borderColor: ThemeSection<ThemeColor>;
borderOpacity: ThemeSection;
borderRadius: ThemeSection;
borderWidth: ThemeSection;
boxShadow: ThemeSection<string | string[]>;
container: ThemeContainer | ThemeSectionResolver<ThemeContainer>;
divideColor: ThemeSection<ThemeColor>;
divideOpacity: ThemeSection;
divideWidth: ThemeSection;
fill: ThemeSection<ThemeColor>;
flex: ThemeSection;
fontFamily: ThemeSection<string | string[]>;
fontSize: ThemeSection<ThemeFontSize>;
fontWeight: ThemeSection;
gap: ThemeSection;
gradientColorStops: ThemeSection<ThemeColor>;
height: ThemeSection;
inset: ThemeSection;
keyframes: ThemeSection<CSSAtKeyframes>;
letterSpacing: ThemeSection;
lineHeight: ThemeSection;
margin: ThemeSection;
maxHeight: ThemeSection;
maxWidth: ThemeSection;
minHeight: ThemeSection;
minWidth: ThemeSection;
opacity: ThemeSection;
order: ThemeSection;
outline: ThemeSection<ThemeOutline>;
padding: ThemeSection;
placeholderColor: ThemeSection<ThemeColor>;
placeholderOpacity: ThemeSection;
ringColor: ThemeSection<ThemeColor>;
ringOffsetColor: ThemeSection<ThemeColor>;
ringOffsetWidth: ThemeSection;
ringOpacity: ThemeSection;
ringWidth: ThemeSection;
rotate: ThemeSection;
scale: ThemeSection;
skew: ThemeSection;
space: ThemeSection;
stroke: ThemeSection<ThemeColor>;
strokeWidth: ThemeSection;
textColor: ThemeSection<ThemeColor>;
textOpacity: ThemeSection;
transitionDelay: ThemeSection<string | string[]>;
transitionDuration: ThemeSection<string | string[]>;
transitionProperty: ThemeSection<string | string[]>;
transitionTimingFunction: ThemeSection<string | string[]>;
translate: ThemeSection;
width: ThemeSection;
zIndex: ThemeSection;
declare type ScreenValue = string | {
raw: string;
} | {
min: string;
max?: string;
} | {
min?: string;
max: string;
};
interface ColorFunctionOptions {
opacityVariable?: string | undefined;
opacityValue?: string | undefined;
}
declare type ColorFunction = (options: ColorFunctionOptions) => string;
interface ColorRecord extends Record<string, MaybeColorValue> {
}
declare type ColorValue = string | ColorFunction;
declare type MaybeColorValue = ColorValue | ColorRecord;
interface ThemeSectionResolverContext<Theme extends BaseTheme = BaseTheme> {
readonly colors: Theme['colors'];
readonly theme: ThemeFunction<Theme>;
/**
* No-op function as negated values are automatically infered and do _not_ need to be in the theme.
*/
readonly negative: (scale: Record<string, string>) => Record<string, string>;
readonly breakpoints: (screens: Record<string, MaybeArray<ScreenValue>>) => Record<string, string>;
}
interface ThemeSectionResolver<Value, Theme extends BaseTheme = BaseTheme> {
(context: ThemeSectionResolverContext<Theme>): Value;
}
declare type ThemeSection<Value, Theme extends BaseTheme = BaseTheme> = Value | ThemeSectionResolver<Value, Theme>;
declare type PartialTheme<Theme extends BaseTheme = BaseTheme> = {
[Section in keyof Theme]?: ThemeSection<Theme[Section], Theme>;
};
declare type ThemeConfig<Theme extends BaseTheme = BaseTheme> = PartialTheme<Theme> & {
extend?: PartialTheme<Theme>;
};
declare type MatchConverter<Theme extends BaseTheme = BaseTheme, Match extends MatchResult = MatchResult> = (match: Match, context: Context<Theme>) => string;
interface PresetThunk<Theme = BaseTheme> {
(config: TwindConfig<Theme & BaseTheme>): TwindPresetConfig<Theme>;
}
declare type Preset<Theme = BaseTheme> = TwindPresetConfig<Theme> | PresetThunk<Theme>;
interface ClassObject {
[key: string]: boolean | number | unknown;
}
declare type Class = string | number | boolean | Falsey | ClassObject | Class[];
declare type NestedFunction = (strings: TemplateStringsArray | Class, ...interpolations: Class[]) => string;
declare type Nested = NestedFunction & {
[label: string]: NestedFunction;
};
interface TW {
(strings: TemplateStringsArray, ...interpolations: Token[]): string;
(...tokens: Token[]): string;
/**
* @group Class Name Generators
*/
declare const apply: Nested;
/**
* @group Class Name Generators
*/
declare const shortcut: Nested;
interface AnimationFunction {
(animation: string | CSSProperties, waypoints: StringLike): StringLike;
}
interface Context {
/** Allow composition */
readonly tw: TW;
/** Access to theme values */
readonly theme: ThemeResolver;
/** Create unique identifier (group, custom properties) */
readonly tag: (key: string) => string;
declare type Animation = AnimationFunction & {
[label: string]: AnimationFunction;
};
/**
* @group Class Name Generators
*/
declare const animation: Animation;
declare type AutocompleteItem = {
prefix?: string;
suffix: string;
theme?: {
section: string;
key: string;
};
modifiers?: AutocompleteModifier[] | false | null | undefined;
color?: string | false | null | undefined;
label?: string;
};
declare type AutocompleteModifier = {
modifier: string;
theme?: {
section: string;
key: string;
};
color?: string | false | null | undefined;
label?: string;
};
interface AutocompleteContext<Theme extends BaseTheme = BaseTheme> {
/** Allows to resolve theme values. */
readonly theme: ThemeFunction<Theme>;
readonly variants: Record<string, string>;
}
interface Instance {
readonly tw: TW;
readonly setup: (options?: Configuration) => void;
declare type AutocompleteProvider<Theme extends BaseTheme = BaseTheme> = (match: MatchResult, context: AutocompleteContext<Theme>) => (string | AutocompleteItem)[];
/**
* @experimental
* @group Configuration
* @param resolver
* @param autocomplete
*/
declare function withAutocomplete<Theme extends BaseTheme = BaseTheme>(resolver: RuleResolver<Theme>, autocomplete: AutocompleteProvider<Theme> | false | null | undefined): RuleResolver<Theme>;
declare function withAutocomplete<Theme extends BaseTheme = BaseTheme>(resolver: VariantResolver<Theme>, autocomplete: AutocompleteProvider<Theme> | false | null | undefined): VariantResolver<Theme>;
declare function withAutocomplete<Theme extends BaseTheme = BaseTheme>(rule: Rule<Theme>, autocomplete: AutocompleteProvider<Theme> | false | null | undefined): Rule<Theme>;
/**
* @internal
* @param resolver
* @returns
*/
declare function getAutocompleteProvider<Theme extends BaseTheme = BaseTheme>(resolver: RuleResolver<Theme> | VariantResolver<Theme>): AutocompleteProvider<Theme> | undefined;
/**
* @internal
* @param color
* @param options
* @returns
*/
declare function toColorValue(color: ColorValue, options?: ColorFunctionOptions): string;
/**
* Looks for a matching dark color within a [tailwind color palette](https://tailwindcss.com/docs/customizing-colors) (`50`, `100`, `200`, ..., `800`, `900`).
*
* ```js
* defineConfig({
* darkColor: autoDarkColor,
* })
* ```
*
* **Note**: Does not work for arbitrary values like `[theme(colors.gray.500)]` or `[theme(colors.gray.500, #ccc)]`.
*
* @group Configuration
* @param section within theme to use
* @param key of the light color or an arbitrary value
* @param context to use
* @returns the dark color if found
*/
declare function autoDarkColor(section: string, key: string, { theme }: Context<any>): ColorValue | Falsey;
/**
* @group Class Name Generators
* @param strings
* @param interpolations
*/
declare function css(strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): string;
declare function css(style: CSSObject | string): string;
/**
* Constructs `class` strings conditionally.
*
* Twinds version of popular libraries like [classnames](https://github.com/JedWatson/classnames) or [clsx](https://github.com/lukeed/clsx).
* The key advantage of `cx` is that it supports twinds enhanced class name syntax like grouping and aliases.
*
* @group Class Name Generators
* @param strings
* @param interpolations
* @returns
*/
declare function cx(strings: TemplateStringsArray, ...interpolations: Class[]): string;
/**
* Constructs `class` strings conditionally.
*
* Twinds version of popular libraries like [classnames](https://github.com/JedWatson/classnames) or [clsx](https://github.com/lukeed/clsx).
* The key advantage of `cx` is that it supports twinds enhanced class name syntax like grouping and aliases.
*
* @group Class Name Generators
* @param input
*/
declare function cx(...input: Class[]): string;
/**
* @group Configuration
* @param param0
* @returns
*/
declare function defineConfig<Theme = BaseTheme, Presets extends Preset<any>[] = Preset[]>({ presets, ...userConfig }: TwindUserConfig<Theme, Presets>): TwindConfig<BaseTheme & ExtractThemes<Theme, Presets>>;
interface InjectGlobalFunction {
(style: CSSBase | string): void;
(strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): void;
bind(thisArg?: ((tokens: string) => string) | undefined | void): InjectGlobalFunction;
call(thisArg: ((tokens: string) => string) | undefined | void, style: CSSBase | string): void;
apply(thisArg: ((tokens: string) => string) | undefined | void, args: [CSSBase | string]): void;
}
interface Preflight {
(preflight: CSSRules, context: Context): CSSRules | undefined | void;
/**
* Injects styles into the global scope and is useful for applications such as gloabl styles, CSS resets or font faces.
*
* It **does not** return a class name, but adds the styles within the base layer to the stylesheet directly.
*
* @group Style Injectors
*/
declare const injectGlobal: InjectGlobalFunction;
/**
* @group Runtime
* @param config
* @param isProduction
*/
declare function install<Theme extends BaseTheme = BaseTheme>(config: TwindConfig<Theme>, isProduction?: boolean): Twind<Theme & BaseTheme>;
declare function install<Theme = BaseTheme, Presets extends Preset<any>[] = Preset[]>(config: TwindUserConfig<Theme, Presets>, isProduction?: boolean): Twind<BaseTheme & ExtractThemes<Theme, Presets>>;
interface KeyframesFunction {
(style: CSSObject | string): StringLike;
(strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): StringLike;
bind(thisArg?: ((tokens: string) => string) | undefined | void): Keyframes & {
[label: string]: KeyframesFunction;
};
call(thisArg: ((tokens: string) => string) | undefined | void, style: CSSObject | string): StringLike;
call(thisArg: ((tokens: string) => string) | undefined | void, strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): StringLike;
apply(thisArg: ((tokens: string) => string) | undefined | void, args: [CSSObject | string]): StringLike;
apply(thisArg: ((tokens: string) => string) | undefined | void, args: [CSSObject | string] | [strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]]): StringLike;
}
interface ThemeConfiguration extends Partial<Theme> {
extend?: Partial<Theme>;
}
interface InjectorConfig<T = unknown> {
declare type Keyframes = KeyframesFunction & {
[label: string]: KeyframesFunction;
};
/**
* **Note**: The styles will be injected on first use.
*
* @group Style Injectors
*/
declare const keyframes: Keyframes;
/**
* @group Runtime
* @param tw
* @param target
* @returns
*/
declare function observe<Theme extends BaseTheme = BaseTheme, Target = unknown>(tw?: Twind<Theme, Target>, target?: false | HTMLElement): Twind<Theme, Target>;
interface ParsedRule {
/**
* Sets a cryptographic nonce (number used once) on the enclosing `<style>` tag when generating a page on demand.
*
* Useful for enforcing a [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP).
* The utility name including `-` if set, but without `!` and variants
*/
nonce?: string;
/** Target to insert rules into. */
target?: T;
readonly n: string;
/**
* All variants without trailing colon: `hover`, `after:`, `[...]`
*/
readonly v: string[];
/**
* Something like `!underline` or `!bg-red-500` or `!red-500`
*/
readonly i?: boolean;
}
interface Injector {
insert: (rule: string, index: number) => void;
interface ParsedDevRule extends ParsedRule {
readonly a: string[];
readonly l: [start: number, end: number];
}
interface VirtualInjector extends Injector {
target: string[];
/**
* @internal
* @param token
* @returns
*/
declare function parse(token: string): ParsedRule[];
declare type ThemeMatchResult<Value> = MatchResult & {
/** The found theme value */
_: Value;
};
declare type ThemeRuleResolver<Value, Theme extends BaseTheme = BaseTheme> = RuleResolver<Theme, ThemeMatchResult<Value>>;
declare type ThemeMatchConverter<Value, Theme extends BaseTheme = BaseTheme> = MatchConverter<Theme, ThemeMatchResult<Value>>;
/**
* @group Configuration
* @param pattern
*/
declare function match<Theme extends BaseTheme = BaseTheme>(pattern: MaybeArray<string | RegExp>): Rule<Theme>;
/**
* @group Configuration
* @param pattern
* @param resolver
*/
declare function match<Theme extends BaseTheme = BaseTheme>(pattern: MaybeArray<string | RegExp>, resolver: RuleResolver<Theme>): Rule<Theme>;
/**
* @group Configuration
* @param pattern
* @param resolve
*/
declare function match<Theme extends BaseTheme = BaseTheme>(pattern: MaybeArray<string | RegExp>, resolve: (string & {}) | CSSObject): Rule<Theme>;
/**
* @group Configuration
* @param pattern
* @param resolve
* @param convert
*/
declare function match<Theme extends BaseTheme = BaseTheme>(pattern: MaybeArray<string | RegExp>, resolve: keyof CSSProperties, convert?: MatchConverter<Theme>): Rule<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link match} instead.
*/
declare function fromMatch<Theme extends BaseTheme = BaseTheme>(): RuleResolver<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link match} instead.
*/
declare function fromMatch<Theme extends BaseTheme = BaseTheme>(resolver: RuleResolver<Theme>): RuleResolver<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link match} instead.
*/
declare function fromMatch<Theme extends BaseTheme = BaseTheme>(resolve: keyof CSSProperties, convert?: MatchConverter<Theme>): RuleResolver<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link match} instead.
*/
declare function fromMatch<Theme extends BaseTheme = BaseTheme>(resolve: string | CSSObject): RuleResolver<Theme>;
/**
* @group Configuration
* @param pattern
* @param section
* @param resolve
* @param convert
* @returns
*/
declare function matchTheme<Theme extends BaseTheme = BaseTheme, Section extends keyof Theme & string = keyof Theme & string>(pattern: MaybeArray<string | RegExp>,
/** Theme section to use (default: `$1` — The first matched group) */
section?: '' | Section | KebabCase<Section>,
/** The css property (default: value of {@link section}) */
resolve?: keyof CSSProperties | ThemeRuleResolver<ThemeValue<Theme[Section]>, Theme>, convert?: ThemeMatchConverter<ThemeValue<Theme[Section]>, Theme>): Rule<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link matchTheme} instead.
* @param section
* @param resolve
* @param convert
* @returns
*/
declare function fromTheme<Theme extends BaseTheme = BaseTheme, Section extends keyof Theme & string = keyof Theme & string>(
/** Theme section to use (default: `$1` — The first matched group) */
section?: '' | Section | KebabCase<Section>,
/** The css property (default: value of {@link section}) */
resolve?: keyof CSSProperties | ThemeRuleResolver<ThemeValue<Theme[Section]>, Theme>, convert?: ThemeMatchConverter<ThemeValue<Theme[Section]>, Theme>): RuleResolver<Theme>;
declare type FilterByThemeValue<Theme, Value> = {
[key in keyof Theme & string]: ThemeValue<Theme[key]> extends Value ? Theme[key] : never;
};
interface ColorFromThemeValue {
value: string;
color: ColorFunction;
opacityVariable: string | undefined;
opacityValue: string | undefined;
}
interface CSSOMInjector extends Injector {
target: CSSStyleSheet;
interface ColorFromThemeOptions<Theme extends BaseTheme = BaseTheme, Section extends keyof FilterByThemeValue<Theme, ColorValue> = keyof FilterByThemeValue<Theme, ColorValue>, OpacitySection extends keyof FilterByThemeValue<Theme, string> = keyof FilterByThemeValue<Theme, string>> {
/** Theme section to use (default: `$0.replace('-', 'Color')` — The matched string with `Color` appended) */
section?: Section | KebabCase<Section>;
/** The css property (default: value of {@link section}) */
property?: keyof CSSProperties;
/** `--tw-${$0}opacity` -> '--tw-text-opacity' */
opacityVariable?: string | false;
/** `section.replace('Color', 'Opacity')` -> 'textOpacity' */
opacitySection?: OpacitySection;
selector?: string;
}
declare type Prefixer = (property: string, value: string) => string;
declare type Hasher = (value: string) => string;
declare type DarkMode = 'media' | 'class' | false;
interface Configuration {
/**
* @group Configuration
* @param pattern
* @param options
* @param resolve
* @returns
*/
declare function matchColor<Theme extends BaseTheme = BaseTheme, Section extends keyof FilterByThemeValue<Theme, ColorValue> = keyof FilterByThemeValue<Theme, ColorValue>, OpacitySection extends keyof FilterByThemeValue<Theme, string> = keyof FilterByThemeValue<Theme, string>>(pattern: MaybeArray<string | RegExp>, options?: ColorFromThemeOptions<Theme, Section, OpacitySection>, resolve?: ThemeRuleResolver<ColorFromThemeValue, Theme>): Rule<Theme>;
/**
* @group Configuration
* @internal
* @deprecated Use {@link matchColor} instead.
* @param options
* @param resolve
* @returns
*/
declare function colorFromTheme<Theme extends BaseTheme = BaseTheme, Section extends keyof FilterByThemeValue<Theme, ColorValue> = keyof FilterByThemeValue<Theme, ColorValue>, OpacitySection extends keyof FilterByThemeValue<Theme, string> = keyof FilterByThemeValue<Theme, string>>(options?: ColorFromThemeOptions<Theme, Section, OpacitySection>, resolve?: ThemeRuleResolver<ColorFromThemeValue, Theme>): RuleResolver<Theme>;
/**
* @internal
* @param property
* @param value
* @returns
*/
declare function toCSS(property: string, value: string | ColorFromThemeValue): CSSObject;
/**
* @internal
* @param value
* @param section
* @param context
* @returns
*/
declare function arbitrary<Theme extends BaseTheme = BaseTheme>(value: string, section: string, context: Context<Theme>): string | undefined;
/**
* @internal
* @param value
* @returns
*/
declare function normalize(value: string): string;
/**
* @group Runtime
* @param install
* @returns
*/
declare function auto(install: () => void): () => void;
/**
* A proxy to the currently active Twind instance.
* @group Style Injectors
*/
declare const tw: Twind<any, any>;
declare type SheetFactory<SheetTarget = unknown> = () => Sheet<SheetTarget>;
/**
* Manages a single Twind instance — works in browser, Node.js, Deno, workers...
*
* @group Runtime
* @param config
* @param sheet
* @param target
* @returns
*/
declare function setup<Theme extends BaseTheme = BaseTheme, SheetTarget = unknown>(config?: TwindConfig<Theme>, sheet?: Sheet<SheetTarget> | SheetFactory<SheetTarget>, target?: HTMLElement): Twind<Theme, SheetTarget>;
declare function setup<Theme = BaseTheme, Presets extends Preset<any>[] = Preset[], SheetTarget = unknown>(config?: TwindUserConfig<Theme, Presets>, sheet?: Sheet<SheetTarget> | SheetFactory<SheetTarget>, target?: HTMLElement): Twind<BaseTheme & ExtractThemes<Theme, Presets>, SheetTarget>;
/**
* @group Sheets
* @param element
* @returns
*/
declare function cssom(element?: CSSStyleSheet | HTMLStyleElement | string | null | false): Sheet<CSSStyleSheet>;
/**
* @group Sheets
* @param element
* @returns
*/
declare function dom(element?: HTMLStyleElement | string | null | false): Sheet<HTMLStyleElement>;
/**
* @group Sheets
* @param includeResumeData
* @returns
*/
declare function virtual(includeResumeData?: boolean): Sheet<string[]>;
/**
* Returns a sheet useable in the current environment.
*
* @group Sheets
* @param useDOMSheet usually something like `process.env.NODE_ENV != 'production'` or `import.meta.env.DEV` (default: browser={@link cssom}, server={@link virtual})
* @param disableResume to not include or use resume data
* @returns a sheet to use
*/
declare function getSheet(useDOMSheet?: boolean, disableResume?: boolean): Sheet<string[] | HTMLStyleElement | CSSStyleSheet>;
/**
* @group Sheets
* @param target
* @returns
*/
declare function stringify(target: unknown): string;
/**
* Options for {@link inline}
*/
interface InlineOptions {
/**
* Determines the dark mode strategy (default: `"media"`).
* {@link Twind} instance to use (default: {@link twind.tw})
*/
darkMode?: DarkMode;
theme?: ThemeConfiguration;
plugins?: Plugins;
tw?: Twind<any, any>;
/**
* Sets a cryptographic nonce (number used once) on the enclosing `<style>` tag when generating a page on demand.
* Allows to minify the resulting CSS.
*/
minify?: InlineMinify;
}
interface InlineMinify {
/**
* Called to minify the CSS.
*
* Useful for enforcing a [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP).
* @param css the CSS to minify
* @param html the HTML that will be used — allows to only include above-the-fold CSS
* @return the resulting CSS
*/
nonce?: string;
/** Style insertion methodology to be used. */
injector?: Injector;
/** Called right before the first rule is injected. */
preflight?: Preflight | boolean;
/** Auto-prefixer method for CSS property–value pairs. */
prefix?: Prefixer | boolean;
hash?: Hasher | boolean;
mode?: Mode;
(css: string, html: string): string;
}
declare type ReportInfo = {
id: 'LATE_SETUP_CALL';
} | {
id: 'UNKNOWN_DIRECTIVE';
rule: string;
} | {
id: 'UNKNOWN_THEME_VALUE';
key: string | undefined;
} | {
id: 'INJECT_CSS_ERROR';
error: Error;
/**
* Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)
*
* 1. parse the markup and process element classes with the provided Twind instance
* 2. update the class attributes _if_ necessary
* 3. inject a style element with the CSS as last element into the head
* 4. return the HTML string with the final element classes
*
* ```js
* import { inline } from 'twind'
*
* function render() {
* return inline(renderApp())
* }
* ```
*
* Minify CSS with [@parcel/css](https://www.npmjs.com/package/@parcel/css):
*
* ```js
* import { inline } from 'twind'
* import { transform } from '@parcel/css'
*
* function render() {
* return inline(renderApp(), { minify: (css) => transform({ filename: 'twind.css', code: Buffer.from(css), minify: true }) })
* }
* ```
*
* You can provide your own Twind instance:
*
* ```js
* import { inline } from 'twind'
* import { tw } from './custom/twind/instance'
*
* function render() {
* return inline(renderApp(), { tw })
* }
* ```
*
* @group Static Extraction
* @param markup HTML to process
* @param options to customize the processing
* @returns the resulting HTML
*/
declare function inline(markup: string, options?: InlineOptions['tw'] | InlineOptions): string;
/**
* Result of {@link extract}
*/
interface ExtractResult {
/** The possibly modified HTML */
html: string;
/** The generated CSS */
css: string;
}
/**
* Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)
*
* **Note**: Consider using {@link inline} instead.
*
* 1. parse the markup and process element classes with the provided Twind instance
* 2. update the class attributes _if_ necessary
* 3. return the HTML string with the final element classes
*
* ```js
* import { extract } from 'twind'
*
* function render() {
* const { html, css } = extract(renderApp())
*
* // inject as last element into the head
* return html.replace('</head>', `<style data-twind>${css}</style></head>`)
* }
* ```
*
* You can provide your own Twind instance:
*
* ```js
* import { extract } from 'twind'
* import { tw } from './custom/twind/instance'
*
* function render() {
* const { html, css } = extract(renderApp(), tw)
*
* // inject as last element into the head
* return html.replace('</head>', `<style data-twind>${css}</style></head>`)
* }
* ```
*
* @group Static Extraction
* @param markup HTML to process
* @param tw a {@link Twind} instance (default: twind managed tw)
* @returns the possibly modified html and css
*/
declare function extract(html: string, tw?: Twind<any, any>): ExtractResult;
/**
* Used for static HTML processing (usually to provide SSR support for your javascript-powered web apps)
*
* **Note**: Consider using {@link inline} or {@link extract} instead.
*
* 1. parse the markup and process element classes with the provided Twind instance
* 2. update the class attributes _if_ necessary
* 3. return the HTML string with the final element classes
*
* ```js
* import { consume, stringify, tw } from 'twind'
*
* function render() {
* const html = renderApp()
*
* // remember global classes
* const restore = tw.snapshot()
*
* // generated markup
* const markup = consume(html)
*
* // create CSS
* const css = stringify(tw.target)
*
* // restore global classes
* restore()
*
* // inject as last element into the head
* return markup.replace('</head>', `<style data-twind>${css}</style></head>`)
* }
* ```
*
* You can provide your own Twind instance:
*
* ```js
* import { consume, stringify } from 'twind'
* import { tw } from './custom/twind/instance'
*
* function render() {
* const html = renderApp()
*
* // remember global classes
* const restore = snapshot(tw.target)
*
* // generated markup
* const markup = consume(html)
*
* // restore global classes
* restore()
*
* // create CSS
* const css = stringify(tw.target)
*
* // inject as last element into the head
* return markup.replace('</head>', `<style data-twind>${css}</style></head>`)
* }
* ```
*
* @group Static Extraction
* @param markup HTML to process
* @param tw a {@link Twind} instance
* @returns possibly modified HTML
*/
declare function consume(markup: string, tw?: (className: string) => string): string;
declare type StrictMorphVariant<T> = T extends number ? `${T}` | T : T extends 'true' ? true | T : T extends 'false' ? false | T : T;
declare type MorphVariant<T> = T extends number ? `${T}` | T : T extends 'true' ? boolean | T : T extends 'false' ? boolean | T : T extends `${number}` ? number | T : T;
declare type StyleTokenValue = string | Falsey;
declare type StyleToken = StyleTokenValue;
/**
* Allows to extract the supported properties of a style function.
*
* Here is an example for `react`
* ```js
* import { HTMLAttributes } from "react";
* import { style, PropsOf } from "twind";
* const button = style({ ... })
* type ButtonProps = PropsOf<typeof button>
* export const Button = (props: ButtonProps & HTMLAttributes<HTMLButtonElement>) => {
* return <button className={style(props)} {...rest} />
* }
* ```
*/
declare type PropsOf<T> = T extends Style<infer Variants> ? {
[key in keyof Variants]: MorphVariant<keyof Variants[key]>;
} : never;
declare type DefaultVariants<Variants> = {
[key in keyof Variants]?: StrictMorphVariant<keyof Variants[key]> | (Record<string, StrictMorphVariant<keyof Variants[key]>> & {
/** initial breakpoint */
_?: StrictMorphVariant<keyof Variants[key]>;
});
};
interface Mode {
/** Called for unknown theme values */
unknown: <Section extends keyof Theme>(section: Section, key: string[] | undefined, optional: boolean, context: Context) => ThemeSectionType<Theme[Section]> | undefined | void;
declare type VariantsProps<Variants> = {
[key in keyof Variants]?: MorphVariant<keyof Variants[key]> | (Record<string, MorphVariant<keyof Variants[key]>> & {
/** initial breakpoint */
_?: MorphVariant<keyof Variants[key]>;
});
};
declare type When<Variants> = {
[key in keyof Variants]?: StrictMorphVariant<keyof Variants[key]>;
};
interface StyleConfig<Variants, BaseVariants = {}> {
/** Used as prefix */
label?: string;
base?: StyleToken;
props?: Variants & {
[variant in keyof BaseVariants]?: {
[key in keyof BaseVariants[variant]]?: StyleToken;
};
};
defaults?: DefaultVariants<Variants & BaseVariants>;
when?: [match: When<Variants & BaseVariants>, then: StyleToken][];
}
interface StyleFunction {
<Variants>(config?: StyleConfig<Variants>): Style<Variants>;
<Variants, BaseVariants>(base: Style<BaseVariants>, config?: StyleConfig<Variants, BaseVariants>): Style<Variants & BaseVariants>;
}
declare type StyleProps<Variants> = VariantsProps<Variants>;
interface Style<Variants> {
/**
* Notify error (missing plugin, duplicate directives? )
* CSS Class associated with the current component.
*
* Why id?
* - can generate an url with more info
* - reduce bundle size by omitting large error messages
* ```jsx
* const button = style({
* base: css({
* color: "DarkSlateGray"
* })
* })
*
* <div className={button()} />
* ```
* <br />
*/
report(info: ReportInfo, context: Context): void;
}
declare type Plugin = string | CSSRules | DirectiveHandler;
declare type Plugins = Record<string, Plugin | undefined>;
interface DirectiveHandler {
(props?: StyleProps<Variants>): string;
/**
* Creates CSSRules based on `parameters`
* To be used as resolve within config.rules:
*
* ```js
* {
* rules: [
* // label?prop=value&other=propValue
* // if the style has base eg no prop is required
* ['label(\\?.+)?', style( /* ... *\/ )],
*
* // if the style requires at least one prop
* ['label\\?(.+)', style( /* ... *\/ )],
* ]
* }
* ```
*
* The first group is used to extract the props using {@link !URLSearchParams | URLSearchParams}.
*/
(parameters: string[], context: Context, id: string): CSSRules | string | Falsy;
}
interface Rule {
(match: MatchResult): string;
readonly defaults: StyleProps<Variants>;
/**
* The variants: `[":sm", ":dark", ":hover"]`
* CSS Class associated with the current component.
*
* ```js
* const button = style({
* base: css`
* color: "DarkSlateGray"
* `
* })
*
* <div className={button.className} />
* ```
*/
v: string[];
readonly className: string;
/**
* The directive: `"text-sm"`, `"rotate-45"`
*/
d: string | InlineDirective;
/** Is this rule negated: `"-rotate-45"` =\> `true` */
n: boolean | undefined;
/**
* The id is the tailwind rule including variants, negate and directive
* CSS Selector associated with the current component.
*
* Initialy this is set to an empty string.
* ```js
* const button = style({
* base: css({
* color: "DarkSlateGray"
* })
* })
*
* This is used to cache the id of static rules (from template literals).
* const Card = styled({
* base: css`
* & ${button.selector} {
* boxShadow: "0 0 0 5px"
* }
* `
* })
* ```
*/
$: string;
readonly selector: string;
}
interface InlineDirective {
(context: Context): CSSRules | string | Falsy;
}
interface TokenGrouping extends Record<string, Token> {
}
declare type TypescriptCompat = boolean | number;
declare type Token = string | TokenGrouping | InlineDirective | Token[] | Falsy | TypescriptCompat;
/**
* @group Class Name Generators
*/
declare const style: StyleFunction;
declare const create: (config?: Configuration | undefined) => Instance;
/**
* @group Runtime
* @param config
* @param sheet
*/
declare function twind<Theme extends BaseTheme = BaseTheme, Target = unknown>(config: TwindConfig<Theme>, sheet: Sheet<Target>): Twind<Theme, Target>;
declare function twind<Theme = BaseTheme, Presets extends Preset<any>[] = Preset[], Target = unknown>(config: TwindUserConfig<Theme, Presets>, sheet: Sheet<Target>): Twind<BaseTheme & ExtractThemes<Theme, Presets>, Target>;
declare const STYLE_ELEMENT_ID: "__tw-in-js";
declare global {
interface Window {
[STYLE_ELEMENT_ID]?: HTMLStyleElement;
}
interface TxFunction {
(...classes: Class[]): string;
(strings: TemplateStringsArray, ...interpolations: readonly Class[]): string;
bind(thisArg?: ((tokens: string) => string) | undefined | void): TxFunction;
call(thisArg: ((tokens: string) => string) | undefined | void, ...classes: Class[]): string;
call(thisArg: ((tokens: string) => string) | undefined | void, strings: TemplateStringsArray, ...interpolations: readonly Class[]): string;
apply(thisArg: ((tokens: string) => string) | undefined | void, classes: Class[] | [strings: TemplateStringsArray, ...interpolations: readonly Class[]]): string;
}
/**
* Creates an injector which collects style rules during server-side rendering.
* Combines {@link tw} and {@link cx}.
*
* Using the default `tw` instance:
*
* ```js
* import { tw } from 'twind'
* tx`underline ${falsy && 'italic'}`
* tx('underline', falsy && 'italic')
* tx({'underline': true, 'italic': false})
*
* // using a custom twind instance
* import { tw } from './custom/twind'
* import { tw } from './custom/twind'
* tx.bind(tw)
* ```
*
* Using a custom `tw` instance:
*
* ```js
* import { tx as tx$ } from 'twind'
* import { tw } from './custom/twind'
*
* export const tx = tx$.bind(tw)
*
* tx`underline ${falsy && 'italic'}`
* tx('underline', falsy && 'italic')
* tx({'underline': true, 'italic': false})
* ```
*
* @group Style Injectors
* @param this {@link Twind} instance to use (default: {@link tw})
* @param strings
* @param interpolations
* @returns the class name
*/
declare const virtualInjector: ({ target, }?: InjectorConfig<string[]>) => VirtualInjector;
declare const tx: TxFunction;
/**
* Creates an injector which inserts style rules through the CSS Object Model.
* @internal
*/
declare const cssomInjector: ({ nonce, target, }?: InjectorConfig<CSSStyleSheet>) => CSSOMInjector;
declare const escape: typeof CSS.escape;
/**
* An injector placeholder which performs no operations. Useful for avoiding errors in a non-browser environment.
* @group Configuration
* @param value
* @returns
*/
declare const noOpInjector: () => Injector;
declare function hash(value: string): string;
/**
* @internal
* @param screen
* @param prefix
* @returns
*/
declare function mql(screen: MaybeArray<ScreenValue>, prefix?: string): string;
/**
* @internal
* @param value
* @returns
*/
declare function asArray<T>(value?: T): T extends Array<any> ? T : T[];
/**
* @internal
* @param value
* @returns
*/
declare function identity<T>(value: T): T;
/**
* @internal
*/
declare function noop(): void;
declare const mode: (report: (message: string) => void) => Mode;
declare const warn: Mode;
declare const strict: Mode;
declare const autoprefix: Prefixer;
declare const noprefix: Prefixer;
declare const tw: TW;
declare const setup: (options?: Configuration | undefined) => void;
export { CSSAtKeyframes, CSSAtMedia, CSSAtSupports, CSSCustomProperties, CSSOMInjector, CSSProperties, CSSPseudos, CSSRules, CSSSimplePseudos, Configuration, Context, DarkMode, DirectiveHandler, Falsy, Hasher, Injector, InjectorConfig, InlineDirective, Instance, Mode, Plugin, Plugins, Prefixer, Preflight, ReportInfo, Rule, TW, Theme, ThemeColor, ThemeConfiguration, ThemeContainer, ThemeFontSize, ThemeOutline, ThemeResolver, ThemeSection, ThemeSectionRecord, ThemeSectionResolver, ThemeSectionResolverContext, ThemeSectionType, Token, TokenGrouping, TypescriptCompat, Unwrap, VirtualInjector, autoprefix, create, cssomInjector, mode, noOpInjector, noprefix, setup, strict, tw, virtualInjector, warn };
export { Animation, AnimationFunction, ArrayType, AutocompleteContext, AutocompleteItem, AutocompleteModifier, AutocompleteProvider, BaseProperties, BaseTheme, CSSBase, CSSFontFace, CSSNested, CSSObject, CSSProperties, CSSValue, Class, ClassObject, ColorFromThemeOptions, ColorFromThemeValue, ColorFunction, ColorFunctionOptions, ColorRecord, ColorValue, Context, CustomProperties, DarkColor, DarkModeConfig, DefaultVariants, ExtractResult, ExtractTheme, ExtractThemes, ExtractUserTheme, Falsey, FilterByThemeValue, HashFunction, InjectGlobalFunction, InlineMinify, InlineOptions, KebabCase, Keyframes, KeyframesFunction, MatchConverter, MatchResult, MaybeArray, MaybeColorValue, MaybeThunk, MorphVariant, Nested, NestedFunction, ParsedDevRule, ParsedRule, PartialTheme, Preflight, PreflightThunk, Preset, PresetThunk, PropsOf, RestoreSnapshot, Rule, RuleResolver, RuleResult, ScreenValue, Sheet, SheetFactory, SheetRule, StrictMorphVariant, StringLike, StringifyDeclaration, Style, StyleConfig, StyleFunction, StyleProps, StyleToken, StyleTokenValue, ThemeConfig, ThemeFunction, ThemeMatchConverter, ThemeMatchResult, ThemeRuleResolver, ThemeSection, ThemeSectionResolver, ThemeSectionResolverContext, ThemeValue, Twind, TwindConfig, TwindPresetConfig, TwindRule, TwindUserConfig, TxFunction, TypedAtRules, TypedAtRulesKeys, UnionToIntersection, Variant, VariantResolver, VariantResult, VariantsProps, When, animation, apply, arbitrary, asArray, auto, autoDarkColor, colorFromTheme, consume, css, cssom, cx, defineConfig, dom, escape, extract, fromMatch, fromTheme, getAutocompleteProvider, getSheet, hash, identity, injectGlobal, inline, install, keyframes, match, matchColor, matchTheme, mql, noop, normalize, observe, parse, setup, shortcut, stringify, style, toCSS, toColorValue, tw, twind, tx, virtual, withAutocomplete };
//# sourceMappingURL=twind.d.ts.map

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc