adding dark mode to feat/refresh

This commit is contained in:
Doug Andrade
2023-06-11 01:50:19 -04:00
parent b0e364acf4
commit 877a579533
21 changed files with 217 additions and 73 deletions

View File

@ -24,13 +24,14 @@
"next": "13.4.1",
"next-auth": "^4.22.1",
"next-plausible": "^3.7.2",
"next-themes": "^0.2.1",
"perfect-freehand": "^1.2.0",
"react": "18.2.0",
"react-pdf": "^7.1.1",
"react-dom": "18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.43.9",
"react-icons": "^4.8.0",
"react-pdf": "^7.1.1",
"typescript": "5.0.4",
"zod": "^3.21.4"
},

View File

@ -48,7 +48,7 @@ export default async function DashboardPage() {
<h2 className="mt-8 text-2xl font-semibold">Recent Documents</h2>
<div className="mt-8 overflow-x-auto rounded-lg border border-slate-200">
<div className="border-border mt-8 overflow-x-auto rounded-lg border">
<Table>
<TableHeader>
<TableRow>
@ -65,7 +65,7 @@ export default async function DashboardPage() {
<TableCell>
<Link
href={`/documents/${document.id}`}
className="font-medium hover:underline"
className="focus-visible:ring-ring ring-offset-background rounded-md font-medium hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
>
{document.title}
</Link>

View File

@ -45,7 +45,7 @@ export default async function DocumentPage({ params }: DocumentPageProps) {
className="mt-4 max-w-xs truncate text-2xl font-semibold md:text-3xl"
title={document.title}
>
Document.pdf
{document.title}
</h1>
<EditDocumentForm className="mt-8" document={document} user={session} />

View File

@ -3,6 +3,7 @@ import { Inter } from 'next/font/google';
import { TrpcProvider } from '@documenso/trpc/react';
import { Toaster } from '@documenso/ui/primitives/toaster';
import { ThemeProvider } from '~/providers/next-theme';
import { PlausibleProvider } from '~/providers/plausible';
import './globals.css';
@ -45,7 +46,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<body>
<PlausibleProvider>
<TrpcProvider>{children}</TrpcProvider>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<TrpcProvider>{children}</TrpcProvider>
</ThemeProvider>
</PlausibleProvider>
<Toaster />
</body>

View File

@ -2,6 +2,7 @@
import { Variants, motion } from 'framer-motion';
import { Plus } from 'lucide-react';
import { useTheme } from 'next-themes';
import { useDropzone } from 'react-dropzone';
import { cn } from '@documenso/ui/lib/utils';
@ -91,6 +92,8 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
},
});
const { theme } = useTheme();
return (
<motion.div
className={cn('flex', className)}
@ -101,9 +104,13 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
>
<Card
role="button"
className={cn('flex flex-1 cursor-pointer flex-col items-center justify-center', className)}
className={cn(
'focus-visible:ring-ring ring-offset-background flex flex-1 cursor-pointer flex-col items-center justify-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
className,
)}
gradient={true}
degrees={120}
lightMode={theme === 'light'}
{...getRootProps()}
{...props}
>
@ -111,39 +118,41 @@ export const DocumentDropzone = ({ className, onDrop, ...props }: DocumentDropzo
{/* <FilePlus strokeWidth="1px" className="h-16 w-16"/> */}
<div className="flex">
<motion.div
className="border-muted-foreground/20 group-hover:border-primary/80 z-10 flex aspect-[3/4] w-24 origin-top-right -rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-right -rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
variants={DocumentDropzoneCardLeftVariants}
>
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-5/6 rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
</motion.div>
<motion.div
className="border-muted-foreground/20 group-hover:border-primary/80 z-20 flex aspect-[3/4] w-24 flex-col items-center justify-center gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-20 flex aspect-[3/4] w-24 flex-col items-center justify-center gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
variants={DocumentDropzoneCardCenterVariants}
>
<Plus
strokeWidth="2px"
className="text-muted-foreground/20 group-hover:text-primary h-12 w-12"
className="text-muted-foreground/20 group-hover:text-documenso h-12 w-12"
/>
</motion.div>
<motion.div
className="border-muted-foreground/20 group-hover:border-primary/80 z-10 flex aspect-[3/4] w-24 origin-top-left rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 origin-top-left rotate-[22deg] flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm"
variants={DocumentDropzoneCardRightVariants}
>
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-5/6 rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-primary h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
</motion.div>
</div>
<input {...getInputProps()} />
<p className="group-hover:text-primary mt-8 font-medium">Add a document</p>
<p className="group-hover:text-foreground text-muted-foreground mt-8 font-medium">
Add a document
</p>
<p className="mt-1 text-sm">Drag & drop your document here.</p>
<p className="text-muted-foreground/80 mt-1 text-sm ">Drag & drop your document here.</p>
</CardContent>
</Card>
</motion.div>

View File

@ -16,17 +16,23 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
<div className={cn('ml-8 hidden flex-1 gap-x-6 md:flex', className)} {...props}>
<Link
href="/dashboard"
className={cn('font-medium leading-5 text-[#A1A1AA] hover:opacity-80', {
'text-primary-foreground': pathname?.startsWith('/dashboard'),
})}
className={cn(
'text-muted-foreground focus-visible:ring-ring ring-offset-background rounded-md font-medium leading-5 hover:opacity-80 focus-visible:outline-none focus-visible:ring-2',
{
'text-foreground': pathname?.startsWith('/dashboard'),
},
)}
>
Dashboard
</Link>
<Link
href="/documents"
className={cn('font-medium leading-5 text-[#A1A1AA] hover:opacity-80', {
'text-primary-foreground': pathname?.startsWith('/documents'),
})}
className={cn(
'text-muted-foreground focus-visible:ring-ring ring-offset-background rounded-md font-medium leading-5 hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 ',
{
'text-foreground': pathname?.startsWith('/documents'),
},
)}
>
Documents
</Link>

View File

@ -29,7 +29,10 @@ export const Header = ({ className, user, ...props }: HeaderProps) => {
{...props}
>
<div className="mx-auto flex w-full max-w-screen-xl items-center justify-between gap-x-4 px-4 md:justify-normal md:px-8">
<Link href="/">
<Link
href="/"
className="focus-visible:ring-ring ring-offset-background rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
>
<Logo className="h-6 w-auto" />
</Link>

View File

@ -2,8 +2,18 @@
import Link from 'next/link';
import { CreditCard, Github, Key, LogOut, User as LucideUser } from 'lucide-react';
import {
CreditCard,
Github,
Key,
LogOut,
User as LucideUser,
Monitor,
Moon,
Sun,
} from 'lucide-react';
import { signOut } from 'next-auth/react';
import { useTheme } from 'next-themes';
import { IS_SUBSCRIPTIONS_ENABLED } from '@documenso/lib/constants/features';
import { User } from '@documenso/prisma/client';
@ -26,10 +36,12 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => {
const initials =
user.name
?.split(' ')
.map((name) => name.slice(0, 1).toUpperCase())
.map((name: string) => name.slice(0, 1).toUpperCase())
.slice(0, 2)
.join('') ?? 'UK';
const { theme, setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
@ -68,6 +80,28 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => {
<DropdownMenuSeparator />
{theme === 'light' ? null : (
<DropdownMenuItem onClick={() => setTheme('light')}>
<Sun className="mr-2 h-4 w-4" />
Light Mode
</DropdownMenuItem>
)}
{theme === 'dark' ? null : (
<DropdownMenuItem onClick={() => setTheme('dark')}>
<Moon className="mr-2 h-4 w-4" />
Dark Mode
</DropdownMenuItem>
)}
{theme === 'system' ? null : (
<DropdownMenuItem onClick={() => setTheme('system')}>
<Monitor className="mr-2 h-4 w-4" />
System Theme
</DropdownMenuItem>
)}
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link href="https://github.com/documenso/documenso" className="cursor-pointer">
<Github className="mr-2 h-4 w-4" />

View File

@ -13,7 +13,7 @@ export type CardMetricProps = {
export const CardMetric = ({ icon: Icon, title, value, className }: CardMetricProps) => {
return (
<div className={cn('overflow-hidden rounded-lg border border-slate-200 bg-white', className)}>
<div className={cn('border-border bg-background overflow-hidden rounded-lg border', className)}>
<div className="px-4 pb-6 pt-4 sm:px-4 sm:pb-8 sm:pt-4">
<div className="flex items-start">
{Icon && <Icon className="mr-2 h-4 w-4 text-slate-500" />}
@ -21,7 +21,7 @@ export const CardMetric = ({ icon: Icon, title, value, className }: CardMetricPr
<h3 className="flex items-end text-sm font-medium text-slate-500">{title}</h3>
</div>
<p className="mt-6 text-4xl font-semibold leading-8 text-gray-900 md:mt-8">
<p className="text-foreground mt-6 text-4xl font-semibold leading-8 md:mt-8">
{typeof value === 'number' ? value.toLocaleString('en-US') : value}
</p>
</div>

View File

@ -132,7 +132,7 @@ export const PDFViewer = ({ className, document, onPageClick, ...props }: PDFVie
.map((_, i) => (
<div
key={i}
className="border-primary/50 my-8 overflow-hidden rounded border first:mt-0 last:mb-0"
className="border-border my-8 overflow-hidden rounded border first:mt-0 last:mb-0"
>
<PDFPage
pageNumber={i + 1}

View File

@ -6,6 +6,7 @@ import dynamic from 'next/dynamic';
import { zodResolver } from '@hookform/resolvers/zod';
import { Loader } from 'lucide-react';
import { useTheme } from 'next-themes';
import { useForm } from 'react-hook-form';
import { Document, User } from '@documenso/prisma/client';
@ -20,10 +21,10 @@ import { TEditDocumentFormSchema, ZEditDocumentFormSchema } from './edit-documen
const PDFViewer = dynamic(async () => import('~/components/(dashboard)/pdf-viewer/pdf-viewer'), {
ssr: false,
loading: () => (
<div className="flex min-h-[80vh] flex-col items-center justify-center bg-white/50">
<Loader className="h-12 w-12 animate-spin text-slate-500" />
<div className="dark:bg-background flex min-h-[80vh] flex-col items-center justify-center bg-white/50">
<Loader className="text-muted-foreground h-12 w-12 animate-spin" />
<p className="mt-4 text-slate-500">Loading document...</p>
<p className="text-muted-foreground mt-4">Loading document...</p>
</div>
),
});
@ -59,6 +60,8 @@ export const EditDocumentForm = ({ className, document, user: _user }: EditDocum
resolver: zodResolver(ZEditDocumentFormSchema),
});
const { theme } = useTheme();
const canGoBack = step > 0;
const canGoNext = isValid && step < MAX_STEP;
@ -67,14 +70,18 @@ export const EditDocumentForm = ({ className, document, user: _user }: EditDocum
return (
<div className={cn('grid w-full grid-cols-12 gap-x-8', className)}>
<Card className="col-span-7 rounded-xl before:rounded-xl" gradient>
<Card
className="col-span-7 rounded-xl before:rounded-xl"
gradient
lightMode={theme === 'light'}
>
<CardContent className="p-2">
<PDFViewer document={documentUrl} />
</CardContent>
</Card>
<div className="relative col-span-5">
<div className="sticky top-20 flex h-[calc(100vh-6rem)] max-h-screen flex-col rounded-xl border bg-[hsl(var(--widget))] px-4 py-6">
<div className="dark:bg-background border-border sticky top-20 flex h-[calc(100vh-6rem)] max-h-screen flex-col rounded-xl border bg-[hsl(var(--widget))] px-4 py-6">
{step === 0 && (
<AddSignersFormPartial
className="-mx-2 flex-1 overflow-y-hidden px-2"
@ -91,17 +98,18 @@ export const EditDocumentForm = ({ className, document, user: _user }: EditDocum
watch={watch}
errors={errors}
isSubmitting={isSubmitting}
theme={theme || 'dark'}
/>
)}
<div className="mt-4 flex-shrink-0">
<p className="text-sm text-black/30">
<p className="text-muted-foreground text-sm">
Add Signers ({step + 1}/{MAX_STEP + 1})
</p>
<div className="relative mt-4 h-[2px] rounded-md bg-slate-300">
<div className="bg-muted relative mt-4 h-[2px] rounded-md">
<div
className="bg-primary absolute inset-y-0 left-0"
className="bg-documenso absolute inset-y-0 left-0"
style={{
width: `${(100 / (MAX_STEP + 1)) * (step + 1)}%`,
}}
@ -110,7 +118,7 @@ export const EditDocumentForm = ({ className, document, user: _user }: EditDocum
<div className="mt-4 flex gap-x-4">
<Button
className="flex-1 bg-black/5 hover:bg-black/10"
className="dark:bg-muted dark:hover:bg-muted/80 flex-1 bg-black/5 hover:bg-black/10"
size="lg"
variant="secondary"
disabled={!canGoBack}
@ -119,7 +127,12 @@ export const EditDocumentForm = ({ className, document, user: _user }: EditDocum
Go Back
</Button>
<Button className="flex-1" size="lg" disabled={!canGoNext} onClick={onGoNextClick}>
<Button
className="bg-documenso flex-1"
size="lg"
disabled={!canGoNext}
onClick={onGoNextClick}
>
Continue
</Button>
</div>

View File

@ -34,6 +34,7 @@ export type AddFieldsFormProps = {
watch: UseFormWatch<TEditDocumentFormSchema>;
errors: FieldErrors<TEditDocumentFormSchema>;
isSubmitting: boolean;
theme: string;
};
export const AddFieldsFormPartial = ({
@ -42,6 +43,7 @@ export const AddFieldsFormPartial = ({
watch,
errors: _errors,
isSubmitting: _isSubmitting,
theme,
}: AddFieldsFormProps) => {
const signers = watch('signers');
@ -51,7 +53,9 @@ export const AddFieldsFormPartial = ({
<div className={cn('flex flex-col', className)}>
<h3 className="text-2xl font-semibold">Edit Document</h3>
<p className="mt-2 text-sm text-black/30">Add all relevant fields for each recipient.</p>
<p className="text-muted-foreground mt-2 text-sm">
Add all relevant fields for each recipient.
</p>
<hr className="mb-8 mt-4" />
@ -60,7 +64,7 @@ export const AddFieldsFormPartial = ({
<Button
variant="outline"
role="combobox"
className="justify-between bg-white font-normal text-slate-500"
className="bg-background text-muted-foreground justify-between font-normal"
>
{selectedSigner.name && (
<span>
@ -103,56 +107,80 @@ export const AddFieldsFormPartial = ({
</Popover>
<div className="-mx-2 mt-8 flex-1 overflow-y-scroll px-2">
<div className="grid grid-cols-2 gap-x-4 gap-y-8">
<div className="mt-4 grid grid-cols-2 gap-x-4 gap-y-8">
<button className="group h-full w-full">
<Card className="group-focus:border-primary h-full w-full cursor-pointer">
<Card
className="group-focus:border-documenso h-full w-full cursor-pointer"
lightMode={theme === 'light'}
>
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
<p
className={cn(
'text-3xl font-medium text-slate-500 group-focus:text-slate-900',
'text-muted-foreground group-focus:text-foreground text-3xl font-medium',
fontCaveat.className,
)}
>
{selectedSigner.name || 'Signature'}
</p>
<p className="mt-2 text-center text-xs text-slate-500">Signature</p>
<p className="text-muted-foreground mt-2 text-center text-xs">Signature</p>
</CardContent>
</Card>
</button>
<button className="group h-full w-full">
<Card className="group-focus:border-primary h-full w-full cursor-pointer">
<Card
className="group-focus:border-documenso h-full w-full cursor-pointer"
lightMode={theme === 'light'}
>
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
<p className={cn('text-xl font-medium text-slate-500 group-focus:text-slate-900')}>
<p
className={cn(
'text-muted-foreground group-focus:text-foreground text-xl font-medium',
)}
>
{'Email'}
</p>
<p className="mt-2 text-xs text-slate-500">Email</p>
<p className="text-muted-foreground mt-2 text-xs">Email</p>
</CardContent>
</Card>
</button>
<button className="group h-full w-full">
<Card className="group-focus:border-primary h-full w-full cursor-pointer">
<Card
className="group-focus:border-documenso h-full w-full cursor-pointer"
lightMode={theme === 'light'}
>
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
<p className={cn('text-xl font-medium text-slate-500 group-focus:text-slate-900')}>
<p
className={cn(
'text-muted-foreground group-focus:text-foreground text-xl font-medium',
)}
>
{'Name'}
</p>
<p className="mt-2 text-xs text-slate-500">Name</p>
<p className="text-muted-foreground mt-2 text-xs">Name</p>
</CardContent>
</Card>
</button>
<button className="group h-full w-full">
<Card className="group-focus:border-primary h-full w-full cursor-pointer">
<Card
className="group-focus:border-documenso h-full w-full cursor-pointer"
lightMode={theme === 'light'}
>
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
<p className={cn('text-xl font-medium text-slate-500 group-focus:text-slate-900')}>
<p
className={cn(
'text-muted-foreground group-focus:text-foreground text-xl font-medium',
)}
>
{'Date'}
</p>
<p className="mt-2 text-xs text-slate-500">Date</p>
<p className="text-muted-foreground mt-2 text-xs">Date</p>
</CardContent>
</Card>
</button>

View File

@ -37,11 +37,13 @@ export const AddSignersFormPartial = ({
return (
<div className={cn('flex flex-col', className)}>
<h3 className="text-2xl font-semibold">Add Signers</h3>
<h3 className="text-foreground text-2xl font-semibold">Add Signers</h3>
<p className="mt-2 text-sm text-black/30">Add the people who will sign the document.</p>
<p className="text-muted-foreground mt-2 text-sm">
Add the people who will sign the document.
</p>
<hr className="mb-8 mt-4" />
<hr className="border-border mb-8 mt-4" />
<div className="-mx-2 flex flex-1 flex-col overflow-y-scroll px-2">
<div className="flex w-full flex-col gap-y-4">
@ -58,7 +60,7 @@ export const AddSignersFormPartial = ({
<Input
id={`signer-${index}-email`}
type="email"
className="mt-2 bg-white"
className="bg-background mt-2"
disabled={isSubmitting}
{...field}
/>
@ -76,7 +78,7 @@ export const AddSignersFormPartial = ({
<Input
id={`signer-${index}-name`}
type="text"
className="mt-2 bg-white"
className="bg-background mt-2"
disabled={isSubmitting}
{...field}
/>

View File

@ -89,7 +89,12 @@ export const PasswordForm = ({ className }: PasswordFormProps) => {
Password
</Label>
<Input id="password" type="password" className="mt-2 bg-white" {...register('password')} />
<Input
id="password"
type="password"
className="bg-background mt-2"
{...register('password')}
/>
<FormErrorMessage className="mt-1.5" error={errors.password} />
</div>
@ -102,7 +107,7 @@ export const PasswordForm = ({ className }: PasswordFormProps) => {
<Input
id="repeated-password"
type="password"
className="mt-2 bg-white"
className="bg-background mt-2"
{...register('repeatedPassword')}
/>

View File

@ -87,7 +87,7 @@ export const ProfileForm = ({ className, user }: ProfileFormProps) => {
Full Name
</Label>
<Input id="full-name" type="text" className="mt-2 bg-white" {...register('name')} />
<Input id="full-name" type="text" className="bg-background mt-2" {...register('name')} />
<FormErrorMessage className="mt-1.5" error={errors.name} />
</div>
@ -97,7 +97,7 @@ export const ProfileForm = ({ className, user }: ProfileFormProps) => {
Email
</Label>
<Input id="email" type="email" className="mt-2 bg-white" value={user.email} disabled />
<Input id="email" type="email" className="bg-muted mt-2" value={user.email} disabled />
</div>
<div>
@ -111,7 +111,7 @@ export const ProfileForm = ({ className, user }: ProfileFormProps) => {
name="signature"
render={({ field: { onChange } }) => (
<SignaturePad
className="h-44 w-full rounded-lg border bg-white backdrop-blur-sm"
className="bg-background h-44 w-full rounded-lg border backdrop-blur-sm"
onChange={(v) => onChange(v ?? '')}
/>
)}

View File

@ -205,7 +205,7 @@ export const SignaturePad = ({ className, onChange, ...props }: SignaturePadProp
<div className="absolute bottom-2 right-2">
<button
type="button"
className="rounded-full p-2 text-xs text-slate-500"
className="focus-visible:ring-ring ring-offset-background rounded-full p-2 text-xs text-slate-500 focus-visible:outline-none focus-visible:ring-2"
onClick={() => onClearClick()}
>
Clear Signature

View File

@ -0,0 +1,10 @@
'use client';
import * as React from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { ThemeProviderProps } from 'next-themes/dist/types';
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

18
package-lock.json generated
View File

@ -67,6 +67,7 @@
"next": "13.4.1",
"next-auth": "^4.22.1",
"next-plausible": "^3.7.2",
"next-themes": "^0.2.1",
"perfect-freehand": "^1.2.0",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -5694,6 +5695,16 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
"integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==",
"peerDependencies": {
"next": "*",
"react": "*",
"react-dom": "*"
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
@ -8970,6 +8981,7 @@
"next": "13.4.1",
"next-auth": "^4.22.1",
"next-plausible": "^3.7.2",
"next-themes": "^0.2.1",
"perfect-freehand": "^1.2.0",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -12696,6 +12708,12 @@
"integrity": "sha512-9PqFiVtD1kZO5gHFYTcgilHhg2WhMzD6I4NK/RUh9DGavD1N11IhNAvyGLFmvB3f4FtHC9IoAsauYDtQBt+riA==",
"requires": {}
},
"next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
"integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==",
"requires": {}
},
"node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",

View File

@ -3,7 +3,7 @@ const { fontFamily } = require('tailwindcss/defaultTheme');
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class', '[data-theme="dark"]'],
darkMode: ['class'],
content: ['src/**/*.{ts,tsx}'],
theme: {
extend: {

View File

@ -10,10 +10,22 @@ export type CardProps = React.HTMLAttributes<HTMLDivElement> & {
spotlight?: boolean;
gradient?: boolean;
degrees?: number;
lightMode?: boolean;
};
const Card = React.forwardRef<HTMLDivElement, CardProps>(
({ className, children, gradient = false, spotlight = false, degrees = 120, ...props }, ref) => {
(
{
className,
children,
gradient = false,
spotlight = false,
degrees = 120,
lightMode = true,
...props
},
ref,
) => {
const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0);
@ -34,12 +46,12 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
} as React.CSSProperties
}
className={cn(
'group relative rounded-lg border-2 bg-white/50 text-slate-900 backdrop-blur-[2px]',
'bg-background text-foreground dark:hover:border-documenso group relative rounded-lg border-2 backdrop-blur-[2px]',
{
'gradient-border-mask before:pointer-events-none before:absolute before:-inset-[2px] before:rounded-lg before:p-[2px] before:[background:linear-gradient(var(--card-gradient-degrees),theme(colors.primary.DEFAULT/50%)_5%,theme(colors.card.DEFAULT/80%)_30%)]':
gradient,
'gradient-border-mask before:pointer-events-none before:absolute before:-inset-[2px] before:rounded-lg before:p-[2px] before:[background:linear-gradient(var(--card-gradient-degrees),theme(colors.documenso.DEFAULT/50%)_5%,theme(colors.border/80%)_30%)]':
gradient && lightMode,
'shadow-[0_0_0_4px_theme(colors.gray.100/70%),0_0_0_1px_theme(colors.gray.100/70%),0_0_0_0.5px_theme(colors.primary.DEFAULT/70%)]':
true,
lightMode,
},
className,
)}

View File

@ -70,7 +70,7 @@
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--ring: 216 34% 17%;
--ring: 95.08 71.08% 67.45%;
--radius: 0.5rem;
}