chore: improve styles

This commit is contained in:
DarkSky
2026-02-17 11:11:55 +08:00
parent 1ecfed91ff
commit 4b074485a4
24 changed files with 90 additions and 70 deletions

View File

@@ -92,7 +92,7 @@ export function SharedDataTable<TData extends { id: string }, TValue>({
return (
<div className="relative flex h-full flex-col gap-4 overflow-auto px-6 py-5">
{renderToolbar?.(table)}
<div className="relative flex h-full flex-col overflow-auto rounded-xl border border-border bg-card shadow-1">
<div className="relative flex h-full flex-col overflow-auto rounded-xl border border-border/60 bg-card shadow-1">
{loading ? (
<div className="absolute inset-0 z-10 flex flex-col items-center justify-center gap-2 bg-background/75 text-sm text-muted-foreground backdrop-blur-[1px]">
<svg

View File

@@ -53,10 +53,10 @@ export const FeatureToggleList = ({
<div key={feature}>
<Label
className={cn(
'cursor-pointer',
'cursor-pointer transition-colors duration-100',
controlPosition === 'right'
? 'flex items-center justify-between p-3 text-[15px] gap-2 font-medium leading-6 overflow-hidden'
: 'flex items-center gap-2 px-3 py-2 text-sm'
? 'flex items-center justify-between p-3 text-sm gap-2 font-medium leading-6 overflow-hidden hover:bg-muted/40'
: 'flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted/40'
)}
>
{controlPosition === 'left' ? (

View File

@@ -15,7 +15,7 @@ describe('Button', () => {
render(<Button>Save</Button>);
const button = screen.getByRole('button', { name: 'Save' });
expect(button.className).toContain('rounded-md');
expect(button.className).toContain('rounded-lg');
expect(button.className).toContain('bg-primary');
expect(button.className).toContain('focus-visible:ring-ring/30');
});

View File

@@ -4,7 +4,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-[background-color,color,border-color,box-shadow,transform] duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none',
'inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-[background-color,color,border-color,box-shadow,transform] duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none',
{
variants: {
variant: {

View File

@@ -8,7 +8,7 @@ const Card = React.forwardRef<
<div
ref={ref}
className={cn(
'rounded-lg border bg-card text-card-foreground shadow-sm',
'rounded-xl border bg-card text-card-foreground shadow-sm transition-shadow duration-200',
className
)}
{...props}

View File

@@ -9,7 +9,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-background px-3 py-1.5 text-sm text-foreground ring-offset-background transition-[border-color,box-shadow,background-color] duration-150 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50',
'flex h-9 w-full rounded-lg border border-input bg-background px-3 py-1.5 text-sm text-foreground ring-offset-background transition-[border-color,box-shadow,background-color] duration-150 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}

View File

@@ -16,7 +16,7 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-1.5 text-sm ring-offset-background transition-[border-color,box-shadow,background-color] duration-150 placeholder:text-muted-foreground focus:border-ring focus:outline-none focus:ring-2 focus:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
'flex h-9 w-full items-center justify-between rounded-lg border border-input bg-background px-3 py-1.5 text-sm ring-offset-background transition-[border-color,box-shadow,background-color] duration-150 placeholder:text-muted-foreground focus:border-ring focus:outline-none focus:ring-2 focus:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className
)}
{...props}

View File

@@ -6,7 +6,7 @@ function Skeleton({
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn('animate-pulse rounded-md bg-muted', className)}
className={cn('animate-pulse rounded-lg bg-muted', className)}
{...props}
/>
);

View File

@@ -57,7 +57,7 @@ const TableRow = React.forwardRef<
<tr
ref={ref}
className={cn(
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
'border-b transition-colors duration-100 hover:bg-muted/50 data-[state=selected]:bg-muted',
className
)}
{...props}

View File

@@ -160,4 +160,26 @@
@apply bg-background text-foreground antialiased;
font-family: var(--affine-font-family);
}
/* Smooth scrollbars */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--muted-foreground);
}
/* Text selection */
::selection {
background: var(--primary);
color: var(--primary-foreground);
}
}

View File

@@ -152,12 +152,12 @@ export const useColumns = ({
<div className="text-sm font-medium max-w-full overflow-hidden gap-[6px]">
<span>{row.original.name}</span>
{row.original.features.includes(FeatureType.Admin) && (
<span className="ml-2 inline-flex h-5 items-center rounded border border-border bg-chip-blue px-2 py-0.5 text-xs font-normal text-chip-text">
<span className="ml-2 inline-flex h-5 items-center rounded-md border border-border/60 bg-chip-blue px-2 py-0.5 text-xxs font-medium text-chip-text">
Admin
</span>
)}
{row.original.disabled && (
<span className="ml-2 inline-flex h-5 items-center rounded border border-border bg-chip-white px-2 py-0.5 text-xs">
<span className="ml-2 inline-flex h-5 items-center rounded-md border border-border/60 bg-chip-white px-2 py-0.5 text-xxs font-medium">
Disabled
</span>
)}
@@ -219,7 +219,7 @@ export const useColumns = ({
user.features.map(feature => (
<span
key={feature}
className="inline-flex h-5 items-center rounded border border-border bg-chip-white px-2 py-0.5 text-xs"
className="inline-flex h-5 items-center rounded-md border border-border/60 bg-chip-white px-2 py-0.5 text-xxs font-medium"
>
{feature}
</span>

View File

@@ -113,15 +113,15 @@ function UserForm({
}, [defaultUser]);
return (
<div className="flex h-full flex-col gap-2 bg-background">
<div className="flex h-full flex-col bg-background">
<RightPanelHeader
title={title}
handleClose={handleClose}
handleConfirm={handleConfirm}
canSave={canSave}
/>
<div className="flex-grow space-y-2 overflow-y-auto p-4">
<div className="flex flex-col rounded-lg border border-border bg-card">
<div className="flex-grow space-y-3 overflow-y-auto p-4">
<div className="flex flex-col rounded-xl border border-border bg-card shadow-sm">
<InputItem
label="User name"
field="name"
@@ -153,7 +153,7 @@ function UserForm({
</div>
<FeatureToggleList
className="rounded-lg border border-border bg-card"
className="rounded-xl border border-border bg-card shadow-sm"
features={serverConfig.availableUserFeatures}
selected={changes.features ?? []}
onChange={handleFeaturesChange}
@@ -190,8 +190,8 @@ function InputItem({
);
return (
<div className="flex flex-col gap-1.5 p-3">
<Label className="flex flex-wrap text-sm font-medium leading-6">
<div className="flex flex-col gap-2 p-3">
<Label className="flex flex-wrap text-xs font-medium leading-5 text-muted-foreground uppercase tracking-wide">
{label}
{optional && (
<span className="ml-1 font-normal text-muted-foreground">
@@ -309,24 +309,24 @@ export function UpdateUserForm({
onValidate={validateUpdateUser}
onDirtyChange={onDirtyChange}
actions={
<>
<div className="space-y-2">
<Button
className="h-9 w-full justify-between px-4 text-sm font-medium"
className="h-10 w-full justify-between rounded-xl border-border/60 px-4 text-sm font-medium hover:bg-muted/50"
variant="outline"
onClick={onResetPassword}
>
<span>Reset Password</span>
<ChevronRightIcon size={16} />
<ChevronRightIcon size={16} className="text-muted-foreground" />
</Button>
<Button
className="h-9 w-full justify-between px-4 text-sm font-medium text-destructive hover:text-destructive"
className="h-10 w-full justify-between rounded-xl border-destructive/30 px-4 text-sm font-medium text-destructive hover:bg-destructive/5 hover:text-destructive"
variant="outline"
onClick={onDeleteAccount}
>
<span>Delete Account</span>
<ChevronRightIcon size={16} />
</Button>
</>
</div>
}
/>
);

View File

@@ -9,7 +9,7 @@ interface UserTableProps {
*/
export const UserTable: React.FC<UserTableProps> = ({ users }) => {
return (
<div className="max-h-[300px] overflow-y-auto rounded-lg border border-border bg-card">
<div className="max-h-[300px] overflow-y-auto rounded-xl border border-border/60 bg-card shadow-sm">
<table className="w-full border-collapse">
<thead className="sticky top-0 bg-muted/40">
<tr>

View File

@@ -19,7 +19,7 @@ function AiPage() {
<div className="text-[20px]">AI</div>
<div className="flex justify-between items-center">
<div>
<p className="text-[15px] font-medium mt-6">Enable AI</p>
<p className="text-sm font-medium mt-6">Enable AI</p>
<p className="text-sm text-muted-foreground mt-1">
AI functionality is not currently supported. Self-hosted AI
support is in progress.

View File

@@ -330,14 +330,14 @@ function PrimaryMetricCard({
description: string;
}) {
return (
<Card className="h-full border-primary/30 bg-gradient-to-br from-primary/10 via-card to-card shadow-sm">
<Card className="h-full border-border/60 bg-card shadow-1">
<CardHeader className="pb-2">
<CardDescription className="flex items-center gap-2 text-foreground/75">
<CardDescription className="flex items-center gap-2 text-sm">
<UsersIcon className="h-4 w-4" aria-hidden="true" />
Current Sync Active Users
</CardDescription>
</CardHeader>
<CardContent className="space-y-1">
<CardContent className="space-y-1.5">
<div className="text-4xl font-bold tracking-tight tabular-nums">
{value}
</div>
@@ -359,9 +359,9 @@ function SecondaryMetricCard({
icon: ReactNode;
}) {
return (
<Card className="h-full border-border/70 bg-card/95 shadow-sm">
<Card className="h-full border-border/60 bg-card shadow-1">
<CardHeader className="pb-2">
<CardDescription className="flex items-center gap-2">
<CardDescription className="flex items-center gap-2 text-sm">
<span aria-hidden="true">{icon}</span>
{title}
</CardDescription>
@@ -370,7 +370,7 @@ function SecondaryMetricCard({
<div className="text-2xl font-semibold tracking-tight tabular-nums">
{value}
</div>
<p className="text-xs text-muted-foreground mt-1">{description}</p>
<p className="text-xs text-muted-foreground mt-1.5">{description}</p>
</CardContent>
</Card>
);
@@ -431,7 +431,7 @@ function DashboardPageSkeleton() {
}
/>
<div className="flex-1 overflow-auto p-6 space-y-6">
<Card className="border-primary/20 bg-gradient-to-r from-primary/5 via-card to-card shadow-sm">
<Card className="border-border/60 bg-card shadow-1">
<CardHeader className="pb-3">
<Skeleton className="h-5 w-36" />
<Skeleton className="h-4 w-80" />
@@ -462,7 +462,7 @@ function DashboardPageSkeleton() {
function TopSharedLinksCardSkeleton() {
return (
<Card className="border-border/70 bg-card/95 shadow-sm">
<Card className="border-border/60 bg-card shadow-1">
<CardHeader>
<Skeleton className="h-5 w-36" />
<Skeleton className="h-4 w-72" />
@@ -515,7 +515,7 @@ function TopSharedLinksSection({
const topSharedLinksWindow = data.adminDashboard.topSharedLinksWindow;
return (
<Card className="border-border/70 bg-card/95 shadow-sm">
<Card className="border-border/60 bg-card shadow-1">
<CardHeader>
<CardTitle className="text-base">Top Shared Links</CardTitle>
<CardDescription>
@@ -525,7 +525,7 @@ function TopSharedLinksSection({
</CardHeader>
<CardContent className="space-y-4">
{topSharedLinks.length === 0 ? (
<div className="rounded-lg border border-dashed p-8 text-center bg-muted/20">
<div className="rounded-xl border border-dashed border-border/60 p-8 text-center bg-muted/15">
<div className="text-sm font-medium">
No shared links in this window
</div>
@@ -688,7 +688,7 @@ function DashboardPageContent() {
/>
<div className="flex-1 overflow-auto p-6 space-y-6">
<Card className="border-primary/20 bg-gradient-to-r from-primary/5 via-card to-card shadow-sm">
<Card className="border-border/60 bg-card shadow-1">
<CardHeader className="pb-3">
<CardTitle className="text-base">Window Controls</CardTitle>
<CardDescription>
@@ -742,9 +742,9 @@ function DashboardPageContent() {
/>
</div>
<div className="h-full min-w-0 lg:col-span-4">
<Card className="h-full border-border/70 bg-gradient-to-br from-card via-card to-muted/15 shadow-sm">
<Card className="h-full border-border/60 bg-card shadow-1">
<CardHeader className="pb-2">
<CardDescription className="flex items-center gap-2">
<CardDescription className="flex items-center gap-2 text-sm">
<DatabaseIcon className="h-4 w-4" aria-hidden="true" />
Managed Storage
</CardDescription>
@@ -763,7 +763,7 @@ function DashboardPageContent() {
</div>
<div className="grid grid-cols-1 gap-5 lg:grid-cols-3">
<Card className="border-border/70 bg-card/95 shadow-sm lg:col-span-1">
<Card className="border-border/60 bg-card shadow-1 lg:col-span-1">
<CardHeader>
<CardTitle className="text-base">
Sync Active Users Trend
@@ -782,7 +782,7 @@ function DashboardPageContent() {
</CardContent>
</Card>
<Card className="border-border/70 bg-gradient-to-br from-primary/5 via-card to-card shadow-sm lg:col-span-2">
<Card className="border-border/60 bg-card shadow-1 lg:col-span-2">
<CardHeader>
<CardTitle className="text-base">
Storage Trend (Workspace + Blob)

View File

@@ -17,7 +17,7 @@ export const Header = ({
const isSmallScreen = useMediaQuery('(max-width: 768px)');
return (
<div>
<div className="border-b border-border/60 bg-background/80 backdrop-blur-sm">
<div className="flex h-14 items-center gap-4 px-6">
{isSmallScreen ? (
<div className="h-7 w-7 p-1" />
@@ -32,10 +32,9 @@ export const Header = ({
</Button>
)}
<Separator orientation="vertical" className="h-5" />
<div className="text-sm font-semibold">{title}</div>
<div className="text-sm font-semibold tracking-tight">{title}</div>
{endFix && <div className="ml-auto">{endFix}</div>}
</div>
<Separator />
</div>
);
};
@@ -52,30 +51,29 @@ export const RightPanelHeader = ({
canSave: boolean;
}) => {
return (
<div>
<div className="flex h-14 items-center justify-between px-6">
<div className="border-b border-border/60 bg-card/80 backdrop-blur-sm">
<div className="flex h-14 items-center justify-between px-4">
<Button
type="button"
size="icon"
className="h-7 w-7"
className="h-7 w-7 text-muted-foreground hover:text-foreground"
variant="ghost"
onClick={handleClose}
>
<XIcon size={20} />
<XIcon size={18} />
</Button>
<span className="text-base font-medium">{title}</span>
<span className="text-sm font-semibold tracking-tight">{title}</span>
<Button
type="submit"
size="icon"
className="h-7 w-7"
className="h-7 w-7 text-primary hover:text-primary"
variant="ghost"
onClick={handleConfirm}
disabled={!canSave}
>
<CheckIcon size={20} />
<CheckIcon size={18} />
</Button>
</div>
<Separator />
</div>
);
};

View File

@@ -196,7 +196,7 @@ export const LeftPanel = ({
</SheetHeader>
<SheetContent
side="left"
className="w-64 border-r border-border bg-sidebar-bg p-0"
className="w-64 border-r border-border/60 bg-sidebar-bg p-0"
withoutCloseButton
>
<div className="flex flex-col w-full h-full">
@@ -230,7 +230,7 @@ export const LeftPanel = ({
onCollapse={onCollapse}
className={cn(
isCollapsed ? 'min-w-[57px] max-w-[57px]' : 'min-w-56 max-w-56',
'h-dvh overflow-visible border-r border-border bg-sidebar-bg'
'h-dvh overflow-visible border-r border-border/60 bg-sidebar-bg'
)}
>
<div className="flex h-full max-w-56 flex-col">
@@ -284,7 +284,7 @@ export const RightPanel = ({
</SheetHeader>
<SheetContent
side="right"
className="border-l border-border bg-background p-0"
className="border-l border-border/60 bg-background p-0"
withoutCloseButton
>
<div className="h-full overflow-y-auto">{panelContent}</div>
@@ -304,7 +304,7 @@ export const RightPanel = ({
collapsedSize={0}
onExpand={onExpand}
onCollapse={onCollapse}
className="max-w-96 border-l border-border bg-card"
className="max-w-96 border-l border-border/60 bg-background"
>
<div className="h-full overflow-y-auto">{panelContent}</div>
</ResizablePanel>

View File

@@ -10,10 +10,11 @@ interface NavItemProps {
}
const navItemBaseClass =
'group inline-flex h-9 items-center gap-2 rounded-lg text-sm font-medium transition-colors duration-150';
'group inline-flex h-9 items-center gap-2 rounded-lg text-sm font-medium transition-all duration-150';
const navItemStateClass =
'text-sidebar-foreground-secondary hover:bg-sidebar-hover hover:text-sidebar-foreground';
const navItemActiveClass = 'bg-sidebar-active text-sidebar-foreground';
const navItemActiveClass =
'bg-sidebar-active text-sidebar-foreground shadow-sm';
export const NavItem = ({ icon, label, to, isCollapsed }: NavItemProps) => {
const className = ({ isActive }: { isActive: boolean }) =>

View File

@@ -25,7 +25,7 @@ interface UserDropdownProps {
}
const adminBadgeClass =
'inline-flex h-5 items-center rounded border border-border bg-chip-blue px-2 py-0.5 text-xs font-normal text-chip-text';
'inline-flex h-5 items-center rounded-md border border-border/60 bg-chip-blue px-2 py-0.5 text-xxs font-medium text-chip-text';
const UserInfo = ({
name,

View File

@@ -1,4 +1,3 @@
import '@queuedash/ui/dist/styles.css';
import './queue.css';

View File

@@ -156,7 +156,7 @@ const AdminPanel = ({
key={module}
value={module}
id={`config-module-${module}`}
className="mb-4 rounded-xl border border-border bg-card px-5 shadow-1"
className="mb-4 rounded-xl border border-border/60 bg-card px-5 shadow-1"
>
<AccordionTrigger className="hover:no-underline py-4">
<div className="flex flex-col items-start text-left gap-1">

View File

@@ -26,7 +26,7 @@ export const useColumns = () => {
{workspace.name || workspace.id}
</span>
{workspace.public ? (
<span className="inline-flex items-center gap-1 rounded border border-border bg-chip-white px-2 py-0.5 text-xxs">
<span className="inline-flex items-center gap-1 rounded-md border border-border/60 bg-chip-white px-2 py-0.5 text-xxs">
<LinkIcon fontSize={14} />
Public
</span>
@@ -40,7 +40,7 @@ export const useColumns = () => {
workspace.features.map(feature => (
<span
key={feature}
className="rounded border border-border bg-chip-white px-2 py-0.5"
className="rounded-md border border-border/60 bg-chip-white px-2 py-0.5"
>
{feature}
</span>

View File

@@ -177,7 +177,7 @@ function WorkspacePanelContent({
canSave={hasChanges && !isMutating}
/>
<div className="flex flex-col gap-4 overflow-y-auto p-4">
<div className="space-y-2 rounded-lg border border-border bg-card p-3">
<div className="space-y-2 rounded-xl border border-border/60 bg-card p-3 shadow-sm">
<div className="text-xs text-muted-foreground">Workspace ID</div>
<div className="text-sm font-mono break-all">{workspace.id}</div>
<div className="flex flex-col gap-1">
@@ -192,7 +192,7 @@ function WorkspacePanelContent({
</div>
</div>
<div className="rounded-lg border border-border bg-card">
<div className="rounded-xl border border-border/60 bg-card shadow-sm">
<FlagItem
label="Public"
description="Allow public access to workspace pages"
@@ -239,7 +239,7 @@ function WorkspacePanelContent({
/>
</div>
<div className="space-y-3 rounded-lg border border-border bg-card p-3">
<div className="space-y-3 rounded-xl border border-border/60 bg-card p-3 shadow-sm">
<div className="text-sm font-medium">Features</div>
<FeatureToggleList
features={serverConfig.availableWorkspaceFeatures ?? []}
@@ -272,7 +272,7 @@ function WorkspacePanelContent({
/>
</div>
<div className="rounded-lg border border-border bg-card">
<div className="rounded-xl border border-border/60 bg-card shadow-sm">
<div className="px-3 py-2 text-sm font-medium">Members</div>
<Separator />
<div className="flex flex-col divide-y">
@@ -337,7 +337,7 @@ function FlagItem({
function MetricCard({ label, value }: { label: string; value: string }) {
return (
<div className="flex flex-col gap-1 rounded-lg border border-border bg-card p-3">
<div className="flex flex-col gap-1 rounded-xl border border-border/60 bg-card p-3 shadow-sm">
<div className="text-xs text-muted-foreground">{label}</div>
<div className="text-sm font-semibold">{value}</div>
</div>

View File

@@ -62,7 +62,7 @@ export function WorkspaceSharedLinksPanel({
{sharedLinks.length === 0 ? (
<div className="text-sm text-muted-foreground">No shared links.</div>
) : (
<div className="flex flex-col divide-y rounded-lg border border-border bg-card">
<div className="flex flex-col divide-y rounded-xl border border-border/60 bg-card shadow-sm">
{sharedLinks.map(link => (
<SharedLinkItem key={link.docId} link={link} />
))}