diff --git a/packages/ui/package.json b/packages/ui/package.json index 3013b93c..c95dac7f 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/ui", - "version": "0.1.5", + "version": "0.1.6", "type": "module", "scripts": { "storybook": "storybook dev -p 6006", diff --git a/packages/ui/src/components/CardButton.tsx b/packages/ui/src/components/CardButton.tsx new file mode 100644 index 00000000..6d462a4d --- /dev/null +++ b/packages/ui/src/components/CardButton.tsx @@ -0,0 +1,71 @@ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { clsx } from 'clsx'; + +/** + * CardButton — a button-shaped CARD that allows stacked, multi-line content. + * + * The {@link Button} primitive applies `whitespace-nowrap` and a fixed + * `h-{size}` because it's tuned for single-line CTAs (Save, Cancel, Submit). + * When you put two stacked spans inside it (e.g. a title + a description), + * the second collapses or overflows the fixed height. This is by design — + * Button is the wrong primitive for picker/option/action *cards*. + * + * CardButton drops those constraints and gives you: + * - `display: block` (or flex via `as-child`) + * - `white-space: normal` so text wraps + * - `height: auto` so any number of stacked rows work + * - the same focus-visible ring as Button (keyboard a11y preserved) + * - `disabled` opacity behavior + * + * Use it whenever a `