Skip to content

Commit fc41089

Browse files
committed
feat: added primitives
1 parent 909ddb0 commit fc41089

19 files changed

Lines changed: 3043 additions & 28 deletions

File tree

apps/origami-web/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"postinstall": "fumadocs-mdx"
1212
},
1313
"dependencies": {
14+
"@radix-ui/react-dropdown-menu": "^2.1.15",
1415
"@radix-ui/react-slot": "^1.2.3",
16+
"@radix-ui/react-tooltip": "^1.2.7",
1517
"@repo/database": "workspace:*",
1618
"@repo/location": "workspace:*",
1719
"@tanstack/react-query": "^5.80.6",
@@ -29,6 +31,7 @@
2931
"fumadocs-mdx": "^11.6.7",
3032
"fumadocs-ui": "^15.5.1",
3133
"hono": "^4.0.0",
34+
"lucide-react": "^0.515.0",
3235
"next": "15.3.2",
3336
"next-themes": "^0.4.6",
3437
"nuqs": "^2.4.3",
@@ -38,7 +41,8 @@
3841
"superjson": "^2.2.2",
3942
"tailwind-merge": "^3.3.0",
4043
"tw-animate-css": "^1.3.0",
41-
"zod": "^3.24.4"
44+
"zod": "^3.24.4",
45+
"zustand": "^5.0.5"
4246
},
4347
"devDependencies": {
4448
"@eslint/eslintrc": "^3",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { NavigationSidebar } from "@/components/ui/sidebars/navigation-sidebar";
2+
3+
export default function Layout({
4+
children,
5+
}: Readonly<{
6+
children: React.ReactNode;
7+
}>) {
8+
return (
9+
<section className="flex h-screen w-screen">
10+
<NavigationSidebar />
11+
{children}
12+
</section>
13+
);
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Page() {
2+
return <div>Page</div>;
3+
}

apps/origami-web/src/app/(withAuth)/[organisationSlug]/page.tsx

Lines changed: 0 additions & 26 deletions
This file was deleted.

apps/origami-web/src/app/(withAuth)/select/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default async function Auth() {
1616
const orgToRedirectTo = orgs?.[0]?.organization;
1717

1818
// This should never happen, but just in case
19-
if (!orgToRedirectTo) {
19+
if (!orgToRedirectTo || !orgToRedirectTo.slug) {
2020
console.error(`ERROR: User ${user?.id} has no organizations found`);
2121

2222
notFound();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use client";
2+
3+
import * as React from "react";
4+
import { Moon, Sun } from "lucide-react";
5+
import { useTheme } from "next-themes";
6+
7+
import { Button } from "@/components/ui/button";
8+
import {
9+
DropdownMenu,
10+
DropdownMenuContent,
11+
DropdownMenuItem,
12+
DropdownMenuTrigger,
13+
} from "@/components/ui/dropdown-menu";
14+
15+
export function ModeToggle() {
16+
const { setTheme } = useTheme();
17+
18+
return (
19+
<DropdownMenu>
20+
<DropdownMenuTrigger asChild>
21+
<Button variant="outline" size="icon">
22+
<Sun className="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
23+
<Moon className="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
24+
<span className="sr-only">Toggle theme</span>
25+
</Button>
26+
</DropdownMenuTrigger>
27+
<DropdownMenuContent align="end">
28+
<DropdownMenuItem onClick={() => setTheme("light")}>
29+
Light
30+
</DropdownMenuItem>
31+
<DropdownMenuItem onClick={() => setTheme("dark")}>
32+
Dark
33+
</DropdownMenuItem>
34+
<DropdownMenuItem onClick={() => setTheme("system")}>
35+
System
36+
</DropdownMenuItem>
37+
</DropdownMenuContent>
38+
</DropdownMenu>
39+
);
40+
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
5+
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
6+
7+
import { cn } from "@/lib/utils"
8+
9+
function DropdownMenu({
10+
...props
11+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
13+
}
14+
15+
function DropdownMenuPortal({
16+
...props
17+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18+
return (
19+
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
20+
)
21+
}
22+
23+
function DropdownMenuTrigger({
24+
...props
25+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
26+
return (
27+
<DropdownMenuPrimitive.Trigger
28+
data-slot="dropdown-menu-trigger"
29+
{...props}
30+
/>
31+
)
32+
}
33+
34+
function DropdownMenuContent({
35+
className,
36+
sideOffset = 4,
37+
...props
38+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
39+
return (
40+
<DropdownMenuPrimitive.Portal>
41+
<DropdownMenuPrimitive.Content
42+
data-slot="dropdown-menu-content"
43+
sideOffset={sideOffset}
44+
className={cn(
45+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
46+
className
47+
)}
48+
{...props}
49+
/>
50+
</DropdownMenuPrimitive.Portal>
51+
)
52+
}
53+
54+
function DropdownMenuGroup({
55+
...props
56+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
57+
return (
58+
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
59+
)
60+
}
61+
62+
function DropdownMenuItem({
63+
className,
64+
inset,
65+
variant = "default",
66+
...props
67+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
68+
inset?: boolean
69+
variant?: "default" | "destructive"
70+
}) {
71+
return (
72+
<DropdownMenuPrimitive.Item
73+
data-slot="dropdown-menu-item"
74+
data-inset={inset}
75+
data-variant={variant}
76+
className={cn(
77+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
78+
className
79+
)}
80+
{...props}
81+
/>
82+
)
83+
}
84+
85+
function DropdownMenuCheckboxItem({
86+
className,
87+
children,
88+
checked,
89+
...props
90+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
91+
return (
92+
<DropdownMenuPrimitive.CheckboxItem
93+
data-slot="dropdown-menu-checkbox-item"
94+
className={cn(
95+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
96+
className
97+
)}
98+
checked={checked}
99+
{...props}
100+
>
101+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
102+
<DropdownMenuPrimitive.ItemIndicator>
103+
<CheckIcon className="size-4" />
104+
</DropdownMenuPrimitive.ItemIndicator>
105+
</span>
106+
{children}
107+
</DropdownMenuPrimitive.CheckboxItem>
108+
)
109+
}
110+
111+
function DropdownMenuRadioGroup({
112+
...props
113+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
114+
return (
115+
<DropdownMenuPrimitive.RadioGroup
116+
data-slot="dropdown-menu-radio-group"
117+
{...props}
118+
/>
119+
)
120+
}
121+
122+
function DropdownMenuRadioItem({
123+
className,
124+
children,
125+
...props
126+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
127+
return (
128+
<DropdownMenuPrimitive.RadioItem
129+
data-slot="dropdown-menu-radio-item"
130+
className={cn(
131+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
132+
className
133+
)}
134+
{...props}
135+
>
136+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
137+
<DropdownMenuPrimitive.ItemIndicator>
138+
<CircleIcon className="size-2 fill-current" />
139+
</DropdownMenuPrimitive.ItemIndicator>
140+
</span>
141+
{children}
142+
</DropdownMenuPrimitive.RadioItem>
143+
)
144+
}
145+
146+
function DropdownMenuLabel({
147+
className,
148+
inset,
149+
...props
150+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
151+
inset?: boolean
152+
}) {
153+
return (
154+
<DropdownMenuPrimitive.Label
155+
data-slot="dropdown-menu-label"
156+
data-inset={inset}
157+
className={cn(
158+
"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
159+
className
160+
)}
161+
{...props}
162+
/>
163+
)
164+
}
165+
166+
function DropdownMenuSeparator({
167+
className,
168+
...props
169+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
170+
return (
171+
<DropdownMenuPrimitive.Separator
172+
data-slot="dropdown-menu-separator"
173+
className={cn("bg-border -mx-1 my-1 h-px", className)}
174+
{...props}
175+
/>
176+
)
177+
}
178+
179+
function DropdownMenuShortcut({
180+
className,
181+
...props
182+
}: React.ComponentProps<"span">) {
183+
return (
184+
<span
185+
data-slot="dropdown-menu-shortcut"
186+
className={cn(
187+
"text-muted-foreground ml-auto text-xs tracking-widest",
188+
className
189+
)}
190+
{...props}
191+
/>
192+
)
193+
}
194+
195+
function DropdownMenuSub({
196+
...props
197+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
198+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
199+
}
200+
201+
function DropdownMenuSubTrigger({
202+
className,
203+
inset,
204+
children,
205+
...props
206+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
207+
inset?: boolean
208+
}) {
209+
return (
210+
<DropdownMenuPrimitive.SubTrigger
211+
data-slot="dropdown-menu-sub-trigger"
212+
data-inset={inset}
213+
className={cn(
214+
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
215+
className
216+
)}
217+
{...props}
218+
>
219+
{children}
220+
<ChevronRightIcon className="ml-auto size-4" />
221+
</DropdownMenuPrimitive.SubTrigger>
222+
)
223+
}
224+
225+
function DropdownMenuSubContent({
226+
className,
227+
...props
228+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
229+
return (
230+
<DropdownMenuPrimitive.SubContent
231+
data-slot="dropdown-menu-sub-content"
232+
className={cn(
233+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
234+
className
235+
)}
236+
{...props}
237+
/>
238+
)
239+
}
240+
241+
export {
242+
DropdownMenu,
243+
DropdownMenuPortal,
244+
DropdownMenuTrigger,
245+
DropdownMenuContent,
246+
DropdownMenuGroup,
247+
DropdownMenuLabel,
248+
DropdownMenuItem,
249+
DropdownMenuCheckboxItem,
250+
DropdownMenuRadioGroup,
251+
DropdownMenuRadioItem,
252+
DropdownMenuSeparator,
253+
DropdownMenuShortcut,
254+
DropdownMenuSub,
255+
DropdownMenuSubTrigger,
256+
DropdownMenuSubContent,
257+
}

0 commit comments

Comments
 (0)