Changelog
Cherry Styled Components is currently at version 0.2.10. The entries below are based on Keep a Changelog, and the project adheres to Semantic Versioning.
Removed
- Breaking: removed the custom
IconCheck,IconArrow, andIconCalendarexports. They were hand-rolled SVGs duplicating existing Lucide glyphs. The form controls that used them now render the built-inIconcomponent instead: the checkbox check mark usesCheck, theSelectdropdown arrow usesChevronDown, and the date/time calendar glyph usesCalendarDays. These icons now take their color fromcurrentColor(the theme's primary color, applied via CSS) rather than a hard-coded stroke. The checkbox check mark renders with a 6px stroke, and theSelectarrow now sizes to 24px to match the date/time calendar glyph. Replace any direct usage with<Icon name="Check" />,<Icon name="ChevronDown" />, or<Icon name="CalendarDays" />
Added
- AI assistant skill in
skills/cherry-design-system/: a Claude Agent Skill (SKILL.mdplusreferences/covering setup, theme tokens, the full component API, and recipes) that teaches LLMs to build with Cherry correctly, always using Cherry components for buttons and form controls, reading design values from the theme, and wiring the provider. Includes a portableAGENTS.mdfor other agents and points at the live docs (cherry.al/llms.txtand per-page.md). Documentation only, not part of the published npm package; install withnpx skills add cherry-design-system/styled-components
Changed
Accordion: the clickable title is now a native<button type="button">(with a button reset) instead of an<h3 role="button">, so it is keyboard-focusable and Enter/Space-activatable natively;aria-expandedis preserved, and a:focus-visibleoutline in the primary color was added for keyboard usersTabs: tab labels bumped tofont-weight: 700(was 600); the:focus-visiblering was retuned (cornerradius.xs→radius.lg, inset-4px→-2px)Input: removed the unusedchildrenprop fromInputProps.Inputrenders a void<input>, so any children were silently ignored; dropping it from the type turns that into a compile-time error
Fixed
Input: small-size date and time inputs now render the calendar icon at 18px instead of the default 24px, with the native::-webkit-calendar-picker-indicatorclick target repositioned to stay aligned with the visible icon
Fixed
Dropzone/AvatarDropzone: text now inherits the surrounding font family instead of pinning the theme'sfonts.text, matching thefont-family: inheritconvention used by Button, Input, Select, and Textarea. The root<button>elements setfont-family: inheritexplicitly, since buttons don't inherit fonts by default
Fixed
Toast: centered stacks no longer wrap their text prematurely. The notifications list is now a full-width strip (20px side margins) for every alignment instead of being anchored atleft: 50%, which capped its shrink-to-fit width at about half the viewport, most visibly on mobileToast: the notification strip and rows no longer swallow clicks on page content beside them;pointer-eventsis re-enabled only on the visible pill itself
Changed
- Hover styles apply on all devices again: removed the
@media (hover: hover)guards around&:hoverrules ininteractiveStyles,errorInteractiveStyles,Dropzone,AvatarDropzone,Tabs, andThemeToggle
Added
Tabs/TabContent: new tabbed-panels component with tablist/tab/tabpanel ARIA semantics, roving-tabindex arrow-key navigation (ArrowLeft/ArrowRight cycle, Home/End jump), and optional controlled selection viaactiveTab+onTabChange(defaultActiveTabfor uncontrolled use)IconButton:$activeprop for a toggle-like "on" state (primary border, translucent primary background); reflected asaria-pressedwhen set
Changed
ThemeToggle: swapped the scale hover/press effects for the sharedinteractiveStyleshover border + focus ring, and aligned the sun/moon icons exactly with the sliding knob
Added
Modal:stylepassthrough on the overlay root, complementingclassNamefor app-level restyling
Fixed
Modal: corrected the restyling guidance in the prop docs.styled(Modal)cannot forward the$-props API, since styled-components strips transient props before they reach the wrapped component; restyle by passing aclassNameand targeting the class hooks instead
Added
Modal:$hideCloseButtonprop to omit the built-in close buttonModal:classNamepassthrough on the overlay root for app-level restyling; inner parts expose stable class hooks (.modal-inner,.modal-close,.modal-title,.modal-content)Modal:role="dialog",aria-modal="true", andaria-label(from$title) on the dialog surface
Changed
- Breaking-ish:
Modalnow unmounts its children once the exit animation finishes instead of keeping them mounted (hidden) while closed. Children such as forms reset their state between openings. The enter/exit motion is unchanged visually (fade + 40px rise) but is now driven by keyframes instead of transitions useOnClickOutsidesubscribes its document listener once per mount (latest-ref pattern) instead of re-subscribing whenever callers pass inline ref arrays or callbacks
Fixed
useOnClickOutsideignores unattached (null) refs instead of suppressing the callback entirely when any ref in the array is not mounted
Added
removeNotification(id)on the toast context, returned byuseToastNotificationsalongsideaddNotification; each toast innotificationsnow carries a uniqueid- Toast stack is an
aria-live="polite"region, so screen readers announce new toasts
Changed
- Toast internals reworked: state and variants are typed
$props on a newStyledNotificationIteminstead of className strings, each toast manages its own enter/exit lifecycle, and the space collapse animates the toast's real height viagrid-template-rowsinstead of amax-heightguess, so entering and exiting toasts glide instead of snapping - Bottom-anchored toasts (
$bottom) slide up from below instead of dropping down from above
Fixed
- Dismissed and auto-hidden toasts are removed from state and the DOM after their exit animation instead of accumulating invisibly forever
Added
ThemeTogglecomponent: a pill-shaped sun/moon switch for light and dark modeClientThemeProvider: SSR-aware theme provider with flash-free dark mode. Renders the server-resolved theme on first paint, reconciles against thethemecookie and OS preference on mount, persists changes to cookie and localStorage (no API route needed), migrates legacy localStorage-only preferences, and keeps the htmldarkclass andtheme-colormeta tag in sync. Supports$initial,$themeColor, and$globalStylespropsthemeInitScriptandcreateThemeInitScript(darkBackground): blocking head script that seeds thethemecookie and prevents the dark-mode flash in browsers without color-scheme client hints (Safari, Firefox). Exported from a server-safe module so it can be used in server componentsresolveTheme(cookieValue, theme, themeDark)helper for resolving thethemecookie to a theme object in server codetoggleTheme()onThemeContext, provided by both theme providersinteractiveStylesanderrorInteractiveStylesmixins: hover/focus/active border + focus ring treatment for interactive surfaces, in the primary color and the error red respectively
Added
IconButtoncomponent for icon-only actionsPasswordcomponent with visibility toggleModalcomponentToastcomponent with theme-aware shadowsAccordioncomponentDropzoneandAvatarDropzonecomponents for file uploads
Added
- Responsive
$alignItems,$alignContent, and per-breakpoint$directionprops onFlex, backed by newgenerateAlignItemsStyles,generateAlignContentStyles, andgenerateDirectionStylesmixins
0.1.17 and earlier
Changes prior to 0.1.18 were not tracked in this changelog. See the git history for details.