Add button animations

This commit is contained in:
Richard Roberson 2025-01-26 20:43:42 -07:00
parent edb0b962d3
commit f9ab9190c2
6 changed files with 32 additions and 34 deletions

View file

@ -10,20 +10,19 @@ export default function Home() {
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
return (
<div className='p-4'>
<div className='p-3 md:p-5'>
<div className="flex justify-between items-center mb-6">
<h1 className="text-xl font-bold text-center flex-grow">OpenReader WebUI</h1>
<button
onClick={() => setIsSettingsOpen(true)}
className="rounded-full p-2.5 text-foreground hover:bg-base focus:bg-base
focus:outline-none focus:ring-2 focus:ring-accent transition-colors"
className="rounded-full p-2 text-foreground hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.1] hover:text-accent"
aria-label="Settings"
>
<SettingsIcon className="w-6 h-6 hover:animate-spin-slow" />
</button>
</div>
<div className="flex flex-col items-center gap-6">
<PDFUploader className="w-full max-w-md" />
<div className="flex flex-col items-center gap-5">
<PDFUploader className='max-w-xl' />
<DocumentList />
</div>
<SettingsModal isOpen={isSettingsOpen} setIsOpen={setIsSettingsOpen} />

View file

@ -79,9 +79,9 @@ export default function PDFViewerPage() {
<Link
href="/"
onClick={() => {clearCurrDoc(); stop();}}
className="inline-flex items-center px-3 py-1 bg-base text-foreground rounded-lg hover:bg-offbase transition-colors"
className="inline-flex items-center px-3 py-1 bg-base text-foreground rounded-lg hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.02]"
>
<svg className="w-4 h-4 mr-2 text-muted" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 mr-2" fill="currentColor" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Documents
@ -89,7 +89,7 @@ export default function PDFViewerPage() {
<div className="bg-offbase px-2 py-0.5 rounded-full flex items-center gap-2">
<Button
onClick={handleZoomOut}
className="text-xs hover:text-accent transition-colors"
className="text-xs transform transition-transform duration-200 ease-in-out hover:scale-[1.45] hover:font-semibold hover:text-accent"
aria-label="Zoom out"
>
@ -97,7 +97,7 @@ export default function PDFViewerPage() {
<span className="text-xs">{zoomLevel}%</span>
<Button
onClick={handleZoomIn}
className="text-xs hover:text-accent transition-colors"
className="text-xs transform transition-transform duration-200 ease-in-out hover:scale-[1.45] hover:font-semibold hover:text-accent"
aria-label="Zoom in"
>
@ -105,8 +105,7 @@ export default function PDFViewerPage() {
</div>
<Button
onClick={() => setIsSettingsOpen(true)}
className="rounded-full p-2 text-foreground hover:bg-offbase focus:bg-offbase
focus:outline-none focus:ring-2 focus:ring-accent transition-colors"
className="rounded-full p-1 text-foreground hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.1] hover:text-accent"
aria-label="View Settings"
>
<SettingsIcon className="w-5 h-5 hover:animate-spin-slow" />

View file

@ -1,6 +1,6 @@
import { usePDF } from '@/contexts/PDFContext';
import Link from 'next/link';
import { Dialog } from '@headlessui/react';
import { Button, Dialog } from '@headlessui/react';
import { Transition, TransitionChild, DialogPanel, DialogTitle } from '@headlessui/react';
import { Fragment, useState } from 'react';
@ -38,7 +38,7 @@ export function DocumentList() {
}
return (
<div className="w-full max-w-3xl mx-auto">
<div className="w-full mx-auto">
<h2 className="text-xl font-semibold mb-4 text-foreground">Your Documents</h2>
<div className="bg-background rounded-lg shadow p-2 space-y-2">
{documents.map((doc) => (
@ -64,14 +64,14 @@ export function DocumentList() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>
</div>
<div className="flex-1 min-w-0">
<div className="flex-1 min-w-0 transform transition-transform duration-200 ease-in-out hover:scale-[1.02]">
<p className="text-foreground font-medium truncate">{doc.name}</p>
<p className="text-sm text-muted truncate">
{(doc.size / 1024 / 1024).toFixed(2)} MB
</p>
</div>
</Link>
<button
<Button
onClick={() => {
setDocumentToDelete({ id: doc.id, name: doc.name });
setIsDeleteDialogOpen(true);
@ -82,7 +82,7 @@ export function DocumentList() {
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</button>
</Button>
</div>
</Transition>
))}
@ -131,20 +131,20 @@ export function DocumentList() {
</div>
<div className="mt-4 flex justify-end space-x-3">
<button
<Button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-base px-4 py-2 text-sm font-medium text-foreground hover:bg-base/80 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2"
onClick={() => setIsDeleteDialogOpen(false)}
>
Cancel
</button>
<button
</Button>
<Button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-2"
onClick={handleDelete}
>
Delete
</button>
</Button>
</div>
</DialogPanel>
</TransitionChild>

View file

@ -45,7 +45,7 @@ export function PDFUploader({ className = '' }: PDFUploaderProps) {
className={`
w-full py-5 px-3 border-2 border-dashed rounded-lg
${isDragActive ? 'border-accent bg-base' : 'border-muted'}
transition-colors duration-200 ease-in-out
transform trasition-transform duration-200 ease-in-out hover:scale-[1.008]
${isUploading ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:border-accent hover:bg-base'}
${className}
`}

View file

@ -1,7 +1,7 @@
'use client';
import { Fragment } from 'react';
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, Listbox, ListboxButton, ListboxOptions, ListboxOption } from '@headlessui/react';
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, Listbox, ListboxButton, ListboxOptions, ListboxOption, Button } from '@headlessui/react';
import { useConfig, ViewType } from '@/contexts/ConfigContext';
import { ChevronUpDownIcon, CheckIcon } from '@/components/icons/Icons';
@ -62,7 +62,7 @@ export function PDFViewSettings({ isOpen, setIsOpen }: PDFViewSettingsProps) {
onChange={(newView) => updateConfigKey('viewType', newView.id as ViewType)}
>
<div className="relative">
<ListboxButton className="relative w-full cursor-pointer rounded-lg bg-background py-2 pl-3 pr-10 text-left text-foreground shadow-sm focus:outline-none focus:ring-2 focus:ring-accent">
<ListboxButton className="relative w-full cursor-pointer rounded-lg bg-background py-2 pl-3 pr-10 text-left text-foreground shadow-sm focus:outline-none focus:ring-2 focus:ring-accent transform transition-transform duration-200 ease-in-out hover:scale-[1.01] hover:text-accent">
<span className="block truncate">{selectedView.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon className="h-5 w-5 text-muted" />
@ -113,16 +113,16 @@ export function PDFViewSettings({ isOpen, setIsOpen }: PDFViewSettingsProps) {
</div>
<div className="mt-3 flex justify-end">
<button
<Button
type="button"
className="inline-flex justify-center rounded-lg bg-background px-4 py-2 text-sm
font-medium text-foreground hover:bg-background/90 focus:outline-none
focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2
transition-colors"
transform transition-transform duration-200 ease-in-out hover:scale-[1.04] hover:text-accent"
onClick={() => setIsOpen(false)}
>
Close
</button>
</Button>
</div>
</DialogPanel>
</TransitionChild>

View file

@ -1,7 +1,7 @@
'use client';
import { Fragment, useState, useEffect } from 'react';
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, Listbox, ListboxButton, ListboxOptions, ListboxOption } from '@headlessui/react';
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, Listbox, ListboxButton, ListboxOptions, ListboxOption, Button } from '@headlessui/react';
import { useTheme } from '@/contexts/ThemeContext';
import { useConfig } from '@/contexts/ConfigContext';
import { ChevronUpDownIcon, CheckIcon } from './icons/Icons';
@ -68,7 +68,7 @@ export function SettingsModal({ isOpen, setIsOpen }: SettingsModalProps) {
<label className="block text-sm font-medium text-foreground">Theme</label>
<Listbox value={selectedTheme} onChange={(newTheme) => setTheme(newTheme.id)}>
<div className="relative">
<ListboxButton className="relative w-full cursor-pointer rounded-lg bg-background py-2 pl-3 pr-10 text-left text-foreground shadow-sm focus:outline-none focus:ring-2 focus:ring-accent">
<ListboxButton className="relative w-full cursor-pointer rounded-lg bg-background py-2 pl-3 pr-10 text-left text-foreground shadow-sm focus:outline-none focus:ring-2 focus:ring-accent transform transition-transform duration-200 ease-in-out hover:scale-[1.01] hover:text-accent">
<span className="block truncate">{selectedTheme.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon className="h-5 w-5 text-muted" />
@ -134,12 +134,12 @@ export function SettingsModal({ isOpen, setIsOpen }: SettingsModalProps) {
</div>
<div className="mt-6 flex justify-end space-x-3">
<button
<Button
type="button"
className="inline-flex justify-center rounded-lg bg-accent px-4 py-2 text-sm
font-medium text-white hover:bg-accent/90 focus:outline-none
focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2
transition-colors"
transform transition-transform duration-200 ease-in-out hover:scale-[1.04] hover:text-background"
onClick={async () => {
await updateConfig({
apiKey: localApiKey,
@ -149,13 +149,13 @@ export function SettingsModal({ isOpen, setIsOpen }: SettingsModalProps) {
}}
>
Save
</button>
<button
</Button>
<Button
type="button"
className="inline-flex justify-center rounded-lg bg-background px-4 py-2 text-sm
font-medium text-foreground hover:bg-background/90 focus:outline-none
focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2
transition-colors"
transform transition-transform duration-200 ease-in-out hover:scale-[1.04] hover:text-accent"
onClick={() => {
setLocalApiKey(apiKey);
setLocalBaseUrl(baseUrl);
@ -163,7 +163,7 @@ export function SettingsModal({ isOpen, setIsOpen }: SettingsModalProps) {
}}
>
Cancel
</button>
</Button>
</div>
</DialogPanel>
</TransitionChild>