diff --git a/.vscode/settings.json b/.vscode/settings.json index 5ed39d11..853691d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,8 @@ { "files.associations": { "tsconfig.json": "jsonc", - "typescript-config/*.json": "jsonc" + "typescript-config/*.json": "jsonc", + "*.css": "tailwindcss" }, // Javascript and TypeScript settings @@ -16,6 +17,10 @@ "typescript.suggestionActions.enabled": true, "typescript.preferences.importModuleSpecifier": "shortest", + "editor.quickSuggestions": { + "strings": "on" + }, + "editor.codeActionsOnSave": { "source.organizeImports": "always", "quickfix.biome": "always", diff --git a/apps/web/package.json b/apps/web/package.json index d1e38a16..2a81cd51 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -31,7 +31,6 @@ "react-secure-storage": "^1.3.2", "tailwind-merge": "^3.2.0", "tailwindcss": "^4.1.6", - "tailwindcss-animate": "^1.0.7", "tw-animate-css": "^1.2.9", "vite-plugin-html": "^3.2.2" }, diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs index b62ffe34..a1523e19 100644 --- a/apps/web/postcss.config.mjs +++ b/apps/web/postcss.config.mjs @@ -1 +1 @@ -export { default } from "@repo/shadcn-ui/postcss.config"; +export { default } from "@repo/shadcn-ui/postcss.config.mjs"; diff --git a/apps/web/src/app.css b/apps/web/src/app.css index a041a744..b28b04f6 100644 --- a/apps/web/src/app.css +++ b/apps/web/src/app.css @@ -1,3 +1,3 @@ -@import "tailwindcss"; + diff --git a/apps/web/src/app.tsx b/apps/web/src/app.tsx index 08f19afa..85801035 100644 --- a/apps/web/src/app.tsx +++ b/apps/web/src/app.tsx @@ -31,7 +31,6 @@ export const App = () => { - {import.meta.env.MODE === "development" && } diff --git a/apps/web/src/global.css b/apps/web/src/global.css index ac7fa1ee..60145b34 100644 --- a/apps/web/src/global.css +++ b/apps/web/src/global.css @@ -1,30 +1,15 @@ @import 'tailwindcss'; -@plugin "tailwindcss-animate"; +@import "tw-animate-css"; @import '@repo/shadcn-ui/globals.css'; @import '@repo/rdx-ui/globals.css'; -@custom-variant dark (&:is(.dark *)); - -@layer base { - - * { - @apply border-border; - } - - body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - tab-size: 4; - font-feature-settings: normal; - font-variation-settings: normal; - font-feature-settings: "rlig" 1, "calt" 1; - @apply h-full text-foreground bg-background /*font-poppins*/; - } - - #factuges { - @apply flex min-h-screen min-w-[320px] flex-col; - } - - -} \ No newline at end of file +/** + * Tailwind CSS official document: + * https://tailwindcss.com/docs/detecting-classes-in-source-files + * + * if you ever need to explicitly add a source that's excluded by default, + * you can always add it with the @source directive. + */ +@source '../node_modules/@repo/shadcn-ui'; +@source '../node_modules/@repo/rdx-ui'; \ No newline at end of file diff --git a/biome.json b/biome.json index 6172acaf..15af6286 100644 --- a/biome.json +++ b/biome.json @@ -19,6 +19,7 @@ "rules": { "recommended": true, "correctness": { + "useExhaustiveDependencies": "info", "noUnreachable": "off" }, "complexity": { diff --git a/packages/rdx-ui/package.json b/packages/rdx-ui/package.json index d460ebc1..4aea26a0 100644 --- a/packages/rdx-ui/package.json +++ b/packages/rdx-ui/package.json @@ -31,6 +31,7 @@ "esbuild-plugin-react18": "^0.2.6", "esbuild-plugin-react18-css": "^0.0.4", "tailwindcss": "^4.1.5", + "tw-animate-css": "^1.2.9", "tsup": "^8.4.0", "typescript": "^5.8.3", "typescript-plugin-css-modules": "^5.1.0", diff --git a/packages/rdx-ui/src/components/layout/app-breadcrumb.tsx b/packages/rdx-ui/src/components/layout/app-breadcrumb.tsx new file mode 100644 index 00000000..68221261 --- /dev/null +++ b/packages/rdx-ui/src/components/layout/app-breadcrumb.tsx @@ -0,0 +1,32 @@ +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, + Separator, + SidebarTrigger, +} from "@repo/shadcn-ui/components"; + +export const AppBreadcrumb = () => { + return ( +
+
+ + + + + + Building Your Application + + + + Data Fetching + + + +
+
+ ); +}; diff --git a/packages/rdx-ui/src/components/layout/app-content.tsx b/packages/rdx-ui/src/components/layout/app-content.tsx new file mode 100644 index 00000000..246e1bf8 --- /dev/null +++ b/packages/rdx-ui/src/components/layout/app-content.tsx @@ -0,0 +1,5 @@ +import { PropsWithChildren } from "react"; + +export const AppContent = ({ children }: PropsWithChildren) => { + return
{children}
; +}; diff --git a/packages/rdx-ui/src/components/layout/app-layout.tsx b/packages/rdx-ui/src/components/layout/app-layout.tsx index add928af..80585627 100644 --- a/packages/rdx-ui/src/components/layout/app-layout.tsx +++ b/packages/rdx-ui/src/components/layout/app-layout.tsx @@ -1,7 +1,6 @@ import { SidebarInset, SidebarProvider } from "@repo/shadcn-ui/components"; import { Outlet } from "react-router"; import { AppSidebar } from "./app-sidebar.tsx"; -import { SiteHeader } from "./site-header.tsx"; export const AppLayout: React.FC = () => { return ( @@ -15,15 +14,7 @@ export const AppLayout: React.FC = () => { > - - -
-
-
- -
-
-
+
); diff --git a/packages/rdx-ui/src/components/layout/index.tsx b/packages/rdx-ui/src/components/layout/index.tsx index 615e1c50..437da7db 100644 --- a/packages/rdx-ui/src/components/layout/index.tsx +++ b/packages/rdx-ui/src/components/layout/index.tsx @@ -1 +1,3 @@ +export * from "./app-breadcrumb.tsx"; +export * from "./app-content.tsx"; export * from "./app-layout.tsx"; diff --git a/packages/rdx-ui/src/components/layout/site-header.tsx b/packages/rdx-ui/src/components/layout/site-header.tsx deleted file mode 100644 index c04ce418..00000000 --- a/packages/rdx-ui/src/components/layout/site-header.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Separator } from "@repo/shadcn-ui/components/separator"; -import { SidebarTrigger } from "@repo/shadcn-ui/components/sidebar"; - -export const SiteHeader = ({ title }: { title: string }) => { - return ( -
-
- - -

{title}

-
-
- ); -}; diff --git a/packages/rdx-ui/src/styles/globals.css b/packages/rdx-ui/src/styles/globals.css index 27bf2e1a..3825f26b 100644 --- a/packages/rdx-ui/src/styles/globals.css +++ b/packages/rdx-ui/src/styles/globals.css @@ -1,3 +1 @@ -@import 'tailwindcss'; @import '@repo/shadcn-ui/globals.css'; - diff --git a/packages/shadcn-ui/@/components/ui/button.tsx b/packages/shadcn-ui/@/components/ui/button.tsx deleted file mode 100644 index a2df8dce..00000000 --- a/packages/shadcn-ui/@/components/ui/button.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", - { - variants: { - variant: { - default: - "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", - destructive: - "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", - outline: - "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", - secondary: - "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", - ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-9 px-4 py-2 has-[>svg]:px-3", - sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", - lg: "h-10 rounded-md px-6 has-[>svg]:px-4", - icon: "size-9", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -function Button({ - className, - variant, - size, - asChild = false, - ...props -}: React.ComponentProps<"button"> & - VariantProps & { - asChild?: boolean - }) { - const Comp = asChild ? Slot : "button" - - return ( - - ) -} - -export { Button, buttonVariants } diff --git a/packages/shadcn-ui/@/components/ui/input.tsx b/packages/shadcn-ui/@/components/ui/input.tsx deleted file mode 100644 index 03295ca6..00000000 --- a/packages/shadcn-ui/@/components/ui/input.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from "react" - -import { cn } from "@/lib/utils" - -function Input({ className, type, ...props }: React.ComponentProps<"input">) { - return ( - - ) -} - -export { Input } diff --git a/packages/shadcn-ui/@/components/ui/separator.tsx b/packages/shadcn-ui/@/components/ui/separator.tsx deleted file mode 100644 index 67c73e5a..00000000 --- a/packages/shadcn-ui/@/components/ui/separator.tsx +++ /dev/null @@ -1,28 +0,0 @@ -"use client" - -import * as React from "react" -import * as SeparatorPrimitive from "@radix-ui/react-separator" - -import { cn } from "@/lib/utils" - -function Separator({ - className, - orientation = "horizontal", - decorative = true, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -export { Separator } diff --git a/packages/shadcn-ui/@/components/ui/sheet.tsx b/packages/shadcn-ui/@/components/ui/sheet.tsx deleted file mode 100644 index 84649ad0..00000000 --- a/packages/shadcn-ui/@/components/ui/sheet.tsx +++ /dev/null @@ -1,139 +0,0 @@ -"use client" - -import * as React from "react" -import * as SheetPrimitive from "@radix-ui/react-dialog" -import { XIcon } from "lucide-react" - -import { cn } from "@/lib/utils" - -function Sheet({ ...props }: React.ComponentProps) { - return -} - -function SheetTrigger({ - ...props -}: React.ComponentProps) { - return -} - -function SheetClose({ - ...props -}: React.ComponentProps) { - return -} - -function SheetPortal({ - ...props -}: React.ComponentProps) { - return -} - -function SheetOverlay({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -function SheetContent({ - className, - children, - side = "right", - ...props -}: React.ComponentProps & { - side?: "top" | "right" | "bottom" | "left" -}) { - return ( - - - - {children} - - - Close - - - - ) -} - -function SheetHeader({ className, ...props }: React.ComponentProps<"div">) { - return ( -
- ) -} - -function SheetFooter({ className, ...props }: React.ComponentProps<"div">) { - return ( -
- ) -} - -function SheetTitle({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -function SheetDescription({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -export { - Sheet, - SheetTrigger, - SheetClose, - SheetContent, - SheetHeader, - SheetFooter, - SheetTitle, - SheetDescription, -} diff --git a/packages/shadcn-ui/@/components/ui/sidebar.tsx b/packages/shadcn-ui/@/components/ui/sidebar.tsx deleted file mode 100644 index 7ffbc078..00000000 --- a/packages/shadcn-ui/@/components/ui/sidebar.tsx +++ /dev/null @@ -1,726 +0,0 @@ -"use client" - -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { VariantProps, cva } from "class-variance-authority" -import { PanelLeftIcon } from "lucide-react" - -import { useIsMobile } from "@/hooks/use-mobile" -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Separator } from "@/components/ui/separator" -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, -} from "@/components/ui/sheet" -import { Skeleton } from "@/components/ui/skeleton" -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip" - -const SIDEBAR_COOKIE_NAME = "sidebar_state" -const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 -const SIDEBAR_WIDTH = "16rem" -const SIDEBAR_WIDTH_MOBILE = "18rem" -const SIDEBAR_WIDTH_ICON = "3rem" -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) - } - - // This sets the cookie to keep the sidebar state. - document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` - }, - [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, - ...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, - ...props -}: React.ComponentProps) { - const { toggleSidebar } = useSidebar() - - return ( - - ) -} - -function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { - const { toggleSidebar } = useSidebar() - - return ( - - ); + ) } function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { - const { toggleSidebar } = useSidebar(); + const { toggleSidebar } = useSidebar() return (