# Mixins

> Cherry's reusable CSS mixins: interaction affordances, resets, and form element helpers.

Source: https://cherry.al/code/mixins

> For the complete documentation index, see [llms.txt](https://cherry.al/llms.txt).

# Mixins

Cherry exports the CSS mixins its own components are built from, so custom elements in your app can share the exact same look and behavior. All of them are plain `styled-components` css fragments or helper functions - interpolate them into any styled component.

## interactiveStyles

The hover, focus, and active affordance used for interactive surfaces like cards, tiles, and block-level links: a transparent 1px border that picks up the primary color on hover, plus a soft focus ring. Pair it with `resetButton` for clickable elements that aren't Buttons.

```tsx
import styled from "styled-components";
import { interactiveStyles, resetButton } from "cherry-styled-components";

const ClickableCard = styled.button`
  ${resetButton}
  ${interactiveStyles}
  border-radius: 12px;
  padding: 20px;
`;
```

## errorInteractiveStyles

The destructive-action sibling of `interactiveStyles`: identical hover, focus, and active behavior, but in the theme error red (the same red the `$error` Button uses). Use it for delete and remove affordances.

```tsx
import styled from "styled-components";
import { errorInteractiveStyles, resetButton } from "cherry-styled-components";

const RemoveTile = styled.button`
  ${resetButton}
  ${errorInteractiveStyles}
  border-radius: 12px;
  padding: 20px;
`;
```

## Color helpers

Three functions for deriving a shade from a token instead of hardcoding a second hex value. Each takes a CSS color and a percentage:

- `alpha(color, percent)` - Fades the color to `percent` opacity.
- `shade(color, percent)` - Darkens the color by `percent` toward black.
- `tint(color, percent)` - Lightens the color by `percent` toward white.

```tsx
import styled from "styled-components";
import { alpha, shade, tint } from "cherry-styled-components";

const DangerZone = styled.div`
  background: ${({ theme }) => tint(theme.colors.error, 90)};
  border: solid 1px ${({ theme }) => alpha(theme.colors.error, 40)};
  color: ${({ theme }) => shade(theme.colors.error, 20)};
`;
```

They return a native CSS `color-mix(in srgb, ...)` string rather than a computed value, which means the browser does the math at paint time. Two consequences worth knowing:

- The input can be any valid CSS color, including a `var(--token)` reference. If you white-label Cherry through CSS custom properties, the helpers keep working, where a JavaScript color library would choke on the unresolved `var()`.
- The output is a CSS string, not a hex value. Interpolate it into a style declaration; do not try to parse it or feed it to something expecting `#rrggbb`.

<Callout type="info">
  `color-mix()` is supported in all current browsers (Chrome 111+, Safari 16.2+, Firefox 113+). Cherry uses these helpers internally for its own hover and focus states, so the same baseline applies to the library as a whole.
</Callout>

## Filled text helpers

Two helpers for text sitting on a brand-colored fill, extracted from the filled Button and shared by Avatar and the chat kit's user bubble:

- `filledTextColor(theme)` - The palette's contrasting end: `colors.light` in light mode, `colors.dark` in dark mode.
- `darkFilledTextRule(theme)` - The same choice restated as a rule scoped to a `dark` class on `<html>`, which is what apps resolving the mode in CSS key off before hydration can swap the theme object. Additive: with an already-dark theme object both paths resolve to the same color. Interpolate it alongside `filledTextColor`.

```tsx
import styled from "styled-components";
import { darkFilledTextRule, filledTextColor } from "cherry-styled-components";

const Badge = styled.span`
  background: ${({ theme }) => theme.colors.primary};
  color: ${({ theme }) => filledTextColor(theme)};
  ${({ theme }) => darkFilledTextRule(theme)};
`;
```

## thinScrollbar

A slim, theme-aware scrollbar for internal scroll areas - chat transcripts, code blocks, wide tables - so the chunky native bar does not stand out, especially in dark mode. Used by [ChatMessageList](/code/chat-messages) and [Prose](/code/prose).

```tsx
import styled from "styled-components";
import { thinScrollbar } from "cherry-styled-components";

const CodeScroller = styled.pre`
  overflow-x: auto;
  ${thinScrollbar};
`;
```

## Resets

- `resetButton` - Strips native button styling (appearance, border, background, padding, margin) and sets `box-sizing: border-box`, `cursor: pointer`, and `outline: none`. Since the focus outline is removed, pair it with `interactiveStyles` or provide your own focus style. The base of Button, IconButton, and ThemeToggle.
- `resetInput` - Minimal input reset used by the form components.

## Form helpers

- `fullWidthStyles(fullWidth)` - Returns `width: 100%` when the flag is set. Backs the `$fullWidth` prop across components. Unlike the other two helpers, its parameter has no `$` sigil.
- `statusBorderStyles($error, $success, theme)` - Border color for error and success validation states.
- `formElementHeightStyles($size)` - Shared height for form elements in the three sizes (`small`, `default`, `big`).

## Responsive style generators

Used internally by the layout components, and available for custom components that take per-breakpoint props:

- `generateGapStyles`, `generateColsStyles`, `generateColSpanStyles`
- `generatePaddingStyles`, `generateJustifyContentStyles`
- `generateAlignItemsStyles`, `generateAlignContentStyles`, `generateDirectionStyles`

Each takes `(size: keyof Breakpoints<number>, value)` and returns the declaration wrapped in the `mq(size)` min-width media query for that breakpoint (`xs`, `sm`, `md`, `lg`, `xl`, `xxl`, `xxxl`):

```tsx
import styled from "styled-components";
import {
  generateGapStyles,
  generateDirectionStyles,
} from "cherry-styled-components";

const Toolbar = styled.div`
  display: flex;
  ${generateGapStyles("xs", 10)}
  ${generateGapStyles("lg", 20)}
  ${generateDirectionStyles("xs", "column")}
  ${generateDirectionStyles("lg", "row")}
`;
```

The component style mixins `buttonStyles` and `iconButtonStyles` are documented on the [Button](/code/button) and [IconButton](/code/icon-button) pages; `proseStyles` on the [Prose](/code/prose) page; and `chatTextStyles` on the [Chat Messages](/code/chat-messages) page.

<Button href="https://github.com/cherry-design-system/styled-components/blob/main/src/lib/utils/mixins.tsx" icon="code" iconPosition="left">
  View Source
</Button>
