@molecule/app-styling-tailwind
Provider bond · styling · App (browser) · v1.0.2 · Apache-2.0
Utility-first CSS with cn() and cva()
npm install @molecule/app-styling-tailwindnpm · Source on GitHub · Implements @molecule/app-styling
How it works
@molecule/app-styling-tailwind is a provider bond on the app (browser) side: it implements the styling core interface (@molecule/app-styling) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
// 1. App startup — register the merger so cn() resolves Tailwind conflicts:
import { registerTailwindClassMerger } from '@molecule/app-styling-tailwind'
registerTailwindClassMerger()
// 2. tailwind.config.ts — derive the theme scale from the molecule theme:
import { themeToTailwind } from '@molecule/app-styling-tailwind'
import { lightTheme } from '@molecule/app-theme'
const tailwindConfig = { theme: { extend: themeToTailwind(lightTheme) } }
// …then `export default tailwindConfig` from tailwind.config.tsWorks with: @molecule/app-styling, @molecule/app-theme
Reference
Tailwind CSS styling utilities for molecule.dev.
The Tailwind bond for @molecule/app-styling: registers tailwind-merge as the
class-conflict merger for cn(), converts molecule themes into Tailwind config
(themeToTailwind), and ships cva-based component presets (buttonClasses,
inputClasses, cardClasses, badgeClasses) plus responsive/state helpers
(responsive, show, hide, dark, hover, …).
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
// 1. App startup — register the merger so cn() resolves Tailwind conflicts:
import { registerTailwindClassMerger } from '@molecule/app-styling-tailwind'
registerTailwindClassMerger()
// 2. tailwind.config.ts — derive the theme scale from the molecule theme:
import { themeToTailwind } from '@molecule/app-styling-tailwind'
import { lightTheme } from '@molecule/app-theme'
const tailwindConfig = { theme: { extend: themeToTailwind(lightTheme) } }
// …then `export default tailwindConfig` from tailwind.config.ts
Type
provider
Installation
npm install @molecule/app-styling-tailwind @molecule/app-styling @molecule/app-theme tailwind-merge
API
Interfaces
CVAConfig
Configuration for a class-variance-authority (cva) function: the variant
definitions, default selections, and compound variants used to resolve a
component's final class string from its props.
interface CVAConfig<T extends Record<string, Record<string, string>>> {
variants?: T
defaultVariants?: {
[K in keyof T]?: keyof T[K]
}
compoundVariants?: Array<
{
[K in keyof T]?: keyof T[K]
} & {
class: string
}
>
}
ThemeBreakpoints
Responsive viewport breakpoints from mobileS (320px) to desktop (2560px).
interface ThemeBreakpoints {
mobileS: string
mobileM: string
mobileL: string
tablet: string
laptop: string
laptopL: string
desktop: string
}
Theme
Complete theme definition.
interface Theme {
name: string
mode: 'light' | 'dark'
colors: ThemeColors
breakpoints: ThemeBreakpoints
spacing: ThemeSpacing
typography: ThemeTypography
borderRadius: ThemeBorderRadius
shadows: ThemeShadows
transitions: ThemeTransitions
zIndex: ThemeZIndex
}
Types
ClassValue
Class name value types accepted by cn.
type ClassValue =
| string
| number
| boolean
| undefined
| null
| ClassValue[]
| Record<string, boolean | undefined | null>
Functions
responsive(classes)
Generates responsive class variants.
function responsive(classes?: (string | false | null | undefined)[]): string
classes— Tailwind class strings, optionally with responsive prefixes (e.g.'md:text-base').
Returns: The merged class string (via cn).
show(breakpoint)
Returns classes that hide an element below the given breakpoint and show it at or above.
function show(breakpoint: keyof ThemeBreakpoints): string
breakpoint— The Tailwind breakpoint key (e.g.'sm','md','lg').
Returns: A class string like 'hidden md:block'.
hide(breakpoint)
Returns classes that show an element below the given breakpoint and hide it at or above.
function hide(breakpoint: keyof ThemeBreakpoints): string
breakpoint— The Tailwind breakpoint key (e.g.'sm','md','lg').
Returns: A class string like 'block lg:hidden'.
dark(classes)
Prefixes each class with dark: for Tailwind dark mode.
function dark(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of dark:-prefixed classes.
hover(classes)
Prefixes each class with hover: for Tailwind hover state.
function hover(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of hover:-prefixed classes.
focus(classes)
Prefixes each class with focus: for Tailwind focus state.
function focus(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of focus:-prefixed classes.
active(classes)
Prefixes each class with active: for Tailwind active (pressed) state.
function active(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of active:-prefixed classes.
disabled(classes)
Prefixes each class with disabled: for Tailwind disabled state.
function disabled(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of disabled:-prefixed classes.
groupHover(classes)
Prefixes each class with group-hover: for Tailwind group hover state.
function groupHover(classes?: string[]): string
classes— Tailwind utility class strings.
Returns: A space-separated string of group-hover:-prefixed classes.
themeToTailwind(theme)
Generates a Tailwind config extend object from a molecule theme.
function themeToTailwind(theme: Theme): Record<string, Record<string, unknown>>
theme— A moleculeThemeobject with colors, spacing, typography, shadows, etc.
Returns: A Tailwind theme.extend object mapping molecule tokens to Tailwind config values.
registerTailwindClassMerger()
Registers tailwind-merge as the class merger for @molecule/app-styling's
cn(), so conflicting Tailwind utilities (e.g. two gap-*) resolve with the
last one winning. Called once at startup by setupAppStylingTailwind() in
the default React bond wiring; call it directly in any custom setup (or test)
that renders Tailwind-styled components and relies on conflict resolution.
function registerTailwindClassMerger(): void
Constants
buttonClasses
Common button class presets.
const buttonClasses: (
props?:
| ({
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | undefined
size?: 'sm' | 'md' | 'lg' | undefined
} & { class?: string })
| undefined,
) => string
inputClasses
Common input class presets.
const inputClasses: (
props?:
| ({
variant?: 'default' | 'error' | 'success' | undefined
size?: 'sm' | 'md' | 'lg' | undefined
} & { class?: string })
| undefined,
) => string
cardClasses
Common card class presets.
const cardClasses: (
props?:
| ({
variant?: 'outline' | 'default' | 'elevated' | undefined
padding?: 'sm' | 'md' | 'lg' | 'none' | undefined
} & { class?: string })
| undefined,
) => string
badgeClasses
Common badge class presets.
const badgeClasses: (
props?:
| ({
variant?: 'primary' | 'secondary' | 'default' | 'error' | 'success' | 'warning' | undefined
size?: 'sm' | 'md' | 'lg' | undefined
} & { class?: string })
| undefined,
) => string
themeToCSS
Maps a molecule theme to CSS custom properties.
const themeToCSS: (theme: ThemeLike) => Record<string, string>
theme— A theme object with colors, spacing, typography, borderRadius, and shadows.
Returns: A flat record of CSS custom properties (e.g. { '--color-primary': '#3b82f6' }).
cn
Merges class names, filtering out falsy values. Supports strings, numbers, conditional objects, and nested arrays.
When a class merger is registered via setClassMerger (e.g. the
Tailwind bond registers tailwind-merge), conflicting utilities such as two
gap-* classes are resolved by it; otherwise the joined string is returned
as-is.
const cn: (...classes: ClassValue[]) => string
classes— Class values to merge (strings, booleans, objects, arrays).
Returns: A single space-separated class string.
cva
Creates a class variance authority (CVA) function for component variants. Given a base class and variant configuration, returns a function that resolves the final class string based on selected variants.
const cva: <T extends Record<string, Record<string, string>>>(
base: string,
config?: CVAConfig<T>,
) => (props?: { [K in keyof T]?: keyof T[K] } & { class?: string }) => string
base— The base class that is always included.config— Variant definitions, defaults, and compound variants.
Returns: A function that accepts variant props and returns the resolved class string.
camelToKebab
Converts a camelCase string to kebab-case.
const camelToKebab: (str: string) => string
str— The camelCase string to convert.
Returns: The kebab-case version (e.g. 'borderRadius' → 'border-radius').
Core Interface
Implements @molecule/app-styling interface.
Injection Notes
Requirements
Peer dependencies:
@molecule/app-styling^1.0.1@molecule/app-theme^1.0.1
Runtime Dependencies
-
@molecule/app-styling -
@molecule/app-theme -
tailwind-merge -
This is NOT the ClassMap bond. Application components style via
getClassMap()/cm.*from@molecule/app-ui(Tailwind ClassMap bond:@molecule/app-ui-tailwind). This package is infrastructure for styling/ClassMap bonds and shared-component plumbing — raw Tailwind class strings stay inside bond packages. -
Call
registerTailwindClassMerger()once at startup. Without it,cn()/cva()from@molecule/app-stylingjust join strings — conflicting utilities (e.g. twogap-*classes) BOTH survive and "last class wins" silently doesn't apply. -
The cva presets emit semantic token classes (
bg-primary,bg-surface, …) — they only resolve if the Tailwind config defines those colors; wirethemeToTailwind(theme)intotheme.extendas shown.