Skip to content

Commit c526a8f

Browse files
author
prostarz
committed
feat(ui): add chevrons to dropdowns
1 parent 1a06c2b commit c526a8f

File tree

5 files changed

+110
-14
lines changed

5 files changed

+110
-14
lines changed

src/components/buttonWithIcon.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { cn } from "@/lib";
2+
import React, { ButtonHTMLAttributes, forwardRef } from "react";
3+
import { Button } from "./ui/button";
4+
5+
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
6+
startIcon?: React.ReactElement;
7+
endIcon?: React.ReactElement;
8+
divClassName?: string;
9+
}
10+
11+
export const ButtonWithIcon = forwardRef<HTMLButtonElement, Props>(
12+
(
13+
{ className, type, startIcon, endIcon, divClassName, children, ...props },
14+
ref
15+
) => {
16+
const StartIcon = startIcon;
17+
const EndIcon = endIcon;
18+
19+
return (
20+
<Button
21+
className={cn(
22+
"flex items-center relative overflow-hidden justify-center w-full px-4",
23+
className
24+
)}
25+
ref={ref}
26+
{...props}
27+
>
28+
{StartIcon && (
29+
<div className="absolute left-1.5 top-1/2 transform -translate-y-1/2 text-muted-foreground">
30+
{startIcon}
31+
</div>
32+
)}
33+
34+
<span
35+
className={cn("truncate capitalize", {
36+
"pl-6": startIcon,
37+
"pr-6": endIcon,
38+
})}
39+
>
40+
{children}
41+
</span>
42+
43+
{EndIcon && (
44+
<div className="absolute transform -translate-y-1/2 right-3 top-1/2 text-muted-foreground">
45+
{endIcon}
46+
</div>
47+
)}
48+
</Button>
49+
);
50+
}
51+
);

