img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
- className,
- )}
- {...props}
- />
- );
-}
-
-function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function CardAction({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function CardContent({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-export {
- Card,
- CardHeader,
- CardFooter,
- CardTitle,
- CardAction,
- CardDescription,
- CardContent,
-};
diff --git a/packages/ui/src/cmp/checkbox.tsx b/packages/ui/src/cmp/checkbox.tsx
deleted file mode 100644
index 16e8119..0000000
--- a/packages/ui/src/cmp/checkbox.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
-
-import { cn } from "../lib/utils";
-import { CheckIcon } from "lucide-react";
-
-function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
- return (
-
-
-
-
-
- );
-}
-
-export { Checkbox };
diff --git a/packages/ui/src/cmp/context-menu.tsx b/packages/ui/src/cmp/context-menu.tsx
deleted file mode 100644
index 4f2d0af..0000000
--- a/packages/ui/src/cmp/context-menu.tsx
+++ /dev/null
@@ -1,272 +0,0 @@
-"use client";
-
-import * as React from "react";
-import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
-
-import { cn } from "../lib/utils";
-import { ChevronRightIcon, CheckIcon } from "lucide-react";
-
-function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {
- return
;
-}
-
-function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {
- return (
-
- );
-}
-
-function ContextMenuTrigger({
- className,
- ...props
-}: ContextMenuPrimitive.Trigger.Props) {
- return (
-
- );
-}
-
-function ContextMenuContent({
- className,
- align = "start",
- alignOffset = 4,
- side = "right",
- sideOffset = 0,
- ...props
-}: ContextMenuPrimitive.Popup.Props &
- Pick<
- ContextMenuPrimitive.Positioner.Props,
- "align" | "alignOffset" | "side" | "sideOffset"
- >) {
- return (
-
-
-
-
-
- );
-}
-
-function ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {
- return (
-
- );
-}
-
-function ContextMenuLabel({
- className,
- inset,
- ...props
-}: ContextMenuPrimitive.GroupLabel.Props & {
- inset?: boolean;
-}) {
- return (
-
- );
-}
-
-function ContextMenuItem({
- className,
- inset,
- variant = "default",
- ...props
-}: ContextMenuPrimitive.Item.Props & {
- inset?: boolean;
- variant?: "default" | "destructive";
-}) {
- return (
-
- );
-}
-
-function ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {
- return (
-
- );
-}
-
-function ContextMenuSubTrigger({
- className,
- inset,
- children,
- ...props
-}: ContextMenuPrimitive.SubmenuTrigger.Props & {
- inset?: boolean;
-}) {
- return (
-
- {children}
-
-
- );
-}
-
-function ContextMenuSubContent({
- ...props
-}: React.ComponentProps
) {
- return (
-
- );
-}
-
-function ContextMenuCheckboxItem({
- className,
- children,
- checked,
- inset,
- ...props
-}: ContextMenuPrimitive.CheckboxItem.Props & {
- inset?: boolean;
-}) {
- return (
-
-
-
-
-
-
- {children}
-
- );
-}
-
-function ContextMenuRadioGroup({
- ...props
-}: ContextMenuPrimitive.RadioGroup.Props) {
- return (
-
- );
-}
-
-function ContextMenuRadioItem({
- className,
- children,
- inset,
- ...props
-}: ContextMenuPrimitive.RadioItem.Props & {
- inset?: boolean;
-}) {
- return (
-
-
-
-
-
-
- {children}
-
- );
-}
-
-function ContextMenuSeparator({
- className,
- ...props
-}: ContextMenuPrimitive.Separator.Props) {
- return (
-
- );
-}
-
-function ContextMenuShortcut({
- className,
- ...props
-}: React.ComponentProps<"span">) {
- return (
-
- );
-}
-
-export {
- ContextMenu,
- ContextMenuTrigger,
- ContextMenuContent,
- ContextMenuItem,
- ContextMenuCheckboxItem,
- ContextMenuRadioItem,
- ContextMenuLabel,
- ContextMenuSeparator,
- ContextMenuShortcut,
- ContextMenuGroup,
- ContextMenuPortal,
- ContextMenuSub,
- ContextMenuSubContent,
- ContextMenuSubTrigger,
- ContextMenuRadioGroup,
-};
diff --git a/packages/ui/src/cmp/dialog.tsx b/packages/ui/src/cmp/dialog.tsx
deleted file mode 100644
index d5f4032..0000000
--- a/packages/ui/src/cmp/dialog.tsx
+++ /dev/null
@@ -1,156 +0,0 @@
-"use client";
-
-import * as React from "react";
-import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
-
-import { cn } from "../lib/utils";
-import { Button } from "./button";
-import { XIcon } from "lucide-react";
-
-function Dialog({ ...props }: DialogPrimitive.Root.Props) {
- return ;
-}
-
-function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
- return ;
-}
-
-function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
- return ;
-}
-
-function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
- return ;
-}
-
-function DialogOverlay({
- className,
- ...props
-}: DialogPrimitive.Backdrop.Props) {
- return (
-
- );
-}
-
-function DialogContent({
- className,
- children,
- showCloseButton = true,
- ...props
-}: DialogPrimitive.Popup.Props & {
- showCloseButton?: boolean;
-}) {
- return (
-
-
-
- {children}
- {showCloseButton && (
-
- }
- >
-
- Close
-
- )}
-
-
- );
-}
-
-function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function DialogFooter({
- className,
- showCloseButton = false,
- children,
- ...props
-}: React.ComponentProps<"div"> & {
- showCloseButton?: boolean;
-}) {
- return (
-
- {children}
- {showCloseButton && (
- }>
- Close
-
- )}
-
- );
-}
-
-function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
- return (
-
- );
-}
-
-function DialogDescription({
- className,
- ...props
-}: DialogPrimitive.Description.Props) {
- return (
-
- );
-}
-
-export {
- Dialog,
- DialogClose,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogOverlay,
- DialogPortal,
- DialogTitle,
- DialogTrigger,
-};
diff --git a/packages/ui/src/cmp/input.tsx b/packages/ui/src/cmp/input.tsx
deleted file mode 100644
index ad8e96b..0000000
--- a/packages/ui/src/cmp/input.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import * as React from "react";
-import { Input as InputPrimitive } from "@base-ui/react/input";
-
-import { cn } from "../lib/utils";
-
-function Input({ className, type, ...props }: React.ComponentProps<"input">) {
- return (
-
- );
-}
-
-export { Input };
diff --git a/packages/ui/src/cmp/label.tsx b/packages/ui/src/cmp/label.tsx
deleted file mode 100644
index 95cad06..0000000
--- a/packages/ui/src/cmp/label.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from "react";
-
-import { cn } from "../lib/utils";
-
-function Label({ className, ...props }: React.ComponentProps<"label">) {
- return (
-
- );
-}
-
-export { Label };
diff --git a/packages/ui/src/cmp/select.tsx b/packages/ui/src/cmp/select.tsx
deleted file mode 100644
index 974dfc0..0000000
--- a/packages/ui/src/cmp/select.tsx
+++ /dev/null
@@ -1,202 +0,0 @@
-"use client";
-
-import * as React from "react";
-import { Select as SelectPrimitive } from "@base-ui/react/select";
-
-import { cn } from "../lib/utils";
-import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
-
-const Select = SelectPrimitive.Root;
-
-function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
- return (
-
- );
-}
-
-function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
- return (
-
- );
-}
-
-function SelectTrigger({
- className,
- size = "default",
- children,
- ...props
-}: SelectPrimitive.Trigger.Props & {
- size?: "sm" | "default";
-}) {
- return (
-
- {children}
-
- }
- />
-
- );
-}
-
-function SelectContent({
- className,
- children,
- side = "bottom",
- sideOffset = 4,
- align = "center",
- alignOffset = 0,
- alignItemWithTrigger = true,
- ...props
-}: SelectPrimitive.Popup.Props &
- Pick<
- SelectPrimitive.Positioner.Props,
- "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger"
- >) {
- return (
-
-
-
-
- {children}
-
-
-
-
- );
-}
-
-function SelectLabel({
- className,
- ...props
-}: SelectPrimitive.GroupLabel.Props) {
- return (
-
- );
-}
-
-function SelectItem({
- className,
- children,
- ...props
-}: SelectPrimitive.Item.Props) {
- return (
-
-
- {children}
-
-
- }
- >
-
-
-
- );
-}
-
-function SelectSeparator({
- className,
- ...props
-}: SelectPrimitive.Separator.Props) {
- return (
-
- );
-}
-
-function SelectScrollUpButton({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
- );
-}
-
-function SelectScrollDownButton({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
- );
-}
-
-export {
- Select,
- SelectContent,
- SelectGroup,
- SelectItem,
- SelectLabel,
- SelectScrollDownButton,
- SelectScrollUpButton,
- SelectSeparator,
- SelectTrigger,
- SelectValue,
-};
diff --git a/packages/ui/src/cmp/separator.tsx b/packages/ui/src/cmp/separator.tsx
deleted file mode 100644
index a9db268..0000000
--- a/packages/ui/src/cmp/separator.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
-
-import { cn } from "../lib/utils";
-
-function Separator({
- className,
- orientation = "horizontal",
- ...props
-}: SeparatorPrimitive.Props) {
- return (
-
- );
-}
-
-export { Separator };
diff --git a/packages/ui/src/cmp/sheet.tsx b/packages/ui/src/cmp/sheet.tsx
deleted file mode 100644
index de91b18..0000000
--- a/packages/ui/src/cmp/sheet.tsx
+++ /dev/null
@@ -1,132 +0,0 @@
-import * as React from "react";
-import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
-
-import { cn } from "../lib/utils";
-import { Button } from "./button";
-import { XIcon } from "lucide-react";
-
-function Sheet({ ...props }: SheetPrimitive.Root.Props) {
- return ;
-}
-
-function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
- return ;
-}
-
-function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
- return ;
-}
-
-function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
- return ;
-}
-
-function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
- return (
-
- );
-}
-
-function SheetContent({
- className,
- children,
- side = "right",
- showCloseButton = true,
- ...props
-}: SheetPrimitive.Popup.Props & {
- side?: "top" | "right" | "bottom" | "left";
- showCloseButton?: boolean;
-}) {
- return (
-
-
-
- {children}
- {showCloseButton && (
-
- }
- >
-
- Close
-
- )}
-
-
- );
-}
-
-function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
- return (
-
- );
-}
-
-function SheetDescription({
- className,
- ...props
-}: SheetPrimitive.Description.Props) {
- return (
-
- );
-}
-
-export {
- Sheet,
- SheetTrigger,
- SheetClose,
- SheetContent,
- SheetHeader,
- SheetFooter,
- SheetTitle,
- SheetDescription,
-};
diff --git a/packages/ui/src/cmp/sidebar.tsx b/packages/ui/src/cmp/sidebar.tsx
deleted file mode 100644
index aa76d18..0000000
--- a/packages/ui/src/cmp/sidebar.tsx
+++ /dev/null
@@ -1,709 +0,0 @@
-"use client";
-
-import * as React from "react";
-import { mergeProps } from "@base-ui/react/merge-props";
-import { useRender } from "@base-ui/react/use-render";
-import { cva, type VariantProps } from "class-variance-authority";
-
-import { useIsMobile } from "../hooks/use-mobile";
-import { cn } from "../lib/utils";
-import { Button } from "./button";
-import { Input } from "./input";
-import { Separator } from "./separator";
-import {
- Sheet,
- SheetContent,
- SheetDescription,
- SheetHeader,
- SheetTitle,
-} from "./sheet";
-import { Skeleton } from "./skeleton";
-import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip";
-
-const SIDEBAR_WIDTH = "16.25rem";
-const SIDEBAR_WIDTH_ICON = "5rem";
-const SIDEBAR_KEYBOARD_SHORTCUT = "b";
-
-type SidebarContextProps = {
- state: "expanded" | "collapsed";
- open: boolean;
- setOpen: (open: boolean) => void;
- openMobile: boolean;
- setOpenMobile: (open: boolean) => void;
- isMobile: boolean;
- toggleSidebar: () => void;
-};
-
-const SidebarContext = React.createContext(null);
-
-function useSidebar() {
- const context = React.useContext(SidebarContext);
- if (!context) {
- throw new Error("useSidebar must be used within a SidebarProvider.");
- }
-
- return context;
-}
-
-function SidebarProvider({
- defaultOpen = true,
- open: openProp,
- onOpenChange: setOpenProp,
- className,
- style,
- children,
- ...props
-}: React.ComponentProps<"div"> & {
- defaultOpen?: boolean;
- open?: boolean;
- onOpenChange?: (open: boolean) => void;
-}) {
- const isMobile = useIsMobile();
- const [openMobile, setOpenMobile] = React.useState(false);
-
- // This is the internal state of the sidebar.
- // We use openProp and setOpenProp for control from outside the component.
- const [_open, _setOpen] = React.useState(defaultOpen);
- const open = openProp ?? _open;
- const setOpen = React.useCallback(
- (value: boolean | ((value: boolean) => boolean)) => {
- const openState = typeof value === "function" ? value(open) : value;
- if (setOpenProp) {
- setOpenProp(openState);
- } else {
- _setOpen(openState);
- }
- },
- [setOpenProp, open],
- );
-
- // Helper to toggle the sidebar.
- const toggleSidebar = React.useCallback(() => {
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
- }, [isMobile, setOpen, setOpenMobile]);
-
- // Adds a keyboard shortcut to toggle the sidebar.
- React.useEffect(() => {
- const handleKeyDown = (event: KeyboardEvent) => {
- if (
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
- (event.metaKey || event.ctrlKey)
- ) {
- event.preventDefault();
- toggleSidebar();
- }
- };
-
- window.addEventListener("keydown", handleKeyDown);
- return () => window.removeEventListener("keydown", handleKeyDown);
- }, [toggleSidebar]);
-
- // We add a state so that we can do data-state="expanded" or "collapsed".
- // This makes it easier to style the sidebar with Tailwind classes.
- const state = open ? "expanded" : "collapsed";
-
- const contextValue = React.useMemo(
- () => ({
- state,
- open,
- setOpen,
- isMobile,
- openMobile,
- setOpenMobile,
- toggleSidebar,
- }),
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],
- );
-
- return (
-
-
- {children}
-
-
- );
-}
-
-function Sidebar({
- side = "left",
- variant = "sidebar",
- collapsible = "offcanvas",
- className,
- children,
- dir,
- ...props
-}: React.ComponentProps<"div"> & {
- side?: "left" | "right";
- variant?: "sidebar" | "floating" | "inset";
- collapsible?: "offcanvas" | "icon" | "none";
-}) {
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
-
- if (collapsible === "none") {
- return (
-
- {children}
-
- );
- }
-
- if (isMobile) {
- return (
-
-
-
- Sidebar
- Displays the mobile sidebar.
-
- {children}
-
-
- );
- }
-
- return (
-
- {/* This is what handles the sidebar gap on desktop */}
-
-
-
- );
-}
-
-function SidebarTrigger({
- className,
- onClick,
- children,
- ...props
-}: React.ComponentProps) {
- const { toggleSidebar } = useSidebar();
-
- return (
-
- );
-}
-
-function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
- const { toggleSidebar } = useSidebar();
-
- return (
-
- );
-}
-
-function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
- return (
-
- );
-}
-
-function SidebarInput({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarSeparator({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarGroupLabel({
- className,
- render,
- ...props
-}: useRender.ComponentProps<"div"> & React.ComponentProps<"div">) {
- return useRender({
- defaultTagName: "div",
- props: mergeProps<"div">(
- {
- className: cn(
- "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
- className,
- ),
- },
- props,
- ),
- render,
- state: {
- slot: "sidebar-group-label",
- sidebar: "group-label",
- },
- });
-}
-
-function SidebarGroupAction({
- className,
- render,
- ...props
-}: useRender.ComponentProps<"button"> & React.ComponentProps<"button">) {
- return useRender({
- defaultTagName: "button",
- props: mergeProps<"button">(
- {
- className: cn(
- "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
- className,
- ),
- },
- props,
- ),
- render,
- state: {
- slot: "sidebar-group-action",
- sidebar: "group-action",
- },
- });
-}
-
-function SidebarGroupContent({
- className,
- ...props
-}: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
- return (
-
- );
-}
-
-function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
- return (
-
- );
-}
-
-const sidebarMenuButtonVariants = cva(
- "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
- {
- variants: {
- variant: {
- default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
- outline:
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
- },
- size: {
- default: "h-8 text-sm",
- sm: "h-7 text-xs",
- lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- },
-);
-
-function SidebarMenuButton({
- render,
- isActive = false,
- variant = "default",
- size = "default",
- tooltip,
- className,
- ...props
-}: useRender.ComponentProps<"button"> &
- React.ComponentProps<"button"> & {
- isActive?: boolean;
- tooltip?: string | React.ComponentProps;
- } & VariantProps) {
- const { isMobile, state } = useSidebar();
- const comp = useRender({
- defaultTagName: "button",
- props: mergeProps<"button">(
- {
- className: cn(sidebarMenuButtonVariants({ variant, size }), className),
- },
- props,
- ),
- render: !tooltip ? render : ,
- state: {
- slot: "sidebar-menu-button",
- sidebar: "menu-button",
- size,
- active: isActive,
- },
- });
-
- if (!tooltip) {
- return comp;
- }
-
- if (typeof tooltip === "string") {
- tooltip = {
- children: tooltip,
- };
- }
-
- return (
-
- {comp}
-
-
- );
-}
-
-function SidebarMenuAction({
- className,
- render,
- showOnHover = false,
- ...props
-}: useRender.ComponentProps<"button"> &
- React.ComponentProps<"button"> & {
- showOnHover?: boolean;
- }) {
- return useRender({
- defaultTagName: "button",
- props: mergeProps<"button">(
- {
- className: cn(
- "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
- showOnHover &&
- "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
- className,
- ),
- },
- props,
- ),
- render,
- state: {
- slot: "sidebar-menu-action",
- sidebar: "menu-action",
- },
- });
-}
-
-function SidebarMenuBadge({
- className,
- ...props
-}: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function SidebarMenuSkeleton({
- className,
- showIcon = false,
- ...props
-}: React.ComponentProps<"div"> & {
- showIcon?: boolean;
-}) {
- // Random width between 50 to 90%.
- const [width] = React.useState(() => {
- return `${Math.floor(Math.random() * 40) + 50}%`;
- });
-
- return (
-
- {showIcon && (
-
- )}
-
-
- );
-}
-
-function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
- return (
-
- );
-}
-
-function SidebarMenuSubItem({
- className,
- ...props
-}: React.ComponentProps<"li">) {
- return (
-
- );
-}
-
-function SidebarMenuSubButton({
- render,
- size = "md",
- isActive = false,
- className,
- ...props
-}: useRender.ComponentProps<"a"> &
- React.ComponentProps<"a"> & {
- size?: "sm" | "md";
- isActive?: boolean;
- }) {
- return useRender({
- defaultTagName: "a",
- props: mergeProps<"a">(
- {
- className: cn(
- "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
- className,
- ),
- },
- props,
- ),
- render,
- state: {
- slot: "sidebar-menu-sub-button",
- sidebar: "menu-sub-button",
- size,
- active: isActive,
- },
- });
-}
-
-export {
- Sidebar,
- SidebarContent,
- SidebarFooter,
- SidebarGroup,
- SidebarGroupAction,
- SidebarGroupContent,
- SidebarGroupLabel,
- SidebarHeader,
- SidebarInput,
- SidebarInset,
- SidebarMenu,
- SidebarMenuAction,
- SidebarMenuBadge,
- SidebarMenuButton,
- SidebarMenuItem,
- SidebarMenuSkeleton,
- SidebarMenuSub,
- SidebarMenuSubButton,
- SidebarMenuSubItem,
- SidebarProvider,
- SidebarRail,
- SidebarSeparator,
- SidebarTrigger,
- useSidebar,
-};
diff --git a/packages/ui/src/cmp/skeleton.tsx b/packages/ui/src/cmp/skeleton.tsx
deleted file mode 100644
index 99f46eb..0000000
--- a/packages/ui/src/cmp/skeleton.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { cn } from "../lib/utils";
-
-function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-export { Skeleton };
diff --git a/packages/ui/src/cmp/sonner.tsx b/packages/ui/src/cmp/sonner.tsx
deleted file mode 100644
index 071e8f2..0000000
--- a/packages/ui/src/cmp/sonner.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-"use client";
-
-import { useTheme } from "next-themes";
-import { Toaster as Sonner, type ToasterProps } from "sonner";
-import {
- CircleCheckIcon,
- InfoIcon,
- TriangleAlertIcon,
- OctagonXIcon,
- Loader2Icon,
-} from "lucide-react";
-
-const Toaster = ({ ...props }: ToasterProps) => {
- const { theme = "system" } = useTheme();
-
- return (
- ,
- info: ,
- warning: ,
- error: ,
- loading: ,
- }}
- style={
- {
- "--normal-bg": "var(--color-popover)",
- "--normal-text": "var(--color-popover-foreground)",
- "--normal-border": "var(--color-border)",
- "--border-radius": "var(--radius)",
- } as React.CSSProperties
- }
- toastOptions={{
- classNames: {
- toast: "cn-toast",
- },
- }}
- {...props}
- />
- );
-};
-
-export { Toaster };
diff --git a/packages/ui/src/cmp/switch.tsx b/packages/ui/src/cmp/switch.tsx
deleted file mode 100644
index 88ac5e9..0000000
--- a/packages/ui/src/cmp/switch.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Switch as SwitchPrimitive } from "@base-ui/react/switch"
-
-import { cn } from "../lib/utils"
-
-function Switch({
- className,
- size = "default",
- ...props
-}: SwitchPrimitive.Root.Props & {
- size?: "sm" | "default"
-}) {
- return (
-
-
-
- )
-}
-
-export { Switch }
diff --git a/packages/ui/src/cmp/tooltip.tsx b/packages/ui/src/cmp/tooltip.tsx
deleted file mode 100644
index 99c7187..0000000
--- a/packages/ui/src/cmp/tooltip.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
-
-import { cn } from "../lib/utils";
-
-function TooltipProvider({
- delay = 0,
- ...props
-}: TooltipPrimitive.Provider.Props) {
- return (
-
- );
-}
-
-function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
- return ;
-}
-
-function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
- return ;
-}
-
-function TooltipContent({
- className,
- side = "top",
- sideOffset = 4,
- align = "center",
- alignOffset = 0,
- children,
- ...props
-}: TooltipPrimitive.Popup.Props &
- Pick<
- TooltipPrimitive.Positioner.Props,
- "align" | "alignOffset" | "side" | "sideOffset"
- >) {
- return (
-
-
-
- {children}
-
-
-
-
- );
-}
-
-export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
diff --git a/packages/ui/src/hooks/use-mobile.ts b/packages/ui/src/hooks/use-mobile.ts
deleted file mode 100644
index a93d583..0000000
--- a/packages/ui/src/hooks/use-mobile.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import * as React from "react";
-
-const MOBILE_BREAKPOINT = 768;
-
-export function useIsMobile() {
- const [isMobile, setIsMobile] = React.useState(
- undefined,
- );
-
- React.useEffect(() => {
- const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
- const onChange = () => {
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
- };
- mql.addEventListener("change", onChange);
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
- return () => mql.removeEventListener("change", onChange);
- }, []);
-
- return !!isMobile;
-}
diff --git a/packages/ui/src/index.css b/packages/ui/src/index.css
deleted file mode 100644
index 6c303b4..0000000
--- a/packages/ui/src/index.css
+++ /dev/null
@@ -1,18 +0,0 @@
-@import "tailwindcss";
-@import "tw-animate-css";
-@import "shadcn/tailwind.css";
-@import "@fontsource-variable/inter";
-
-@custom-variant dark (&:is(.dark *));
-
-@layer base {
- * {
- @apply border-border outline-ring/50;
- }
- body {
- @apply bg-background text-foreground;
- }
- html {
- @apply font-sans;
- }
-}
diff --git a/packages/ui/src/lib/utils.ts b/packages/ui/src/lib/utils.ts
deleted file mode 100644
index fcd28e3..0000000
--- a/packages/ui/src/lib/utils.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { clsx, type ClassValue } from "clsx";
-import { twMerge } from "tailwind-merge";
-
-/**
- * Executes cn.
- * @param inputs Parameter inputs.
- * @returns unknown.
- */
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
-}
-
-import { useIsMobile } from "../hooks/use-mobile";
-export { useIsMobile };
diff --git a/packages/ui/src/link.tsx b/packages/ui/src/link.tsx
deleted file mode 100644
index 9737ba0..0000000
--- a/packages/ui/src/link.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ExternalLink } from "lucide-react";
-
-/**
- * Executes Link.
- * @param props Parameter props.
- * @returns unknown.
- */
-export default function Link(props: { link: string; label: string }) {
- return (
-
- {props.label}
-
- );
-}
diff --git a/packages/ui/src/screens/error.tsx b/packages/ui/src/screens/error.tsx
deleted file mode 100644
index b5e93d3..0000000
--- a/packages/ui/src/screens/error.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import Link from "../link";
-import CreateScreen, { StorageDestoryer } from "./util";
-
-/**
- * Executes Screen.
- * @param props Parameter props.
- * @returns unknown.
- */
-export default function Screen(props: { error: string; description: string }) {
- return (
-
- {props.error}
-
- {props.description}
-
-
-
-
- );
-}
diff --git a/packages/ui/src/screens/loading.tsx b/packages/ui/src/screens/loading.tsx
deleted file mode 100644
index 0c26834..0000000
--- a/packages/ui/src/screens/loading.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import * as React from "react";
-import CreateScreen, { StorageDestoryer } from "./util";
-
-const DELAY = 250;
-
-type ScreenProps = {
- progress: number;
- title?: string;
- description?: string;
- fullscreen?: boolean;
-};
-
-/**
- * Executes Screen.
- * @param props Parameter props.
- * @returns unknown.
- */
-export default function Screen(props: ScreenProps) {
- const [displayProgress, setDisplayProgress] = React.useState(0);
- const displayProgressRef = React.useRef(0);
-
- React.useEffect(() => {
- displayProgressRef.current = displayProgress;
- }, [displayProgress]);
-
- React.useEffect(() => {
- const target = props.progress;
- const start = displayProgressRef.current;
- const delta = target - start;
-
- if (delta === 0) {
- return;
- }
-
- const duration = DELAY;
- const startTime = performance.now();
- let frameId = 0;
-
- /**
- * Executes animate.
- * @param now Parameter now.
- * @returns unknown.
- */
- function animate(now: number) {
- const elapsed = now - startTime;
- const t = Math.min(elapsed / duration, 1);
- const eased = 1 - Math.pow(1 - t, 3);
- setDisplayProgress(start + delta * eased);
-
- if (t < 1) {
- frameId = requestAnimationFrame(animate);
- }
- }
-
- frameId = requestAnimationFrame(animate);
-
- return () => {
- cancelAnimationFrame(frameId);
- };
- }, [props.progress]);
-
- return (
-
-
- {props.title ?? "Loading"}
-
- {props.description ? (
-
- {props.description}
-
- ) : (
-
- )}
-
-
-
- );
-}
diff --git a/packages/ui/src/screens/util.tsx b/packages/ui/src/screens/util.tsx
deleted file mode 100644
index 1029d57..0000000
--- a/packages/ui/src/screens/util.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import { cn } from "../lib/utils";
-import Controls from "@tensamin/tauri/controls";
-import { isTauri } from "@tauri-apps/api/core";
-
-export default function CreateScreen({
- children,
- className,
-}: {
- children: React.ReactNode;
- className?: string;
-}) {
- return (
-
- <>
-
- {children}
- >
-
- );
-}
-
-import { Button } from "../cmp/button";
-import {
- AlertDialog,
- AlertDialogAction,
- AlertDialogCancel,
- AlertDialogContent,
- AlertDialogDescription,
- AlertDialogFooter,
- AlertDialogHeader,
- AlertDialogTitle,
- AlertDialogTrigger,
-} from "../cmp/alert-dialog";
-import { useIsMobile } from "../lib/utils";
-
-export function StorageDestoryer() {
- const isMobile = useIsMobile();
- return (
-
-
-
- Clear storage
-
- }
- />
-
-
-
- Are you sure you want to clear storage?
-
-
- This action cannot be undone. It will clear all your settings and
- credentials.
-
-
-
- {
- localStorage.clear();
- for (const db of await indexedDB.databases()) {
- indexedDB.deleteDatabase(db.name!);
- }
- location.reload();
- }}
- >
- Continue
-
- Cancel
-
-
-
-
- );
-}
diff --git a/packages/ui/src/theme.tsx b/packages/ui/src/theme.tsx
deleted file mode 100644
index 5c0ec94..0000000
--- a/packages/ui/src/theme.tsx
+++ /dev/null
@@ -1,286 +0,0 @@
-import * as React from "react";
-
-type Theme = "dark" | "light" | "system";
-type ResolvedTheme = "dark" | "light";
-
-type ThemeProviderProps = {
- children: React.ReactNode;
- defaultTheme?: Theme;
- storageKey?: string;
- disableTransitionOnChange?: boolean;
-};
-
-type ThemeProviderState = {
- theme: Theme;
- setTheme: (theme: Theme) => void;
-};
-
-const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)";
-const THEME_VALUES: Theme[] = ["dark", "light", "system"];
-
-const ThemeProviderContext = React.createContext<
- ThemeProviderState | undefined
->(undefined);
-
-/**
- * Executes isTheme.
- * @param value Parameter value.
- * @returns value is Theme.
- */
-function isTheme(value: string | null): value is Theme {
- if (value === null) {
- return false;
- }
-
- return THEME_VALUES.includes(value as Theme);
-}
-
-/**
- * Executes getSystemTheme.
- * @param none This function has no parameters.
- * @returns ResolvedTheme.
- */
-function getSystemTheme(): ResolvedTheme {
- if (window.matchMedia(COLOR_SCHEME_QUERY).matches) {
- return "dark";
- }
-
- return "light";
-}
-
-/**
- * Executes disableTransitionsTemporarily.
- * @param none This function has no parameters.
- * @returns unknown.
- */
-function disableTransitionsTemporarily() {
- const style = document.createElement("style");
- style.appendChild(
- document.createTextNode(
- "*,*::before,*::after{-webkit-transition:none!important;transition:none!important}",
- ),
- );
- document.head.appendChild(style);
-
- return () => {
- window.getComputedStyle(document.body);
- requestAnimationFrame(() => {
- requestAnimationFrame(() => {
- style.remove();
- });
- });
- };
-}
-
-/**
- * Executes isEditableTarget.
- * @param target Parameter target.
- * @returns unknown.
- */
-function isEditableTarget(target: EventTarget | null) {
- if (!(target instanceof HTMLElement)) {
- return false;
- }
-
- if (target.isContentEditable) {
- return true;
- }
-
- const editableParent = target.closest(
- "input, textarea, select, [contenteditable='true']",
- );
- if (editableParent) {
- return true;
- }
-
- return false;
-}
-
-/**
- * Executes ThemeProvider.
- * @param {
- children,
- defaultTheme = "system",
- storageKey = "theme",
- disableTransitionOnChange = true,
- ...props
-} Parameter {
- children,
- defaultTheme = "system",
- storageKey = "theme",
- disableTransitionOnChange = true,
- ...props
-}.
- * @returns unknown.
- */
-export function ThemeProvider({
- children,
- defaultTheme = "system",
- storageKey = "theme",
- disableTransitionOnChange = true,
- ...props
-}: ThemeProviderProps) {
- const [theme, setThemeState] = React.useState(() => {
- const storedTheme = localStorage.getItem(storageKey);
- if (isTheme(storedTheme)) {
- return storedTheme;
- }
-
- return defaultTheme;
- });
-
- const setTheme = React.useCallback(
- (nextTheme: Theme) => {
- localStorage.setItem(storageKey, nextTheme);
- setThemeState(nextTheme);
- },
- [storageKey],
- );
-
- const applyTheme = React.useCallback(
- (nextTheme: Theme) => {
- const root = document.documentElement;
- const resolvedTheme =
- nextTheme === "system" ? getSystemTheme() : nextTheme;
- const restoreTransitions = disableTransitionOnChange
- ? disableTransitionsTemporarily()
- : null;
-
- root.classList.remove("light", "dark");
- root.classList.add(resolvedTheme);
-
- if (restoreTransitions) {
- restoreTransitions();
- }
- },
- [disableTransitionOnChange],
- );
-
- React.useEffect(() => {
- applyTheme(theme);
-
- if (theme !== "system") {
- return undefined;
- }
-
- const mediaQuery = window.matchMedia(COLOR_SCHEME_QUERY);
- /**
- * Executes handleChange.
- * @param none This function has no parameters.
- * @returns unknown.
- */
- const handleChange = () => {
- applyTheme("system");
- };
-
- mediaQuery.addEventListener("change", handleChange);
-
- return () => {
- mediaQuery.removeEventListener("change", handleChange);
- };
- }, [theme, applyTheme]);
-
- React.useEffect(() => {
- /**
- * Executes handleKeyDown.
- * @param event Parameter event.
- * @returns unknown.
- */
- const handleKeyDown = (event: KeyboardEvent) => {
- if (event.repeat) {
- return;
- }
-
- if (event.metaKey || event.ctrlKey || event.altKey) {
- return;
- }
-
- if (isEditableTarget(event.target)) {
- return;
- }
-
- if (event.key.toLowerCase() !== "d") {
- return;
- }
-
- setThemeState((currentTheme) => {
- const nextTheme =
- currentTheme === "dark"
- ? "light"
- : currentTheme === "light"
- ? "dark"
- : getSystemTheme() === "dark"
- ? "light"
- : "dark";
-
- localStorage.setItem(storageKey, nextTheme);
- return nextTheme;
- });
- };
-
- window.addEventListener("keydown", handleKeyDown);
-
- return () => {
- window.removeEventListener("keydown", handleKeyDown);
- };
- }, [storageKey]);
-
- React.useEffect(() => {
- /**
- * Executes handleStorageChange.
- * @param event Parameter event.
- * @returns unknown.
- */
- const handleStorageChange = (event: StorageEvent) => {
- if (event.storageArea !== localStorage) {
- return;
- }
-
- if (event.key !== storageKey) {
- return;
- }
-
- if (isTheme(event.newValue)) {
- setThemeState(event.newValue);
- return;
- }
-
- setThemeState(defaultTheme);
- };
-
- window.addEventListener("storage", handleStorageChange);
-
- return () => {
- window.removeEventListener("storage", handleStorageChange);
- };
- }, [defaultTheme, storageKey]);
-
- const value = React.useMemo(
- () => ({
- theme,
- setTheme,
- }),
- [theme, setTheme],
- );
-
- return (
-
- {children}
-
- );
-}
-
-/**
- * Executes useTheme.
- * @param none This function has no parameters.
- * @returns unknown.
- */
-export const useTheme = () => {
- const context = React.useContext(ThemeProviderContext);
-
- if (context === undefined) {
- throw new Error("useTheme must be used within a ThemeProvider");
- }
-
- return context;
-};
diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json
deleted file mode 100644
index b86df33..0000000
--- a/packages/ui/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2022",
- "module": "ESNext",
- "moduleResolution": "bundler",
- "jsx": "react-jsx",
- "strict": true,
- "skipLibCheck": true,
- "noEmit": true,
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- },
- "include": ["src/**/*.ts", "src/**/*.tsx"]
-}
diff --git a/scripts/install-packages.ts b/scripts/install-packages.ts
deleted file mode 100644
index f897f0c..0000000
--- a/scripts/install-packages.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { existsSync, readdirSync, statSync } from "fs";
-import { join, relative } from "path";
-import { execSync } from "child_process";
-
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-
-const _dirname = dirname(fileURLToPath(import.meta.url));
-
-const rootDir = join(_dirname, "..");
-const targetDirs = [join(rootDir, "packages"), join(rootDir, "apps")];
-
-function getPackageDirs(dir: string): string[] {
- const entries = readdirSync(dir);
- const dirs: string[] = [];
-
- for (const entry of entries) {
- const fullPath = join(dir, entry);
- if (!statSync(fullPath).isDirectory()) continue;
-
- if (existsSync(join(fullPath, "package.json"))) {
- dirs.push(fullPath);
- continue;
- }
-
- dirs.push(...getPackageDirs(fullPath));
- }
-
- return dirs;
-}
-
-for (const targetDir of targetDirs) {
- const packageDirs = getPackageDirs(targetDir);
-
- for (const fullPath of packageDirs) {
- const entry = relative(rootDir, fullPath);
- console.log(`Installing ${entry}...`);
- try {
- execSync("bun install", { cwd: fullPath, stdio: "inherit" });
- console.log(`${entry} intalled successfully.`);
- } catch {
- console.error(`Failed to install ${entry}.`);
- process.exit(1);
- }
- }
-}
-
-console.log("Done!");