Utilities
Utilities are functions that accept a design-token value and return a StyleRule. Every utility satisfies the Utility type signature:
type Utility = (value: any) => StyleRuleAll utilities can be composed with cx() and dcx(), and wrapped with modifiers via when().
Spacing
Spacing utilities accept a SpacingInput value:
- number — maps to the spacing scale (e.g.
4becomes1rem) - string — passed through as a raw CSS value (e.g.
'2.5rem','auto') - DynamicValue — a runtime-dynamic value created with
dynamic()
The spacing scale follows Tailwind CSS conventions where each unit equals 0.25rem:
| Scale | Value | Scale | Value | Scale | Value |
|---|---|---|---|---|---|
0 | 0px | 6 | 1.5rem | 20 | 5rem |
0.5 | 0.125rem | 7 | 1.75rem | 24 | 6rem |
1 | 0.25rem | 8 | 2rem | 28 | 7rem |
1.5 | 0.375rem | 9 | 2.25rem | 32 | 8rem |
2 | 0.5rem | 10 | 2.5rem | 36 | 9rem |
2.5 | 0.625rem | 11 | 2.75rem | 40 | 10rem |
3 | 0.75rem | 12 | 3rem | 48 | 12rem |
3.5 | 0.875rem | 14 | 3.5rem | 56 | 14rem |
4 | 1rem | 16 | 4rem | 64 | 16rem |
5 | 1.25rem | 96 | 24rem |
Numbers not in the predefined scale fall back to value * 0.25rem.
p()
Sets padding on all sides.
function p(value: number | string | DynamicValue): StyleRuleCSS property: padding
import { cx, p } from 'typewritingclass'
cx(p(4)) // padding: 1remcx(p(0.5)) // padding: 0.125remcx(p('2.5rem')) // padding: 2.5rempx()
Sets horizontal padding (left and right).
function px(value: number | string | DynamicValue): StyleRuleCSS properties: padding-left, padding-right
import { cx, px } from 'typewritingclass'
cx(px(6)) // padding-left: 1.5rem; padding-right: 1.5remcx(px('10px')) // padding-left: 10px; padding-right: 10pxpy()
Sets vertical padding (top and bottom).
function py(value: number | string | DynamicValue): StyleRuleCSS properties: padding-top, padding-bottom
import { cx, py } from 'typewritingclass'
cx(py(2)) // padding-top: 0.5rem; padding-bottom: 0.5remcx(py('1em')) // padding-top: 1em; padding-bottom: 1empt()
Sets top padding.
function pt(value: number | string | DynamicValue): StyleRuleCSS property: padding-top
import { cx, pt } from 'typewritingclass'
cx(pt(8)) // padding-top: 2remcx(pt('0.5em')) // padding-top: 0.5empr()
Sets right padding.
function pr(value: number | string | DynamicValue): StyleRuleCSS property: padding-right
import { cx, pr } from 'typewritingclass'
cx(pr(3)) // padding-right: 0.75remcx(pr('1rem')) // padding-right: 1rempb()
Sets bottom padding.
function pb(value: number | string | DynamicValue): StyleRuleCSS property: padding-bottom
import { cx, pb } from 'typewritingclass'
cx(pb(10)) // padding-bottom: 2.5remcx(pb('2em')) // padding-bottom: 2empl()
Sets left padding.
function pl(value: number | string | DynamicValue): StyleRuleCSS property: padding-left
import { cx, pl } from 'typewritingclass'
cx(pl(5)) // padding-left: 1.25remcx(pl('3ch')) // padding-left: 3chm()
Sets margin on all sides.
function m(value: number | string | DynamicValue): StyleRuleCSS property: margin
import { cx, m } from 'typewritingclass'
cx(m(4)) // margin: 1remcx(m('auto')) // margin: automx()
Sets horizontal margin (left and right).
function mx(value: number | string | DynamicValue): StyleRuleCSS properties: margin-left, margin-right
import { cx, mx } from 'typewritingclass'
cx(mx(8)) // margin-left: 2rem; margin-right: 2remcx(mx('auto')) // margin-left: auto; margin-right: automy()
Sets vertical margin (top and bottom).
function my(value: number | string | DynamicValue): StyleRuleCSS properties: margin-top, margin-bottom
import { cx, my } from 'typewritingclass'
cx(my(6)) // margin-top: 1.5rem; margin-bottom: 1.5remcx(my('0.5em')) // margin-top: 0.5em; margin-bottom: 0.5emmt()
Sets top margin.
function mt(value: number | string | DynamicValue): StyleRuleCSS property: margin-top
import { cx, mt } from 'typewritingclass'
cx(mt(2)) // margin-top: 0.5remcx(mt('10px')) // margin-top: 10pxmr()
Sets right margin.
function mr(value: number | string | DynamicValue): StyleRuleCSS property: margin-right
import { cx, mr } from 'typewritingclass'
cx(mr(3)) // margin-right: 0.75remcx(mr('auto')) // margin-right: automb()
Sets bottom margin.
function mb(value: number | string | DynamicValue): StyleRuleCSS property: margin-bottom
import { cx, mb } from 'typewritingclass'
cx(mb(4)) // margin-bottom: 1remcx(mb('20px')) // margin-bottom: 20pxml()
Sets left margin.
function ml(value: number | string | DynamicValue): StyleRuleCSS property: margin-left
import { cx, ml } from 'typewritingclass'
cx(ml(12)) // margin-left: 3remcx(ml('auto')) // margin-left: autogap()
Sets gap between flex or grid children on both axes.
function gap(value: number | string | DynamicValue): StyleRuleCSS property: gap
import { cx, gap } from 'typewritingclass'
cx(gap(4)) // gap: 1remcx(gap('1.5em')) // gap: 1.5emgapX()
Sets horizontal (column) gap between flex or grid children.
function gapX(value: number | string | DynamicValue): StyleRuleCSS property: column-gap
import { cx, gapX } from 'typewritingclass'
cx(gapX(2)) // column-gap: 0.5remcx(gapX('12px')) // column-gap: 12pxgapY()
Sets vertical (row) gap between flex or grid children.
function gapY(value: number | string | DynamicValue): StyleRuleCSS property: row-gap
import { cx, gapY } from 'typewritingclass'
cx(gapY(3)) // row-gap: 0.75remcx(gapY('8px')) // row-gap: 8pxDynamic spacing example
All spacing utilities accept DynamicValue for runtime values:
import { dcx, p, mx, gap, dynamic } from 'typewritingclass'
const spacing = dynamic('1.5rem')const { className, style } = dcx(p(spacing), mx(spacing), gap(spacing))// style => { '--twc-d0': '1.5rem' }// All three utilities reference the same custom propertyColors
Color utilities accept a ColorInput value:
- string — a raw CSS color string (e.g.
'#3b82f6','red','rgb(59, 130, 246)') - CSSColor — a branded theme color token
- DynamicValue — a runtime-dynamic value created with
dynamic()
bg()
Sets the background color of an element.
function bg(color: string | DynamicValue): StyleRuleCSS property: background-color
import { cx, bg } from 'typewritingclass'import { blue } from 'typewritingclass/theme/colors'
cx(bg('#3b82f6')) // background-color: #3b82f6cx(bg(blue[500])) // background-color: #3b82f6cx(bg('transparent')) // background-color: transparentcx(bg('rgb(59, 130, 246)')) // background-color: rgb(59, 130, 246)Dynamic background:
import { dcx, bg, dynamic } from 'typewritingclass'
const { className, style } = dcx(bg(dynamic('#e11d48')))// CSS: background-color: var(--twc-d0)// style: { '--twc-d0': '#e11d48' }textColor()
Sets the text color of an element.
function textColor(color: string | DynamicValue): StyleRuleCSS property: color
import { cx, textColor } from 'typewritingclass'import { gray } from 'typewritingclass/theme/colors'
cx(textColor('#111827')) // color: #111827cx(textColor(gray[900])) // color: #111827cx(textColor('inherit')) // color: inheritDynamic text color:
import { dcx, textColor, dynamic } from 'typewritingclass'
const { className, style } = dcx(textColor(dynamic('#ffffff')))// CSS: color: var(--twc-d0)// style: { '--twc-d0': '#ffffff' }borderColor()
Sets the border color of an element.
function borderColor(color: string | DynamicValue): StyleRuleCSS property: border-color
import { cx, borderColor } from 'typewritingclass'import { gray } from 'typewritingclass/theme/colors'
cx(borderColor('#e5e7eb')) // border-color: #e5e7ebcx(borderColor(gray[200])) // border-color: #e5e7ebcx(borderColor('currentColor')) // border-color: currentColorDynamic border color:
import { dcx, borderColor, dynamic } from 'typewritingclass'
const { className, style } = dcx(borderColor(dynamic('#ef4444')))// CSS: border-color: var(--twc-d0)// style: { '--twc-d0': '#ef4444' }Typography
text()
Sets the font size (and optionally line height) of an element.
function text(size: TextSize | string | DynamicValue): StyleRuleCSS properties: font-size, and optionally line-height (when a TextSize object is passed)
When passed a TextSize object from the typography theme (which has both fontSize and lineHeight), both properties are set. When passed a raw string, only font-size is set.
import { cx, text } from 'typewritingclass'import { lg, _2xl } from 'typewritingclass/theme/typography'
// TextSize preset -- sets both font-size and line-heightcx(text(lg))// font-size: 1.125rem; line-height: 1.75rem
cx(text(_2xl))// font-size: 1.5rem; line-height: 2rem
// Raw string -- sets font-size onlycx(text('2rem'))// font-size: 2remDynamic font size:
import { dcx, text, dynamic } from 'typewritingclass'
const { className, style } = dcx(text(dynamic('1.5rem')))// CSS: font-size: var(--twc-d0)// style: { '--twc-d0': '1.5rem' }font()
Sets the font weight of an element.
function font(weight: string | DynamicValue): StyleRuleCSS property: font-weight
import { cx, font } from 'typewritingclass'import { bold, semibold } from 'typewritingclass/theme/typography'
cx(font(bold)) // font-weight: 700cx(font(semibold)) // font-weight: 600cx(font('400')) // font-weight: 400tracking()
Sets the letter spacing (tracking) of an element.
function tracking(value: string | DynamicValue): StyleRuleCSS property: letter-spacing
import { cx, tracking } from 'typewritingclass'
cx(tracking('-0.025em')) // letter-spacing: -0.025emcx(tracking('0.05em')) // letter-spacing: 0.05emcx(tracking('0.1em')) // letter-spacing: 0.1emleading()
Sets the line height (leading) of an element.
function leading(value: string | DynamicValue): StyleRuleCSS property: line-height
import { cx, leading } from 'typewritingclass'
cx(leading('1.5')) // line-height: 1.5cx(leading('2rem')) // line-height: 2remcx(leading('1')) // line-height: 1textAlign()
Sets the text alignment of an element.
function textAlign(value: string): StyleRuleCSS property: text-align
import { cx, textAlign } from 'typewritingclass'
cx(textAlign('center')) // text-align: centercx(textAlign('right')) // text-align: rightcx(textAlign('justify')) // text-align: justifycx(textAlign('left')) // text-align: leftLayout
flex()
Sets the element to display: flex.
function flex(): StyleRuleCSS property: display: flex
import { cx, flex, items, justify, gap } from 'typewritingclass'
cx(flex(), items('center'), justify('space-between'), gap(4))// display: flex; align-items: center; justify-content: space-between; gap: 1remflexCol()
Sets the element to a column-oriented flex container.
function flexCol(): StyleRuleCSS properties: display: flex, flex-direction: column
import { cx, flexCol, gap } from 'typewritingclass'
cx(flexCol(), gap(4))// display: flex; flex-direction: column; gap: 1remflexRow()
Sets the element to a row-oriented flex container.
function flexRow(): StyleRuleCSS properties: display: flex, flex-direction: row
import { cx, flexRow, gap } from 'typewritingclass'
cx(flexRow(), gap(2))// display: flex; flex-direction: row; gap: 0.5remflexWrap()
Sets flex-wrap: wrap on a flex container.
function flexWrap(): StyleRuleCSS property: flex-wrap: wrap
import { cx, flex, flexWrap, gap } from 'typewritingclass'
cx(flex(), flexWrap(), gap(4))// display: flex; flex-wrap: wrap; gap: 1reminlineFlex()
Sets the element to display: inline-flex.
function inlineFlex(): StyleRuleCSS property: display: inline-flex
import { cx, inlineFlex, items, gap } from 'typewritingclass'
cx(inlineFlex(), items('center'), gap(2))// display: inline-flex; align-items: center; gap: 0.5remgrid()
Sets the element to display: grid, optionally defining equal-width columns.
function grid(cols?: number): StyleRule| Parameter | Type | Description |
|---|---|---|
cols | number | undefined | Optional number of equal-width columns. |
CSS properties: display: grid, and optionally grid-template-columns
import { cx, grid, gap } from 'typewritingclass'
cx(grid())// display: grid
cx(grid(3))// display: grid; grid-template-columns: repeat(3, minmax(0, 1fr))
cx(grid(3), gap(4))// display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1remgridCols()
Sets the number of equal-width grid columns.
function gridCols(n: number): StyleRuleCSS property: grid-template-columns
import { cx, gridCols } from 'typewritingclass'
cx(gridCols(4))// grid-template-columns: repeat(4, minmax(0, 1fr))gridRows()
Sets the number of equal-height grid rows.
function gridRows(n: number): StyleRuleCSS property: grid-template-rows
import { cx, gridRows } from 'typewritingclass'
cx(gridRows(3))// grid-template-rows: repeat(3, minmax(0, 1fr))w()
Sets the width of an element.
function w(value: number | string | DynamicValue): StyleRuleCSS property: width
import { cx, w } from 'typewritingclass'import { full, screen } from 'typewritingclass/theme/sizes'
cx(w(64)) // width: 16remcx(w('100%')) // width: 100%cx(w(full)) // width: 100%cx(w(screen)) // width: 100vwh()
Sets the height of an element.
function h(value: number | string | DynamicValue): StyleRuleCSS property: height
import { cx, h } from 'typewritingclass'import { screenH } from 'typewritingclass/theme/sizes'
cx(h(12)) // height: 3remcx(h('100vh')) // height: 100vhcx(h(screenH)) // height: 100vhsize()
Sets both width and height to the same value.
function size(value: number | string | DynamicValue): StyleRuleCSS properties: width, height
import { cx, size } from 'typewritingclass'
cx(size(10)) // width: 2.5rem; height: 2.5remcx(size('48px')) // width: 48px; height: 48pxminW()
Sets the minimum width of an element.
function minW(value: number | string | DynamicValue): StyleRuleCSS property: min-width
import { cx, minW } from 'typewritingclass'
cx(minW(48)) // min-width: 12remcx(minW('0')) // min-width: 0minH()
Sets the minimum height of an element.
function minH(value: number | string | DynamicValue): StyleRuleCSS property: min-height
import { cx, minH } from 'typewritingclass'
cx(minH(96)) // min-height: 24remcx(minH('100vh')) // min-height: 100vhmaxW()
Sets the maximum width of an element.
function maxW(value: number | string | DynamicValue): StyleRuleCSS property: max-width
import { cx, maxW } from 'typewritingclass'
cx(maxW(80)) // max-width: 20remcx(maxW('768px')) // max-width: 768pxmaxH()
Sets the maximum height of an element.
function maxH(value: number | string | DynamicValue): StyleRuleCSS property: max-height
import { cx, maxH } from 'typewritingclass'
cx(maxH(40)) // max-height: 10remcx(maxH('100vh')) // max-height: 100vhdisplay()
Sets the CSS display property.
function display(value: string): StyleRuleCSS property: display
import { cx, display } from 'typewritingclass'
cx(display('block')) // display: blockcx(display('inline-block')) // display: inline-blockcx(display('none')) // display: noneitems()
Sets the align-items property on a flex or grid container.
function items(value: string): StyleRuleCSS property: align-items
import { cx, items } from 'typewritingclass'
cx(items('center')) // align-items: centercx(items('flex-start')) // align-items: flex-startcx(items('stretch')) // align-items: stretchcx(items('baseline')) // align-items: baselinejustify()
Sets the justify-content property on a flex or grid container.
function justify(value: string): StyleRuleCSS property: justify-content
import { cx, justify } from 'typewritingclass'
cx(justify('center')) // justify-content: centercx(justify('space-between')) // justify-content: space-betweencx(justify('flex-end')) // justify-content: flex-endcx(justify('space-around')) // justify-content: space-aroundself()
Sets the align-self property on a flex or grid child.
function self(value: string): StyleRuleCSS property: align-self
import { cx, self } from 'typewritingclass'
cx(self('center')) // align-self: centercx(self('flex-start')) // align-self: flex-startcx(self('stretch')) // align-self: stretchoverflow()
Sets the overflow behavior on both axes.
function overflow(value: string): StyleRuleCSS property: overflow
import { cx, overflow } from 'typewritingclass'
cx(overflow('hidden')) // overflow: hiddencx(overflow('auto')) // overflow: autocx(overflow('scroll')) // overflow: scrollcx(overflow('visible')) // overflow: visibleoverflowX()
Sets the horizontal overflow behavior.
function overflowX(value: string): StyleRuleCSS property: overflow-x
import { cx, overflowX } from 'typewritingclass'
cx(overflowX('auto')) // overflow-x: autocx(overflowX('hidden')) // overflow-x: hiddencx(overflowX('scroll')) // overflow-x: scrolloverflowY()
Sets the vertical overflow behavior.
function overflowY(value: string): StyleRuleCSS property: overflow-y
import { cx, overflowY } from 'typewritingclass'
cx(overflowY('auto')) // overflow-y: autocx(overflowY('hidden')) // overflow-y: hiddencx(overflowY('scroll')) // overflow-y: scrollrelative()
Sets the element to position: relative.
function relative(): StyleRuleCSS property: position: relative
import { cx, relative } from 'typewritingclass'
cx(relative())// position: relativeabsolute()
Sets the element to position: absolute.
function absolute(): StyleRuleCSS property: position: absolute
import { cx, absolute, top, left } from 'typewritingclass'
cx(absolute(), top(0), left(0))// position: absolute; top: 0px; left: 0pxfixed()
Sets the element to position: fixed.
function fixed(): StyleRuleCSS property: position: fixed
import { cx, fixed, top, inset } from 'typewritingclass'
cx(fixed(), top(0))// position: fixed; top: 0px
cx(fixed(), inset(0))// position: fixed; inset: 0pxsticky()
Sets the element to position: sticky.
function sticky(): StyleRuleCSS property: position: sticky
import { cx, sticky, top, z } from 'typewritingclass'
cx(sticky(), top(0), z(10))// position: sticky; top: 0px; z-index: 10top()
Sets the top position offset.
function top(value: number | string | DynamicValue): StyleRuleCSS property: top
import { cx, top } from 'typewritingclass'
cx(top(0)) // top: 0pxcx(top(4)) // top: 1remcx(top('50%')) // top: 50%right()
Sets the right position offset.
function right(value: number | string | DynamicValue): StyleRuleCSS property: right
import { cx, right } from 'typewritingclass'
cx(right(0)) // right: 0pxcx(right(4)) // right: 1remcx(right('0')) // right: 0bottom()
Sets the bottom position offset.
function bottom(value: number | string | DynamicValue): StyleRuleCSS property: bottom
import { cx, bottom } from 'typewritingclass'
cx(bottom(0)) // bottom: 0pxcx(bottom('2rem')) // bottom: 2remleft()
Sets the left position offset.
function left(value: number | string | DynamicValue): StyleRuleCSS property: left
import { cx, left } from 'typewritingclass'
cx(left(4)) // left: 1remcx(left('50%')) // left: 50%inset()
Sets the inset shorthand property (top, right, bottom, left).
function inset(value: number | string | DynamicValue): StyleRuleCSS property: inset
import { cx, inset } from 'typewritingclass'
cx(inset(0)) // inset: 0pxcx(inset('0')) // inset: 0z()
Sets the z-index stacking order.
function z(value: number | string | DynamicValue): StyleRuleCSS property: z-index
Numeric values are converted to strings. Also accepts string values like 'auto'.
import { cx, z } from 'typewritingclass'
cx(z(10)) // z-index: 10cx(z(50)) // z-index: 50cx(z(-1)) // z-index: -1cx(z('auto')) // z-index: autoBorders
rounded()
Sets the border-radius on all corners.
function rounded(value?: string | DynamicValue): StyleRule| Parameter | Type | Default | Description |
|---|---|---|---|
value | string | DynamicValue | undefined | '0.25rem' | CSS border-radius string or dynamic() value. |
CSS property: border-radius
When called without arguments, uses the default border radius of 0.25rem.
import { cx, rounded } from 'typewritingclass'import { lg, full, none } from 'typewritingclass/theme/borders'
cx(rounded()) // border-radius: 0.25remcx(rounded('0.5rem')) // border-radius: 0.5remcx(rounded(lg)) // border-radius: 0.5remcx(rounded(full)) // border-radius: 9999px (pill/circle)cx(rounded(none)) // border-radius: 0pxcx(rounded('9999px')) // border-radius: 9999pxroundedT()
Sets the border-radius on the top-left and top-right corners.
function roundedT(value?: string | DynamicValue): StyleRuleCSS properties: border-top-left-radius, border-top-right-radius
import { cx, roundedT } from 'typewritingclass'
cx(roundedT()) // border-top-left-radius: 0.25rem; border-top-right-radius: 0.25remcx(roundedT('1rem')) // border-top-left-radius: 1rem; border-top-right-radius: 1remroundedB()
Sets the border-radius on the bottom-left and bottom-right corners.
function roundedB(value?: string | DynamicValue): StyleRuleCSS properties: border-bottom-left-radius, border-bottom-right-radius
import { cx, roundedB } from 'typewritingclass'
cx(roundedB()) // border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25remcx(roundedB('1rem')) // border-bottom-left-radius: 1rem; border-bottom-right-radius: 1remroundedL()
Sets the border-radius on the top-left and bottom-left corners.
function roundedL(value?: string | DynamicValue): StyleRuleCSS properties: border-top-left-radius, border-bottom-left-radius
import { cx, roundedL } from 'typewritingclass'
cx(roundedL()) // border-top-left-radius: 0.25rem; border-bottom-left-radius: 0.25remcx(roundedL('0.75rem')) // border-top-left-radius: 0.75rem; border-bottom-left-radius: 0.75remroundedR()
Sets the border-radius on the top-right and bottom-right corners.
function roundedR(value?: string | DynamicValue): StyleRuleCSS properties: border-top-right-radius, border-bottom-right-radius
import { cx, roundedR } from 'typewritingclass'
cx(roundedR()) // border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25remcx(roundedR('0.75rem')) // border-top-right-radius: 0.75rem; border-bottom-right-radius: 0.75remborder()
Sets a solid border on all sides.
function border(width?: string): StyleRule| Parameter | Type | Default | Description |
|---|---|---|---|
width | string | undefined | '1px' | CSS border-width string. |
CSS properties: border-width, border-style: solid
import { cx, border } from 'typewritingclass'
cx(border()) // border-width: 1px; border-style: solidcx(border('2px')) // border-width: 2px; border-style: solidcx(border('0')) // border-width: 0; border-style: solidborderT()
Sets a solid border on the top side.
function borderT(width?: string): StyleRuleCSS properties: border-top-width, border-style: solid
import { cx, borderT } from 'typewritingclass'
cx(borderT()) // border-top-width: 1px; border-style: solidcx(borderT('2px')) // border-top-width: 2px; border-style: solidborderR()
Sets a solid border on the right side.
function borderR(width?: string): StyleRuleCSS properties: border-right-width, border-style: solid
import { cx, borderR } from 'typewritingclass'
cx(borderR()) // border-right-width: 1px; border-style: solidcx(borderR('3px')) // border-right-width: 3px; border-style: solidborderB()
Sets a solid border on the bottom side.
function borderB(width?: string): StyleRuleCSS properties: border-bottom-width, border-style: solid
import { cx, borderB } from 'typewritingclass'
cx(borderB()) // border-bottom-width: 1px; border-style: solidcx(borderB('2px')) // border-bottom-width: 2px; border-style: solidborderL()
Sets a solid border on the left side.
function borderL(width?: string): StyleRuleCSS properties: border-left-width, border-style: solid
import { cx, borderL } from 'typewritingclass'
cx(borderL()) // border-left-width: 1px; border-style: solidcx(borderL('4px')) // border-left-width: 4px; border-style: solidring()
Creates a focus-ring-style box-shadow around an element.
function ring(width?: string, color?: string): StyleRule| Parameter | Type | Default | Description |
|---|---|---|---|
width | string | undefined | '3px' | The ring width. |
color | string | undefined | '#3b82f6' | The ring color. |
CSS property: box-shadow
Produces a box-shadow with zero offset and zero blur, acting as an outline alternative that respects border-radius.
import { cx, ring } from 'typewritingclass'
cx(ring()) // box-shadow: 0 0 0 3px #3b82f6cx(ring('2px')) // box-shadow: 0 0 0 2px #3b82f6cx(ring('2px', '#ef4444')) // box-shadow: 0 0 0 2px #ef4444cx(ring('1px')) // box-shadow: 0 0 0 1px #3b82f6Combine with modifiers for focus rings:
import { cx, ring, when, focusVisible } from 'typewritingclass'
cx(when(focusVisible)(ring('2px', '#3b82f6')))// CSS: .cls:focus-visible { box-shadow: 0 0 0 2px #3b82f6; }Effects
shadow()
Sets the box-shadow of an element.
function shadow(value?: string | DynamicValue): StyleRule| Parameter | Type | Default | Description |
|---|---|---|---|
value | string | DynamicValue | undefined | Theme DEFAULT shadow | CSS box-shadow string or dynamic() value. |
CSS property: box-shadow
When called without arguments, uses the default shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1).
import { cx, shadow } from 'typewritingclass'import { sm, md, lg, xl, _2xl, inner, none } from 'typewritingclass/theme/shadows'
cx(shadow()) // Default shadowcx(shadow(sm)) // Subtle shadowcx(shadow(md)) // Moderate shadowcx(shadow(lg)) // Pronounced shadowcx(shadow(xl)) // Heavy shadowcx(shadow(_2xl)) // Most dramatic shadowcx(shadow(inner)) // Inset shadowcx(shadow(none)) // Remove shadowcx(shadow('none')) // Remove shadow (raw string)Shadow with hover effect:
import { cx, shadow, when, hover } from 'typewritingclass'import { md, lg } from 'typewritingclass/theme/shadows'
cx(shadow(md), when(hover)(shadow(lg)))opacity()
Sets the opacity of an element.
function opacity(value: number | DynamicValue): StyleRuleCSS property: opacity
The numeric value (between 0 and 1) is converted to a string.
import { cx, opacity } from 'typewritingclass'
cx(opacity(1)) // opacity: 1cx(opacity(0.5)) // opacity: 0.5cx(opacity(0)) // opacity: 0cx(opacity(0.75)) // opacity: 0.75With modifiers:
import { cx, opacity, when, hover, disabled } from 'typewritingclass'
cx(opacity(1), when(hover)(opacity(0.8)), when(disabled)(opacity(0.5)))backdrop()
Sets the backdrop-filter CSS property.
function backdrop(value: string | DynamicValue): StyleRuleCSS property: backdrop-filter
Applies graphical effects (blurring, color shifting) to the area behind the element.
import { cx, backdrop } from 'typewritingclass'
cx(backdrop('blur(8px)')) // backdrop-filter: blur(8px)cx(backdrop('saturate(180%)')) // backdrop-filter: saturate(180%)cx(backdrop('blur(12px) saturate(150%)')) // backdrop-filter: blur(12px) saturate(150%)Interactivity
cursor()
Sets the cursor style of an element.
function cursor(value: string | DynamicValue): StyleRuleCSS property: cursor
import { cx, cursor } from 'typewritingclass'
cx(cursor('pointer')) // cursor: pointercx(cursor('grab')) // cursor: grabcx(cursor('not-allowed')) // cursor: not-allowedcx(cursor('text')) // cursor: textcx(cursor('move')) // cursor: movecx(cursor('default')) // cursor: defaultselect()
Sets the user-select behavior of an element.
function select(value: string): StyleRuleCSS property: user-select
import { cx, select } from 'typewritingclass'
cx(select('none')) // user-select: nonecx(select('text')) // user-select: textcx(select('all')) // user-select: allcx(select('auto')) // user-select: autopointerEvents()
Sets the pointer-events behavior of an element.
function pointerEvents(value: string): StyleRuleCSS property: pointer-events
import { cx, pointerEvents } from 'typewritingclass'
cx(pointerEvents('none')) // pointer-events: nonecx(pointerEvents('auto')) // pointer-events: autoComposition patterns
All utilities compose naturally with each other through cx() and with modifiers through when():
Responsive layout
import { cx, flex, flexCol, flexRow, gap, p, when, md, lg } from 'typewritingclass'
const container = cx( flexCol(), gap(4), p(4), when(md)(flexRow(), gap(6), p(6)), when(lg)(gap(8), p(8)),)Interactive button
import { cx, p, px, bg, textColor, rounded, font, cursor, opacity, shadow, when, hover, active, disabled, focusVisible, ring } from 'typewritingclass'import { blue, white } from 'typewritingclass/theme/colors'import { bold } from 'typewritingclass/theme/typography'
const button = cx( px(6), p(3), bg(blue[500]), textColor(white), rounded('0.375rem'), font(bold), cursor('pointer'), shadow(), when(hover)(bg(blue[600])), when(active)(bg(blue[700])), when(focusVisible)(ring('2px', blue[400])), when(disabled)(opacity(0.5), cursor('not-allowed')),)Dynamic values
import { dcx, bg, textColor, rounded, p, dynamic } from 'typewritingclass'
function ThemedCard({ bgColor, radius }: { bgColor: string; radius: string }) { const { className, style } = dcx( p(4), bg(dynamic(bgColor)), rounded(dynamic(radius)), textColor('#111827'), ) return <div className={className} style={style} />}