src/features/settings/components/tabs/accounts/addAccountButton.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button } from "@/components/ui/button";
1+
import { ButtonWithIcon } from "@/components/buttonWithIcon";
22
import { Dialog } from "@/components/ui/dialog";
33
import {
44
DropdownMenu,
@@ -10,18 +10,32 @@ import {
1010
} from "@/components/ui/dropdown-menu";
1111
import RealDebridDialogContent from "@/features/realDebrid/components/realDebridDialogContent";
1212
import TorBoxDialogContent from "@/features/torBox/components/torBoxDialogContent";
13+
import { cn } from "@/lib";
1314
import { useAccountServices } from "@/stores/account-services";
15+
import { ChevronDown } from "lucide-react";
1416
import { useState } from "react";
1517

1618
const AddAccountButton = () => {
1719
const [isRealDebridDialogOpen, setIsRealDebridDialogOpen] = useState(false);
1820
const [isTorBoxDialogOpen, setIsTorBoxDialogOpen] = useState(false);
21+
const [open, setOpen] = useState(false);
1922
const { realDebrid, torBox } = useAccountServices();
2023

2124
return (
22-
<DropdownMenu>
25+
<DropdownMenu open={open} onOpenChange={setOpen}>
2326
<DropdownMenuTrigger asChild>
24-
<Button>Add Account</Button>
27+
<ButtonWithIcon
28+
endIcon={
29+
<ChevronDown
30+
className={cn("transition-all overflow-hidden truncate w-full", {
31+
"rotate-180": open,
32+
"rotate-0": !open,
33+
})}
34+
/>
35+
}
36+
>
37+
Add Account
38+
</ButtonWithIcon>
2539
</DropdownMenuTrigger>
2640
<DropdownMenuContent align="start">
2741
<DropdownMenuLabel>Choose an account</DropdownMenuLabel>

src/features/settings/components/tabs/accounts/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ const AccountSettings = () => {
1818

1919
<SettingsContainer>
2020
<SettingsSection>
21-
<div className="flex gap-4">
22-
<AddAccountButton />
21+
<div className="flex gap-2">
22+
<div className="w-2/12">
23+
<AddAccountButton />
24+
</div>
2325
<div className="flex items-center space-x-2">
2426
<Switch
2527
id="use-accounts-for-downloads"

src/features/settings/components/tabs/general/settings/language.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button } from "@/components/ui/button";
1+
import { ButtonWithIcon } from "@/components/buttonWithIcon";
22
import {
33
DropdownMenu,
44
DropdownMenuCheckboxItem,
@@ -9,11 +9,14 @@ import {
99
} from "@/components/ui/dropdown-menu";
1010
import { useLanguageContext } from "@/contexts/I18N";
1111
import { useSettings } from "@/hooks";
12-
import { useMemo } from "react";
12+
import { cn } from "@/lib";
13+
import { ChevronDown } from "lucide-react";
14+
import { useMemo, useState } from "react";
1315

1416
const LanguageDropdown = () => {
1517
const { languages, i18n } = useLanguageContext();
1618
const { settings, updateSetting } = useSettings();
19+
const [open, setOpen] = useState(false);
1720

1821
const currentLanguage = useMemo(() => {
1922
return Object.entries(languages).find(([key, _value]) => {
@@ -23,12 +26,23 @@ const LanguageDropdown = () => {
2326
}, [languages, settings.language, i18n.language]);
2427

2528
return (
26-
<DropdownMenu>
29+
<DropdownMenu open={open} onOpenChange={setOpen}>
2730
<DropdownMenuTrigger asChild>
28-
<Button className="w-full">{currentLanguage?.[1].nativeName}</Button>
31+
<ButtonWithIcon
32+
endIcon={
33+
<ChevronDown
34+
className={cn("transition-all overflow-hidden truncate w-full", {
35+
"rotate-180": open,
36+
"rotate-0": !open,
37+
})}
38+
/>
39+
}
40+
>
41+
{currentLanguage?.[1].nativeName}
42+
</ButtonWithIcon>
2943
</DropdownMenuTrigger>
3044

31-
<DropdownMenuContent className="w-64" align="start">
45+
<DropdownMenuContent className="w-64" align="start" side="bottom">
3246
<DropdownMenuLabel>Choose Language</DropdownMenuLabel>
3347
<DropdownMenuSeparator />
3448
{Object.entries(languages).map(([key, value]) => (

src/features/settings/components/tabs/general/settings/title-bar.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SettingsTitleBarStyle } from "@/@types";
2-
import { Button } from "@/components/ui/button";
2+
import { ButtonWithIcon } from "@/components/buttonWithIcon";
33
import {
44
DropdownMenu,
55
DropdownMenuContent,
@@ -10,16 +10,31 @@ import {
1010
DropdownMenuTrigger,
1111
} from "@/components/ui/dropdown-menu";
1212
import { useSettings } from "@/hooks";
13+
import { cn } from "@/lib";
14+
import { ChevronDown } from "lucide-react";
15+
import { useState } from "react";
1316

1417
const TitleBarDropdown = () => {
1518
const { settings, updateSetting } = useSettings();
19+
const [open, setOpen] = useState(false);
1620

1721
return (
18-
<DropdownMenu>
22+
<DropdownMenu open={open} onOpenChange={setOpen}>
1923
<DropdownMenuTrigger asChild>
20-
<Button className="w-full capitalize">{settings?.titleBarStyle}</Button>
24+
<ButtonWithIcon
25+
endIcon={
26+
<ChevronDown
27+
className={cn("transition-all overflow-hidden truncate w-full", {
28+
"rotate-180": open,
29+
"rotate-0": !open,
30+
})}
31+
/>
32+
}
33+
>
34+
{settings?.titleBarStyle}
35+
</ButtonWithIcon>
2136
</DropdownMenuTrigger>
22-
<DropdownMenuContent className="w-64">
37+
<DropdownMenuContent className="w-64" side="bottom">
2338
<DropdownMenuLabel>Title Bar Style</DropdownMenuLabel>
2439
<DropdownMenuSeparator />
2540
<DropdownMenuRadioGroup

0 commit comments

Comments
 (0)