Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions packages/ui/src/components/pill-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import {type PillVariant, pillVariants} from '@proxy/ui/lib/pill-variants';
/**
* The app's button: round, solid and dark for the main action, ghost for any other (Cancel), red
* (`destructive`) where it deletes or removes something. A ghost one is also a toggle's option or
* a tab, filled in where it is chosen (`aria-pressed`, or `aria-current` on a link). With a label
* it has no icon of its own; `icon` makes it an icon alone, in a circle, its label for whoever
* can't see it in `aria-label` (`IconButton` adds the tooltip). Where Enter presses it, `enter`
* puts Enter's mark after its label, as on the command bar's cards (`EnterButton`); Chat's send
* button is the mark alone, in a circle. A link drawn as one takes `pillVariants`
* (lib/pill-variants.ts, which says which corners the rest of the app has).
* a tab, filled in where it is chosen (`aria-pressed`, or `aria-current` on a link), and, unlike a
* button, not sinking as it is pressed. With a label it has no icon of its own; `icon` makes it an
* icon alone, in a circle, its label for whoever can't see it in `aria-label` (`IconButton` adds
* the tooltip). Where Enter presses it, `enter` puts Enter's mark after its label, as on the
* command bar's cards (`EnterButton`); Chat's send button is the mark alone, in a circle. A link
* drawn as one takes `pillVariants` (lib/pill-variants.ts, which says which corners the rest of
* the app has).
*/
export function PillButton({
variant = 'default',
Expand All @@ -28,7 +29,10 @@ export function PillButton({
// Enter's mark with no label: a circle around it.
const alone = enter && (children === undefined || children === null);
return (
<ButtonPrimitive className={cn(pillVariants({variant, icon: alone || icon}), className)} {...props}>
<ButtonPrimitive
className={cn(pillVariants({variant, icon: alone || icon}), className)}
{...props}
>
{children}
{enter && <EnterHint alone={alone} />}
</ButtonPrimitive>
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/src/lib/pill-variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import {cn} from '@proxy/ui/lib/utils';
export type PillVariant = 'default' | 'ghost' | 'destructive';

// Every pill: its shape, its type, its focus ring, its icons' size, and how it looks pressed,
// turned off or invalid.
// turned off or invalid. Pressed, a button sinks a pixel; a tab or a toggle's option stays put,
// only filling in.
const BASE =
"inline-flex shrink-0 items-center justify-center rounded-full border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
"inline-flex shrink-0 items-center justify-center rounded-full border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:not-[[role=tab]]:not-[[aria-pressed]]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";

// Each variant's colors. A ghost one that is chosen, a toggle's option pressed (`aria-pressed`) or a
// tab open (`aria-current` on a link, `aria-selected` in a tablist), is filled in as it is under
Expand Down
Loading