Last active
March 20, 2024 13:48
-
-
Save Akkuma/7ecc69a504e7a6fdd00e253737b61807 to your computer and use it in GitHub Desktop.
Tailwind Width Type Magic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Widths */ | |
type TailwindFractionalWidth = `w-${number}/${number}`; | |
export type TailwindWidth = | |
| `w-${number}` | |
| TailwindFractionalWidth | |
| 'w-full' | |
| 'w-auto' | |
| `w-[clamp(${string},${string},${string})]`; | |
export type TailwindMinWidth = `min-${Exclude<TailwindWidth, TailwindFractionalWidth>}`; | |
export type TailwindMaxWidth = | |
| `max-${Exclude<TailwindWidth, TailwindFractionalWidth>}` | |
| `max-w-${TailwindBreakpoints}` | |
| `max-w-[${number}%]`; | |
export type TailwindBreakpoints = 'sm' | 'md' | 'lg' | 'xl' | '2xl'; | |
export type TailwindMinBreakpoints = `min-${TailwindBreakpoints}`; | |
export type TailwindMaxBreakpoints = `max-${TailwindBreakpoints}`; | |
export type Width = | |
| TailwindWidth | |
| `${TailwindBreakpoints | TailwindMinBreakpoints | TailwindMaxBreakpoints}:${TailwindWidth}`; | |
export type MaxWidth = | |
| TailwindMaxWidth | |
| `${TailwindBreakpoints | TailwindMinBreakpoints | TailwindMaxBreakpoints}:${TailwindMaxWidth}`; | |
export type MinWidth = | |
| TailwindMinWidth | |
| `${TailwindBreakpoints | TailwindMinBreakpoints | TailwindMaxBreakpoints}:${TailwindMinWidth}`; | |
export type AnyWidth = Width | MaxWidth | MinWidth; | |
type IsWidth<T extends string> = T extends AnyWidth ? true : false; | |
type AreAllWidths<T extends string[], Pos extends number[] = []> = T extends [infer Head, ...infer Tail] | |
? Head extends string | |
? IsWidth<Head> extends true | |
? Tail extends string[] | |
? AreAllWidths<Tail, [0, ...Pos]> | |
: never | |
: Head extends '' | |
? never | |
: `${Head} is an invalid tailwind width class or unsupported at index ${Pos['length']}` | |
: never | |
: true; | |
export type Split< | |
S extends string, | |
Delimiter extends string, | |
Acc extends string[] = [], | |
> = S extends `${infer Head}${Delimiter}${infer Tail}` | |
? Split<Tail, Delimiter, [Head, ...Acc]> | |
: S extends Delimiter | |
? Acc | |
: [S, ...Acc]; | |
type Reverse<T, Acc extends unknown[] = []> = T extends [infer Head, ...infer Tail] | |
? Reverse<Tail, [Head, ...Acc]> | |
: Acc; | |
type WidthsStr<T extends string, AAW = AreAllWidths<Reverse<Split<T, ' '>>>> = AAW extends never | |
? never | |
: AAW extends string | |
? { err: AAW } | |
: T; | |
export type Widths<T extends string, WS = WidthsStr<T>> = T extends '' | |
? AnyWidth | |
: WS extends { err: string } | |
? WS['err'] | |
: WS extends T | |
? T | |
: never; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment