Add missing variants on TextField and Select
Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -48,6 +48,27 @@ export function Default() {
|
||||
);
|
||||
}
|
||||
|
||||
export function Variants() {
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
{(["classic", "surface", "soft", "ghost"] as const).map(variant => (
|
||||
<div key={variant} className="w-40">
|
||||
<Select>
|
||||
<SelectTrigger variant={variant} placeholder={variant}>
|
||||
{(value: string | null) => (value ? fruits[value] : null)}
|
||||
</SelectTrigger>
|
||||
<SelectPopup>
|
||||
{Object.entries(fruits).map(([value, label]) => (
|
||||
<SelectItem key={value} value={value}>{label}</SelectItem>
|
||||
))}
|
||||
</SelectPopup>
|
||||
</Select>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Controlled() {
|
||||
const [value, setValue] = useState<string | null>(null);
|
||||
return (
|
||||
|
||||
@@ -23,6 +23,8 @@ export type SelectTriggerProps
|
||||
& {
|
||||
className?: string;
|
||||
size?: 1 | 2;
|
||||
// Surface treatment (defaults to "surface").
|
||||
variant?: "classic" | "surface" | "soft" | "ghost";
|
||||
// Shown when no value is selected.
|
||||
placeholder?: ReactNode;
|
||||
// Renders the selected value; pass a function to map a value to its label.
|
||||
@@ -32,8 +34,8 @@ export type SelectTriggerProps
|
||||
// The bordered surface button that opens the popup, showing the selected value
|
||||
// (or placeholder) and a trailing chevron.
|
||||
export function SelectTrigger(props: SelectTriggerProps) {
|
||||
const { className, size, placeholder, children, ...rest } = props;
|
||||
const { trigger, value, icon } = selectTrigger({ size });
|
||||
const { className, size, variant, placeholder, children, ...rest } = props;
|
||||
const { trigger, value, icon } = selectTrigger({ size, variant });
|
||||
|
||||
return (
|
||||
<BaseSelect.Trigger className={trigger({ className })} {...rest}>
|
||||
|
||||
@@ -20,8 +20,8 @@ import { tv } from "tailwind-variants/lite";
|
||||
export const selectTrigger = tv({
|
||||
slots: {
|
||||
trigger: [
|
||||
"flex w-full items-center justify-between gap-2 rounded-2 border border-sand-a7 bg-sand-1 text-2 text-sand-12",
|
||||
"cursor-pointer outline-none transition-colors hover:bg-sand-2",
|
||||
"flex w-full items-center justify-between gap-2 rounded-2 text-2 text-sand-12",
|
||||
"cursor-pointer outline-none transition-colors",
|
||||
"focus-visible:ring-2 focus-visible:ring-sand-8 focus-visible:ring-offset-1 focus-visible:ring-offset-sand-1",
|
||||
"data-disabled:pointer-events-none data-disabled:opacity-50 data-placeholder:text-sand-a10",
|
||||
],
|
||||
@@ -33,9 +33,19 @@ export const selectTrigger = tv({
|
||||
1: { trigger: "h-7 px-2" },
|
||||
2: { trigger: "h-8 px-3" },
|
||||
},
|
||||
// Surface treatment. Only the accent (gold) color ships, matching Figma;
|
||||
// classic adds a recessed inset shadow (Figma can't express its gradient),
|
||||
// soft drops the border for a tint, ghost is transparent until hover.
|
||||
variant: {
|
||||
classic: { trigger: "border border-sand-a7 bg-sand-1 inset-shadow-2 hover:bg-sand-2" },
|
||||
surface: { trigger: "border border-sand-a7 bg-sand-1 hover:bg-sand-2" },
|
||||
soft: { trigger: "bg-gold-3 hover:bg-gold-4" },
|
||||
ghost: { trigger: "hover:bg-sand-2" },
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: 2,
|
||||
variant: "surface",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -39,6 +39,16 @@ export function WithIcon() {
|
||||
);
|
||||
}
|
||||
|
||||
export function Variants() {
|
||||
return (
|
||||
<div className="flex w-60 flex-col gap-3">
|
||||
<TextField variant="classic" icon={<MagnifyingGlassIcon />} placeholder="Classic" />
|
||||
<TextField variant="surface" icon={<MagnifyingGlassIcon />} placeholder="Surface" />
|
||||
<TextField variant="soft" icon={<MagnifyingGlassIcon />} placeholder="Soft" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Controlled() {
|
||||
const [value, setValue] = useState("");
|
||||
return (
|
||||
|
||||
@@ -23,6 +23,8 @@ export type TextFieldProps
|
||||
// Applied to the bordered container (the top-level element).
|
||||
className?: string;
|
||||
size?: 1 | 2;
|
||||
// Surface treatment (defaults to "surface").
|
||||
variant?: "classic" | "surface" | "soft";
|
||||
// Leading icon slot (e.g. a MagnifyingGlassIcon for search).
|
||||
icon?: ReactNode;
|
||||
};
|
||||
@@ -31,8 +33,8 @@ export type TextFieldProps
|
||||
// node; all native input props spread onto the inner control. Controlled with
|
||||
// Base UI's `value` / `onValueChange` (or native `value` / `onChange`).
|
||||
export function TextField(props: TextFieldProps) {
|
||||
const { className, size, icon, ...inputProps } = props;
|
||||
const { root, icon: iconSlot, input } = textField({ size });
|
||||
const { className, size, variant, icon, ...inputProps } = props;
|
||||
const { root, icon: iconSlot, input } = textField({ size, variant });
|
||||
|
||||
return (
|
||||
<div className={root({ className })}>
|
||||
|
||||
@@ -19,7 +19,7 @@ import { tv } from "tailwind-variants/lite";
|
||||
export const textField = tv({
|
||||
slots: {
|
||||
root: [
|
||||
"flex items-center gap-2 rounded-2 border border-sand-a5 bg-sand-1 text-2 text-sand-12 transition-colors",
|
||||
"flex items-center gap-2 rounded-2 text-2 text-sand-12 transition-colors",
|
||||
"focus-within:ring-2 focus-within:ring-sand-8 focus-within:ring-offset-1 focus-within:ring-offset-sand-1",
|
||||
"has-[input:disabled]:pointer-events-none has-[input:disabled]:opacity-50",
|
||||
],
|
||||
@@ -31,9 +31,17 @@ export const textField = tv({
|
||||
1: { root: "h-7 px-2" },
|
||||
2: { root: "h-8 px-2" },
|
||||
},
|
||||
// Surface treatment. Only the accent (gold) color ships, matching Figma;
|
||||
// classic adds a recessed inset shadow, soft drops the border for a tint.
|
||||
variant: {
|
||||
classic: { root: "border border-sand-a5 bg-sand-1 inset-shadow-2" },
|
||||
surface: { root: "border border-sand-a5 bg-sand-1" },
|
||||
soft: { root: "bg-gold-3" },
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: 2,
|
||||
variant: "surface",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user