com um clique
styling-react-with-tailwind
Use when building React components with Tailwind CSS in this codebase. Covers token usage, tv() patterns, and component structure.
Menu
Use when building React components with Tailwind CSS in this codebase. Covers token usage, tv() patterns, and component structure.
Use when composing Conventional Commit messages in this repo. Prioritizes commit prefixes by changed-file paths.
Use when publishing or scheduling posts in zenobi.us. Verifies stage behavior from code, updates frontmatter safely, and confirms visibility implications before merge.
Use when planning, drafting, or revising zenobi.us posts and you need repository-native writing style, start-middle-end structure, MDX-safe formatting, and miniproject-based planning artifacts.
Use when working with Remix routing in this repository as a static site generator (SSG). Covers file-based routing, dynamic segments, layout groups, and best practices.
| name | styling-react-with-tailwind |
| description | Use when building React components with Tailwind CSS in this codebase. Covers token usage, tv() patterns, and component structure. |
References:
This codebase uses:
tw-colors plugintv()) for type-safe variant styling{property}-{category}-{semantic}
Text tokens:
text-text-base - Primary body texttext-text-muted - Secondary/subtle texttext-text-link - Interactive link color (iris purple)text-text-strong - Emphasized textBackground tokens:
bg-background-base - Page backgroundbg-background-card - Card surfacesbg-background-button - Button backgroundsbg-background-informative - Info calloutsBorder tokens:
border-border-muted - Subtle bordersborder-border-input - Form field bordersborder-border-informative - Info bordersStandard Tailwind spacing scale. Use semantic sizing:
p-4, gap-2, m-0 - standard spacingmax-w-7xl - content width constraintsUse when component has multiple styled children.
import { tv, VariantProps } from 'tailwind-variants';
import { classnames } from '~/core/classnames';
const Styles = tv({
slots: {
root: ['flex', 'items-center', 'gap-2'],
label: ['text-text-base', 'font-medium'],
icon: ['text-text-muted', 'w-4', 'h-4'],
},
variants: {
size: {
sm: { root: 'p-2', label: 'text-sm' },
md: { root: 'p-4', label: 'text-base' },
},
intent: {
primary: { root: 'bg-background-button', label: 'text-text-strong' },
ghost: { root: 'bg-transparent', label: 'text-text-muted' },
},
},
defaultVariants: {
size: 'md',
intent: 'primary',
},
});
type StyleProps = VariantProps<typeof Styles>;
type Props = StyleProps & {
className?: string;
children: React.ReactNode;
};
export function MyComponent(props: Props) {
const styles = Styles({ size: props.size, intent: props.intent });
return (
<div className={classnames(styles.root(), props.className)}>
<span className={styles.icon()}>*</span>
<span className={styles.label()}>{props.children}</span>
</div>
);
}
Use when component is a single styled element.
import { tv, VariantProps } from 'tailwind-variants';
import { classnames } from '~/core/classnames';
const Styles = tv({
base: [
'border',
'border-border-muted',
'rounded',
'transition-colors',
],
variants: {
variant: {
solid: 'border-2',
dashed: 'border-dashed',
},
},
defaultVariants: {
variant: 'solid',
},
});
type Props = VariantProps<typeof Styles> & {
className?: string;
};
export function Divider(props: Props) {
const styles = Styles({ variant: props.variant });
return <hr className={classnames(styles, props.className)} />;
}
For conditional style combinations:
const Styles = tv({
base: ['rounded', 'px-4', 'py-2'],
variants: {
intent: { primary: '', danger: '' },
disabled: { true: 'opacity-50 cursor-not-allowed' },
},
compoundVariants: [
{
intent: 'primary',
disabled: false,
class: 'bg-background-button hover:bg-background-hover',
},
{
intent: 'danger',
disabled: false,
class: 'bg-red-500 hover:bg-red-600',
},
],
});
Always use for merging classes safely:
import { classnames } from '~/core/classnames';
// Merges and deduplicates Tailwind classes
classnames(styles.root(), props.className, isActive && 'ring-2');
For polymorphic components:
import { Box } from '~/components/ds/box/Box';
<Box asChild className="text-text-link">
<a href="/path">Link styled as Box</a>
</Box>
| Need | Use |
|---|---|
| Multiple styled elements | tv({ slots: { ... } }) |
| Single styled element | tv({ base: [...] }) |
| Variant types | VariantProps<typeof Styles> |
| Merge classes | classnames(a, b, c) |
| Conditional variants | compoundVariants: [...] |
| Purple accent | text-text-link, text-text-strong |
| Muted text | text-text-muted |
| Card background | bg-background-card |
text-text-base not text-gray-900)props.x not { x } per codebase convention