diff --git a/package-lock.json b/package-lock.json index d84cfc4..ab823a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,12 @@ "dependencies": { "@hookform/resolvers": "^3.7.0", "@radix-ui/react-checkbox": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-navigation-menu": "^1.2.0", + "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", @@ -2938,6 +2940,41 @@ } } }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", @@ -3294,6 +3331,36 @@ } } }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.1.0.tgz", + "integrity": "sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-select": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.1.tgz", diff --git a/package.json b/package.json index 762df19..bc5b852 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,12 @@ "dependencies": { "@hookform/resolvers": "^3.7.0", "@radix-ui/react-checkbox": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-navigation-menu": "^1.2.0", + "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", diff --git a/src/components/download.tsx b/src/components/download.tsx index d928454..4b7932a 100644 --- a/src/components/download.tsx +++ b/src/components/download.tsx @@ -19,7 +19,7 @@ function getDefaultPlatformBasedOnUserAgent() { userAgent = window.navigator.userAgent; } if (userAgent.includes("Win")) { - return "WindowsStubInstaller"; + return "WindowsInstaller"; } if (userAgent.includes("Mac")) { return "MacOS"; @@ -56,8 +56,8 @@ export default function DownloadPage() { } return ( -
-
+
+
-
-
+
+
+
Zen Browser © {new Date().getFullYear()} - Made with ❤️ by the Zen team. - Source Code + Source Code
); } diff --git a/src/components/mobile-nav.tsx b/src/components/mobile-nav.tsx new file mode 100644 index 0000000..25a4c06 --- /dev/null +++ b/src/components/mobile-nav.tsx @@ -0,0 +1,100 @@ +'use client' + +import { SidebarOpen } from 'lucide-react' +import type { LinkProps } from 'next/link' +import Link from 'next/link' +import { useRouter } from 'next/navigation' +import * as React from 'react' +import { Sheet, SheetContent, SheetTrigger } from './ui/sheet' +import { Button } from './ui/button' +import { ScrollArea } from './ui/scroll-area' +import Logo from './logo' +import { ny } from '@/lib/utils' +import { components } from './navigation' + +export function MobileNav() { + const [open, setOpen] = React.useState(false) + + return ( + + + + + + + + + +
+ + Download + + + Release Notes + + + Source Code + + {components.map(({title, href, description}) => ( + + {title} + + ))} +
+
+
+
+ ) +} + +interface MobileLinkProps extends LinkProps { + onOpenChange?: (open: boolean) => void + children: React.ReactNode + className?: string +} + +function MobileLink({ + href, + onOpenChange, + className, + children, + ...props +}: MobileLinkProps) { + const router = useRouter() + return ( + { + router.push(href.toString()) + onOpenChange?.(false) + }} + className={ny(className)} + {...props} + > + {children} + + ) +} \ No newline at end of file diff --git a/src/components/navigation.tsx b/src/components/navigation.tsx index e4e6e4c..c156354 100644 --- a/src/components/navigation.tsx +++ b/src/components/navigation.tsx @@ -15,8 +15,9 @@ import { } from "@/components/ui/navigation-menu" import Logo from "./logo" import { ModeToggle } from "./mode-toggle" +import { MobileNav } from "./mobile-nav" -const components: { title: string; href: string; description: string }[] = [ +export const components: { title: string; href: string; description: string }[] = [ { title: "Privacy Policy", href: "/privacy-policy", @@ -32,8 +33,9 @@ const components: { title: string; href: string; description: string }[] = [ export function Navigation() { return (
+ - + diff --git a/src/components/release-note.tsx b/src/components/release-note.tsx index abc022d..df7f71d 100644 --- a/src/components/release-note.tsx +++ b/src/components/release-note.tsx @@ -6,7 +6,7 @@ import { Button } from "./ui/button"; export default function ReleaseNoteElement({ data }: { data: ReleaseNote }) { return (
-
+

Release notes for {data.version} 🎉

{data.date}

{data.extra && ( diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx new file mode 100644 index 0000000..cebe705 --- /dev/null +++ b/src/components/ui/scroll-area.tsx @@ -0,0 +1,48 @@ +'use client' + +import * as React from 'react' +import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area' + +import { ny } from '@/lib/utils' + +const ScrollArea = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + {children} + + + + +)) +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName + +const ScrollBar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, orientation = 'vertical', ...props }, ref) => ( + + + +)) +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName + +export { ScrollArea, ScrollBar } diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx new file mode 100644 index 0000000..045e231 --- /dev/null +++ b/src/components/ui/sheet.tsx @@ -0,0 +1,144 @@ +'use client' + +import * as React from 'react' +import * as SheetPrimitive from '@radix-ui/react-dialog' +import { Cross2Icon } from '@radix-ui/react-icons' +import { type VariantProps, cva } from 'class-variance-authority' + +import { ny } from '@/lib/utils' + +const Sheet = SheetPrimitive.Root + +const SheetTrigger = SheetPrimitive.Trigger + +const SheetClose = SheetPrimitive.Close + +const SheetPortal = SheetPrimitive.Portal + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName + +const sheetVariants = cva( + 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out', + { + variants: { + side: { + top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top', + bottom: + 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom', + left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm', + right: + 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm', + }, + }, + defaultVariants: { + side: 'right', + }, + }, +) + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = 'right', className, children, ...props }, ref) => ( + + + + + + Close + + {children} + + +)) +SheetContent.displayName = SheetPrimitive.Content.displayName + +function SheetHeader({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ) +} +SheetHeader.displayName = 'SheetHeader' + +function SheetFooter({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ) +} +SheetFooter.displayName = 'SheetFooter' + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetTitle.displayName = SheetPrimitive.Title.displayName + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetDescription.displayName = SheetPrimitive.Description.displayName + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +}