mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-08 18:56:37 +08:00
938e9ff4fd
* docs: add design spec for iOS 26 Liquid Glass UI redesign * docs: add implementation plan for iOS 26 Liquid Glass UI redesign * feat(ui): add liquid glass CSS variables and update root layouts * feat(ui): update Card and Modal components to iOS 26 Liquid Glass style * feat(ui): redesign dashboard page to Liquid Glass style * feat(ui): redesign node management page cards and charts * feat(ui): redesign monitor page to Liquid Glass style * feat(ui): redesign group and panel-sharing cards to Liquid Glass * feat(ui): redesign settings and user components to Liquid Glass * feat(ui): redesign profile and auth pages to Liquid Glass * fix(ui): revert to LineChart to fix compilation issues * refactor(ui): extract dashboard user header and cleanup admin layout * feat(ui): refine monitor page hero metrics and fix build * fix(ui): real data for monitor hero metrics and card padding adjustments * fix(ui): apply global card padding and fix index layouts * feat(ui): implement liquid-glass-react for all Card components * fix(ui): resolve liquid-glass-react rendering issues causing invisible text and broken layout * fix(ui): native CSS liquid-glass effect replacing NPM package * fix(ui): cleanup duplicate closing tags and complete liquid glass tables * fix(ui): apply perfect rounded corners to list views and table headers in non-compact mode * fix(ui): apply liquid glass styling to grouped rules view in forward page * fix(ui): re-implement liquid-glass natively to prevent text distortion and remove package dependency * fix(ui): remove mouse distortion and preserve proper liquid glass texture * fix(ui): remove svg filter causing text distortion and replace with pure css liquid glass * fix(ui): apply properly scoped border radius to table headers * fix(ui): remove hardcoded bg-default-50/60 from TableHeader * fix(ui): apply global liquid glass styling and transparent overlays to all modals and dialogs * fix(ui): remove absolute/relative class conflicts hiding Dialog modales and implement pure transparent layout * feat(ui): apply global liquid glass styling to cards, buttons, and diagnosis modals
195 lines
4.4 KiB
TypeScript
195 lines
4.4 KiB
TypeScript
import * as React from "react";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface TableClassNames {
|
|
th?: string;
|
|
td?: string;
|
|
tr?: string;
|
|
wrapper?: string;
|
|
}
|
|
|
|
interface TableStyleContextValue {
|
|
thClassName?: string;
|
|
tdClassName?: string;
|
|
trClassName?: string;
|
|
}
|
|
|
|
const TableStyleContext = React.createContext<TableStyleContextValue>({});
|
|
|
|
export interface TableProps extends React.ComponentProps<"table"> {
|
|
classNames?: TableClassNames;
|
|
}
|
|
|
|
export function Table({
|
|
children,
|
|
className,
|
|
classNames,
|
|
...props
|
|
}: TableProps) {
|
|
return (
|
|
<TableStyleContext.Provider
|
|
value={{
|
|
thClassName: classNames?.th,
|
|
tdClassName: classNames?.td,
|
|
trClassName: classNames?.tr,
|
|
}}
|
|
>
|
|
<div
|
|
className={cn("w-full overflow-auto rounded-md", classNames?.wrapper)}
|
|
>
|
|
<table className={cn("w-full text-sm", className)} {...props}>
|
|
{children}
|
|
</table>
|
|
</div>
|
|
</TableStyleContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function TableHeader({
|
|
children,
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"thead">) {
|
|
const childArray = React.Children.toArray(children);
|
|
const hasRow = childArray.some(
|
|
(child) => React.isValidElement(child) && child.type === TableRow,
|
|
);
|
|
|
|
return (
|
|
<thead className={cn("border-b", className)} {...props}>
|
|
{hasRow ? children : <TableRow>{children}</TableRow>}
|
|
</thead>
|
|
);
|
|
}
|
|
|
|
interface TableBodyProps<T>
|
|
extends Omit<React.ComponentProps<"tbody">, "children"> {
|
|
children?: React.ReactNode | ((item: T) => React.ReactNode);
|
|
emptyContent?: React.ReactNode;
|
|
isLoading?: boolean;
|
|
items?: T[];
|
|
loadingContent?: React.ReactNode;
|
|
}
|
|
|
|
export const TableBody = React.forwardRef<
|
|
HTMLTableSectionElement,
|
|
TableBodyProps<any>
|
|
>(function TableBody<T>(
|
|
{
|
|
children,
|
|
className,
|
|
emptyContent,
|
|
isLoading,
|
|
items,
|
|
loadingContent,
|
|
...props
|
|
}: TableBodyProps<T>,
|
|
ref: React.Ref<HTMLTableSectionElement>,
|
|
) {
|
|
if (isLoading) {
|
|
return (
|
|
<tbody ref={ref} className={className} {...props}>
|
|
<tr>
|
|
<td className="p-4 text-center text-default-500" colSpan={999}>
|
|
{loadingContent ?? "加载中..."}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
);
|
|
}
|
|
|
|
if (items && typeof children === "function") {
|
|
if (items.length === 0) {
|
|
return (
|
|
<tbody ref={ref} className={className} {...props}>
|
|
<tr>
|
|
<td className="p-4 text-center text-default-500" colSpan={999}>
|
|
{emptyContent ?? "暂无数据"}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<tbody ref={ref} className={className} {...props}>
|
|
{items.map((item) => {
|
|
const key =
|
|
typeof item === "object" && item !== null && "id" in item
|
|
? String((item as { id: React.Key }).id)
|
|
: JSON.stringify(item);
|
|
|
|
return <React.Fragment key={key}>{children(item)}</React.Fragment>;
|
|
})}
|
|
</tbody>
|
|
);
|
|
}
|
|
|
|
const staticChildren =
|
|
typeof children === "function" ? [] : React.Children.toArray(children);
|
|
|
|
if (staticChildren.length === 0) {
|
|
return (
|
|
<tbody ref={ref} className={className} {...props}>
|
|
<tr>
|
|
<td className="p-4 text-center text-default-500" colSpan={999}>
|
|
{emptyContent ?? "暂无数据"}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<tbody ref={ref} className={className} {...props}>
|
|
{typeof children === "function" ? null : children}
|
|
</tbody>
|
|
);
|
|
});
|
|
|
|
export function TableColumn({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"th">) {
|
|
const { thClassName } = React.useContext(TableStyleContext);
|
|
|
|
return (
|
|
<th
|
|
className={cn(
|
|
"px-3 py-2 text-left font-medium text-default-600",
|
|
thClassName,
|
|
className,
|
|
)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export const TableRow = React.forwardRef<
|
|
HTMLTableRowElement,
|
|
React.ComponentProps<"tr">
|
|
>(({ className, ...props }, ref) => {
|
|
const { trClassName } = React.useContext(TableStyleContext);
|
|
|
|
return (
|
|
<tr
|
|
ref={ref}
|
|
className={cn("border-b last:border-b-0", trClassName, className)}
|
|
{...props}
|
|
/>
|
|
);
|
|
});
|
|
TableRow.displayName = "TableRow";
|
|
|
|
export function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
const { tdClassName } = React.useContext(TableStyleContext);
|
|
|
|
return (
|
|
<td
|
|
className={cn("px-3 py-2 align-middle", tdClassName, className)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|