Attributify preset for UnoCSS that enables using utility classes as HTML attributes rather than class names.
—
Type-safe attribute names and values for TypeScript and JSX usage, providing full IntelliSense support and compile-time validation for attributify syntax.
Generic type for generating type-safe attribute names with optional prefixes.
/**
* Type-safe attribute names for attributify usage
* @template Prefix - Optional prefix string for attribute names
*/
type AttributifyNames<Prefix extends string = ''> =
| `${Prefix}${BasicAttributes}`
| `${Prefix}${PseudoPrefix}:${BasicAttributes}`;Main interface for type-safe attributify attributes in JSX/TSX.
/**
* Interface providing type-safe attribute names for JSX/TSX usage
* Extends Partial<Record> to make all attributes optional
*/
interface AttributifyAttributes extends Partial<Record<AttributifyNames, string | boolean>> {}Usage Examples:
import type { AttributifyAttributes } from '@unocss/preset-attributify'
// Use in React component props
interface ButtonProps extends AttributifyAttributes {
children: React.ReactNode;
}
function Button(props: ButtonProps) {
return <button {...props} />;
}
// Usage with full type safety
<Button
bg="blue-500 hover:blue-600" // ✓ Valid
text="white sm" // ✓ Valid
p="x-4 y-2" // ✓ Valid
invalidAttr="value" // ✗ TypeScript error
/>Union of all basic utility attribute types.
/**
* All basic attribute types available in attributify mode
*/
type BasicAttributes = SpecialSingleWord | TwoStringsComposition | SeparateEnabled;Utilities that work as complete UnoCSS rules by themselves.
/**
* Complete UnoCSS utilities that work as single words
*/
type SpecialSingleWord =
| 'container'
| 'flex'
| 'block'
| 'inline'
| 'table'
| 'isolate'
| 'absolute'
| 'relative'
| 'fixed'
| 'sticky'
| 'static'
| 'visible'
| 'invisible'
| 'grow'
| 'shrink'
| 'antialiased'
| 'italic'
| 'ordinal'
| 'overline'
| 'underline'
| 'uppercase'
| 'lowercase'
| 'capitalize'
| 'truncate'
| 'border'
| 'rounded'
| 'outline'
| 'ring'
| 'shadow'
| 'blur'
| 'grayscale'
| 'invert'
| 'sepia'
| 'transition'
| 'resize'
| 'transform'
| 'filter';Utilities that combine two characters to form complete utilities.
/**
* Valid prefixes for two-string composition utilities
*/
type TwoStringsCompositionPrefix = 'm' | 'p';
/**
* Valid suffixes for two-string composition utilities
*/
type TwoStringsCompositionSuffix = 'r' | 'b' | 'l' | 't' | 'a' | 'x' | 'y';
/**
* Two-character utility combinations plus special cases
*/
type TwoStringsComposition =
| `${TwoStringsCompositionPrefix}${TwoStringsCompositionSuffix}`
| 'ha'
| 'wa';Examples:
mr → margin-rightpt → padding-topha → height-autowa → width-autoValid pseudo-class and breakpoint prefixes for variants.
/**
* Valid pseudo-class and breakpoint prefixes
*/
type PseudoPrefix =
| 'active'
| 'before'
| 'after'
| 'dark'
| 'light'
| 'first'
| 'last'
| 'focus'
| 'hover'
| 'link'
| 'root'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| '2xl'
| 'enabled'
| 'disabled'
| 'all'
| 'children';Utilities that can contain multiple space-separated values.
/**
* Utilities that can separate multiple values with spaces
* For example: font="mono light", text="sm white"
*/
type SeparateEnabled =
| 'align'
| 'animate'
| 'backdrop'
| 'bg'
| 'blend'
| 'border'
| 'box'
| 'container'
| 'content'
| 'cursor'
| 'display'
| 'divide'
| 'filter'
| 'flex'
| 'font'
| 'fw'
| 'gap'
| 'gradient'
| 'grid'
| 'h'
| 'icon'
| 'items'
| 'justify'
| 'list'
| 'm'
| 'op'
| 'opacity'
| 'order'
| 'outline'
| 'overflow'
| 'p'
| 'place'
| 'pos'
| 'position'
| 'ring'
| 'select'
| 'shadow'
| 'size'
| 'space'
| 'table'
| 'text'
| 'transform'
| 'transition'
| 'underline'
| 'w'
| 'z'
| PseudoPrefix;React/JSX Usage:
import type { AttributifyAttributes } from '@unocss/preset-attributify'
// Extend component props
interface CardProps extends AttributifyAttributes {
title: string;
children: React.ReactNode;
}
function Card({ title, children, ...attrs }: CardProps) {
return (
<div
bg="white dark:gray-800"
border="rounded-lg"
p="6"
shadow="lg"
{...attrs}
>
<h2 text="xl font-bold">{title}</h2>
{children}
</div>
);
}Vue.js Usage:
<script setup lang="ts">
import type { AttributifyAttributes } from '@unocss/preset-attributify'
interface Props extends AttributifyAttributes {
title: string;
}
defineProps<Props>();
</script>
<template>
<div
bg="white dark:gray-800"
border="rounded-lg"
p="6"
shadow="lg"
>
<h2 text="xl font-bold">{{ title }}</h2>
<slot />
</div>
</template>Custom Prefix Support:
import type { AttributifyNames } from '@unocss/preset-attributify'
// Custom prefix type
type UIAttributes = Partial<Record<AttributifyNames<'ui-'>, string | boolean>>;
interface ComponentProps extends UIAttributes {
// Component-specific props
}
// Usage
<div
ui-bg="blue-500"
ui-text="white"
ui-p="4"
/>For global type augmentation in JSX environments:
// types/jsx.d.ts
import type { AttributifyAttributes } from '@unocss/preset-attributify'
declare module 'react' {
interface HTMLAttributes<T> extends AttributifyAttributes {}
}
// Now all HTML elements support attributify
<div bg="blue-500" text="white" /> // ✓ Type-safe everywhereReact:
import type { HTMLAttributes } from 'react'
import type { AttributifyAttributes } from '@unocss/preset-attributify'
type ReactAttributifyProps<T = HTMLElement> = HTMLAttributes<T> & AttributifyAttributes;Vue:
import type { AllowedComponentProps } from 'vue'
import type { AttributifyAttributes } from '@unocss/preset-attributify'
type VueAttributifyProps = AllowedComponentProps & AttributifyAttributes;Boolean Attributes:
// Both string and boolean values are supported
<div block /> // boolean: true
<div block="true" /> // string: "true"
<div block={true} /> // boolean: true (JSX)Complex Values:
// String values support complex utilities
<div bg="gradient-to-r from-blue-500 to-purple-600" />
<div text="lg font-bold leading-tight" />Type Checking:
Install with Tessl CLI
npx tessl i tessl/npm-unocss--preset-attributify