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.
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.
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 topercentopacity.shade(color, percent)- Darkens the color bypercenttoward black.tint(color, percent)- Lightens the color bypercenttoward white.
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 unresolvedvar(). - 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.
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.
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.lightin light mode,colors.darkin dark mode.darkFilledTextRule(theme)- The same choice restated as a rule scoped to adarkclass 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 alongsidefilledTextColor.
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 and Prose.
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 setsbox-sizing: border-box,cursor: pointer, andoutline: none. Since the focus outline is removed, pair it withinteractiveStylesor 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)- Returnswidth: 100%when the flag is set. Backs the$fullWidthprop 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,generateColSpanStylesgeneratePaddingStyles,generateJustifyContentStylesgenerateAlignItemsStyles,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):
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 and IconButton pages; proseStyles on the Prose page; and chatTextStyles on the Chat Messages page.