@payfit/unity-components
Version:
140 lines (109 loc) • 4.27 kB
Markdown
# Unity layout and styling patterns
### Flex for 1D, Grid for 2D
`Flex` is for one-dimensional rows/columns; `Grid` is for the 12-column (or 6-column)
two-dimensional layout. Each exposes layout props; everything else goes via
`className` with `uy:` utilities.
```tsx
import { Flex, FlexItem, Grid, GridItem } from '@payfit/unity-components'
// Flex props: asElement, inline, direction, isReversed, wrap,
// gap, gapX, gapY, justify, align, alignContent, className
<Flex direction="row" gap="200" justify="between" align="center">
<FlexItem grow="1">Left</FlexItem>
<FlexItem>Right</FlexItem>
</Flex>
// Grid props: asElement, inline, cols (6 | 12), rows, areas, flow,
// justifyItems, alignItems, className
// GridItem positions via colSpan/colStart/colEnd OR area (mutually exclusive)
<Grid cols={12} className="uy:gap-200">
<GridItem colSpan={8}>Main</GridItem>
<GridItem colSpan={4}>Aside</GridItem>
</Grid>
```
### Responsive classes via uy:md:
There is no responsive prop-object API. Responsive behavior is driven by
TailwindCSS v4 modifiers on `className`.
```tsx
<Flex gap="100" className="uy:md:gap-200 uy:lg:gap-300">
<span>Item</span>
</Flex>
<Grid cols={12} className="uy:grid-cols-1 uy:md:grid-cols-2 uy:lg:grid-cols-3" />
```
### Variants with uyTv
`uyTv` from `@payfit/unity-themes` is the pre-configured tailwind-variants
factory. It applies the Unity `twMergeConfig` so variant collisions resolve
against Unity tokens. Export the variant function and derive its typed props
with `VariantProps`.
```tsx
import type { VariantProps } from '@payfit/unity-themes'
import { uyTv } from '@payfit/unity-themes'
export const callout = uyTv({
base: 'uy:inline-flex uy:items-center uy:gap-100 uy:rounded-100 uy:px-200 uy:py-100',
variants: {
intent: {
info: 'uy:bg-surface-primary-default uy:text-content-inverted-default',
danger: 'uy:bg-surface-danger-default uy:text-content-inverted-default',
neutral: 'uy:bg-surface-neutral-default uy:text-content-neutral-default',
},
size: {
sm: 'uy:typography-body-small',
md: 'uy:typography-body',
},
},
defaultVariants: { intent: 'info', size: 'md' },
})
export type CalloutVariantProps = VariantProps<typeof callout>
```
### Class merging with uyMerge
`uyMerge` is `tailwind-merge` configured with Unity's class groups. Use it
whenever an external `className` may collide with internal classes.
```tsx
import { uyMerge } from '@payfit/unity-themes'
uyMerge('uy:p-100', 'uy:p-200') // → 'uy:p-200'
uyMerge('uy:bg-surface-primary-default', 'uy:bg-surface-danger-default')
// → 'uy:bg-surface-danger-default'
uyMerge('uy:p-100', 'uy:px-200', 'uy:py-300') // p, px, py don't collide
```
### Conditional classes with cn / classNames / clsx
`cn`, `classNames`, and `clsx` are aliases for the same Unity-configured helper
in `@payfit/unity-themes`. Use them for ad-hoc conditional strings — not for
component-scoped variant APIs.
```tsx
import { cn } from '@payfit/unity-themes'
function Row({
isActive,
className,
}: {
isActive: boolean
className?: string
}) {
return (
<div
className={cn(
'uy:flex uy:items-center uy:px-200 uy:py-100',
isActive && 'uy:bg-surface-primary-default',
className,
)}
/>
)
}
```
### Typography with `<Text>`
Use `<Text variant=...>` instead of a `<div>` + typography class. `Text`
picks a semantic element from the variant (e.g. `variant="h1"` → `<h1>`),
applies the typography variant, and exposes `color`, `isTruncated`,
`lineClamp`, and `maxWidthCh`.
```tsx
import { Text } from '@payfit/unity-components'
<Text variant="h1" color="content.primary">Title</Text>
<Text variant="body" color="content.neutral">Description</Text>
// Override the semantic element when needed:
<Text variant="h1" asElement="h2">Visual h1, semantic h2</Text>
```
### Data-attribute pseudo-states
Several Unity components expose internal state via `data-hovered`,
`data-pressed`, `data-focus-visible`, etc. Target the component-owned state
attribute rather than the native CSS pseudo-state.
```tsx
import { ListViewItem } from '@payfit/unity-components'
;<ListViewItem className="uy:data-[hovered=true]:bg-surface-primary-hover" />
```