Files
kandev/apps/web/components/integrations/saved-query-default-button.tsx
T
2026-08-11 11:52:34 +01:00

106 lines
2.7 KiB
TypeScript

"use client";
import { IconStar } from "@tabler/icons-react";
import { DropdownMenuCheckboxItem } from "@kandev/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";
type SavedQueryDefaultControlProps = {
label: string;
isDefault: boolean;
disabled?: boolean;
pending?: boolean;
testId?: string;
onToggle: () => void;
};
function useSavedQueryDefaultPresentation(
label: string,
isDefault: boolean,
disabled: boolean,
pending: boolean,
) {
const { t } = useTranslation();
const actionLabel = t(
isDefault
? "integrations:clearSavedQueryAsDefaultView"
: "integrations:setSavedQueryAsDefaultView",
{ label },
);
return {
accessibleLabel: disabled
? t("integrations:savedQueryDefaultUpdateInProgress", { action: actionLabel })
: actionLabel,
iconClassName: cn(
"h-4 w-4",
isDefault && "fill-amber-500 text-amber-500",
pending && !isDefault && "fill-amber-500 text-amber-500 opacity-60",
pending && "animate-pulse motion-reduce:animate-none",
),
};
}
export function SavedQueryDefaultDropdownItem({
label,
isDefault,
disabled = false,
pending = false,
testId,
onToggle,
}: SavedQueryDefaultControlProps) {
const { accessibleLabel, iconClassName } = useSavedQueryDefaultPresentation(
label,
isDefault,
disabled,
pending,
);
return (
<DropdownMenuCheckboxItem
checked={isDefault}
disabled={disabled}
aria-label={accessibleLabel}
title={accessibleLabel}
data-testid={testId}
onSelect={(event) => event.preventDefault()}
onCheckedChange={() => onToggle()}
showIndicator={false}
className="h-7 min-h-7 w-7 shrink-0 cursor-pointer justify-center p-0 text-muted-foreground hover:text-foreground"
>
<IconStar className={iconClassName} />
</DropdownMenuCheckboxItem>
);
}
export function SavedQueryDefaultButton({
label,
isDefault,
disabled = false,
pending = false,
testId,
onToggle,
}: SavedQueryDefaultControlProps) {
const { accessibleLabel, iconClassName } = useSavedQueryDefaultPresentation(
label,
isDefault,
disabled,
pending,
);
return (
<button
type="button"
aria-label={accessibleLabel}
aria-pressed={isDefault}
title={accessibleLabel}
disabled={disabled}
data-testid={testId}
onClick={onToggle}
className={cn(
"flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-wait disabled:opacity-50",
"h-11 w-11",
)}
>
<IconStar className={iconClassName} />
</button>
);
}