Select labels

This commit is contained in:
Oliver Bryan
2026-01-08 19:40:12 +00:00
parent cec4b0b535
commit 8cea2815e0
3 changed files with 35 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ export function OrganisationSelect({
onCreateOrganisation,
placeholder = "Select Organisation",
contentClass,
labelPosition = "top",
}: {
organisations: OrganisationResponse[];
selectedOrganisation: OrganisationResponse | null;
@@ -27,6 +28,7 @@ export function OrganisationSelect({
onCreateOrganisation?: (organisationId: number) => void | Promise<void>;
placeholder?: string;
contentClass?: string;
labelPosition?: "top" | "bottom";
}) {
const [open, setOpen] = useState(false);
@@ -43,7 +45,13 @@ export function OrganisationSelect({
}}
onOpenChange={setOpen}
>
<SelectTrigger className="text-sm" isOpen={open}>
<SelectTrigger
className="text-sm"
isOpen={open}
label="Organisation"
hasValue={!!selectedOrganisation}
labelPosition={labelPosition}
>
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent side="bottom" position="popper" className={contentClass}>

View File

@@ -20,6 +20,7 @@ export function ProjectSelect({
onSelectedProjectChange,
onCreateProject,
placeholder = "Select Project",
labelPosition = "top",
}: {
projects: ProjectResponse[];
selectedProject: ProjectResponse | null;
@@ -27,6 +28,7 @@ export function ProjectSelect({
onSelectedProjectChange: (project: ProjectResponse | null) => void;
onCreateProject?: (projectId: number) => void | Promise<void>;
placeholder?: string;
labelPosition?: "top" | "bottom";
}) {
const [open, setOpen] = useState(false);
@@ -43,7 +45,13 @@ export function ProjectSelect({
}}
onOpenChange={setOpen}
>
<SelectTrigger className="text-sm" isOpen={open}>
<SelectTrigger
className="text-sm"
isOpen={open}
label="Project"
hasValue={!!selectedProject}
labelPosition={labelPosition}
>
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent side="bottom" position="popper" align={"start"}>

View File

@@ -21,10 +21,16 @@ function SelectTrigger({
size = "default",
children,
isOpen,
label,
hasValue,
labelPosition = "top",
...props
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
isOpen?: boolean;
size?: "sm" | "default";
label?: string;
hasValue?: boolean;
labelPosition?: "top" | "bottom";
}) {
return (
<SelectPrimitive.Trigger
@@ -35,7 +41,7 @@ function SelectTrigger({
"[&_svg:not([class*='text-'])]:text-muted-foreground",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
"aria-invalid:border-destructive dark:hover:bg-muted/40",
"flex w-fit items-center justify-between gap-2 border",
"relative flex w-fit items-center justify-between gap-2 border",
"bg-transparent px-3 py-2 text-sm whitespace-nowrap",
"shadow-xs outline-none disabled:cursor-not-allowed",
"disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8",
@@ -46,6 +52,16 @@ function SelectTrigger({
)}
{...props}
>
{label && hasValue && (
<span
className={cn(
"text-muted-foreground bg-background absolute left-0.5 px-1 text-[9px] leading-none",
labelPosition === "top" ? "-top-1" : "-bottom-1",
)}
>
{label}
</span>
)}
{children}
<SelectPrimitive.Icon asChild>
<ChevronDownIcon