Skip to content

Commit 4190be7

Browse files
committed
Adding the appearance toggle and updates
1 parent 65f0561 commit 4190be7

File tree

16 files changed

+369
-106
lines changed

16 files changed

+369
-106
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ npx shadcn@latest add button
117117
You'll now have a button component in your `resources/js/Components/ui` folder. You can then use the button component inside of any page.
118118

119119
```tsx
120-
import { Button } from "@/components/ui/button"
120+
import { Button } from "@/Components/ui/button"
121121

122122
export default function Home() {
123123
return (

package-lock.json

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
"@radix-ui/react-select": "^2.1.4",
3232
"@radix-ui/react-separator": "^1.1.1",
3333
"@radix-ui/react-slot": "^1.1.1",
34+
"@radix-ui/react-toggle": "^1.1.1",
35+
"@radix-ui/react-toggle-group": "^1.1.1",
3436
"@radix-ui/react-tooltip": "^1.1.5",
3537
"class-variance-authority": "^0.7.1",
3638
"clsx": "^2.1.1",

resources/css/app.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
--chart-5: 340 75% 55%;
6767
--sidebar-background: 240 5.9% 10%;
6868
--sidebar-foreground: 240 4.8% 95.9%;
69-
--sidebar-primary: 224.3 76.3% 48%;
69+
--sidebar-primary: 6, 72%, 55%;
7070
--sidebar-primary-foreground: 0 0% 100%;
7171
--sidebar-accent: 240 3.7% 15.9%;
7272
--sidebar-accent-foreground: 240 4.8% 95.9%;

resources/js/Components/AppSidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const footerNavItems: NavItem[] = [
3434

3535
export function AppSidebar() {
3636
return (
37-
<Sidebar variant="inset" collapsible="offcanvas">
37+
<Sidebar variant="sidebar" collapsible="icon">
3838
<SidebarHeader>
3939
<SidebarMenu>
4040
<SidebarMenuItem>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { HTMLAttributes } from 'react';
2+
import { Button } from "@/Components/ui/button";
3+
import {
4+
DropdownMenu,
5+
DropdownMenuContent,
6+
DropdownMenuItem,
7+
DropdownMenuTrigger,
8+
} from "@/Components/ui/dropdown-menu";
9+
import { Sun, Moon, Monitor } from 'lucide-react';
10+
import { useAppearance } from '@/hooks/use-appearance';
11+
12+
interface AppearanceToggleDropdownProps extends HTMLAttributes<HTMLDivElement> {}
13+
14+
export default function AppearanceToggleDropdown({ className = '', ...props }: AppearanceToggleDropdownProps) {
15+
const { appearance, updateAppearance } = useAppearance();
16+
17+
const getCurrentIcon = () => {
18+
switch (appearance) {
19+
case 'dark': return <Moon className="h-5 w-5" />;
20+
case 'light': return <Sun className="h-5 w-5" />;
21+
default: return <Monitor className="h-5 w-5" />;
22+
}
23+
};
24+
25+
return (
26+
<div className={className} {...props}>
27+
<DropdownMenu>
28+
<DropdownMenuTrigger asChild>
29+
<Button variant="ghost" size="icon" className="h-9 w-9 rounded-md">
30+
{getCurrentIcon()}
31+
<span className="sr-only">Toggle theme</span>
32+
</Button>
33+
</DropdownMenuTrigger>
34+
<DropdownMenuContent align="end" rounded="xl">
35+
<DropdownMenuItem onClick={() => updateAppearance('light')}>
36+
<span className="flex items-center gap-2">
37+
<Sun className="h-5 w-5" />
38+
Light
39+
</span>
40+
</DropdownMenuItem>
41+
<DropdownMenuItem onClick={() => updateAppearance('dark')}>
42+
<span className="flex items-center gap-2">
43+
<Moon className="h-5 w-5" />
44+
Dark
45+
</span>
46+
</DropdownMenuItem>
47+
<DropdownMenuItem onClick={() => updateAppearance('system')}>
48+
<span className="flex items-center gap-2">
49+
<Monitor className="h-5 w-5" />
50+
System
51+
</span>
52+
</DropdownMenuItem>
53+
</DropdownMenuContent>
54+
</DropdownMenu>
55+
</div>
56+
);
57+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { HTMLAttributes } from 'react';
2+
import { Sun, Moon, Monitor } from 'lucide-react';
3+
import { useAppearance } from '@/hooks/use-appearance';
4+
5+
interface AppearanceToggleTabProps extends HTMLAttributes<HTMLDivElement> {}
6+
7+
export default function AppearanceToggleTab({ className = '', ...props }: AppearanceToggleTabProps) {
8+
const { appearance, updateAppearance } = useAppearance();
9+
10+
const tabs = [
11+
{ value: 'light', icon: Sun, label: 'Light' },
12+
{ value: 'dark', icon: Moon, label: 'Dark' },
13+
{ value: 'system', icon: Monitor, label: 'System' }
14+
];
15+
16+
return (
17+
<div className={`inline-flex bg-neutral-100 dark:bg-neutral-800 p-1 gap-1 rounded-lg ${className}`} {...props}>
18+
{tabs.map(({ value, icon: Icon, label }) => (
19+
<button
20+
key={value}
21+
onClick={() => updateAppearance(value)}
22+
className={`
23+
flex items-center px-3.5 py-1.5 rounded-md transition-colors
24+
${appearance === value
25+
? 'bg-white dark:bg-neutral-700 shadow-sm dark:text-neutral-100'
26+
: 'hover:bg-neutral-200/60 text-neutral-500 hover:text-black dark:hover:bg-neutral-700/60 dark:text-neutral-400'
27+
}
28+
`}
29+
>
30+
<Icon className="h-4 w-4 -ml-1" />
31+
<span className="ml-1.5 text-sm">{label}</span>
32+
</button>
33+
))}
34+
</div>
35+
);
36+
}

resources/js/Components/AppearanceToggle.tsx

Lines changed: 0 additions & 97 deletions
This file was deleted.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as React from "react"
2+
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
3+
import { type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "@/lib/utils"
6+
import { toggleVariants } from "@/Components/ui/toggle"
7+
8+
const ToggleGroupContext = React.createContext<
9+
VariantProps<typeof toggleVariants>
10+
>({
11+
size: "default",
12+
variant: "default",
13+
})
14+
15+
const ToggleGroup = React.forwardRef<
16+
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
17+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
18+
VariantProps<typeof toggleVariants>
19+
>(({ className, variant, size, children, ...props }, ref) => (
20+
<ToggleGroupPrimitive.Root
21+
ref={ref}
22+
className={cn("flex items-center justify-center gap-1", className)}
23+
{...props}
24+
>
25+
<ToggleGroupContext.Provider value={{ variant, size }}>
26+
{children}
27+
</ToggleGroupContext.Provider>
28+
</ToggleGroupPrimitive.Root>
29+
))
30+
31+
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
32+
33+
const ToggleGroupItem = React.forwardRef<
34+
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
35+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
36+
VariantProps<typeof toggleVariants>
37+
>(({ className, children, variant, size, ...props }, ref) => {
38+
const context = React.useContext(ToggleGroupContext)
39+
40+
return (
41+
<ToggleGroupPrimitive.Item
42+
ref={ref}
43+
className={cn(
44+
toggleVariants({
45+
variant: context.variant || variant,
46+
size: context.size || size,
47+
}),
48+
className
49+
)}
50+
{...props}
51+
>
52+
{children}
53+
</ToggleGroupPrimitive.Item>
54+
)
55+
})
56+
57+
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
58+
59+
export { ToggleGroup, ToggleGroupItem }

0 commit comments

Comments
 (0)