mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-24 23:46:52 +08:00
Adjust styles to match the design system (#11118)
### What problem does this PR solve? - Modify and adjust styles (CSS vars, components) to match the design system - Adjust file and directory structure of admin UI ### Type of change - [x] Refactoring
This commit is contained in:
@ -39,7 +39,7 @@ const AvatarFallback = React.forwardRef<
|
||||
<AvatarPrimitive.Fallback
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-full w-full items-center justify-center rounded-full bg-muted',
|
||||
'flex h-full w-full items-center justify-center rounded-full bg-bg-member',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -4,16 +4,18 @@ import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const badgeVariants = cva(
|
||||
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
||||
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors outline-none focus:outline-none',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
|
||||
'border-transparent bg-bg-primary text-text-primary hover:bg-primary/80',
|
||||
secondary:
|
||||
'border-transparent bg-bg-card text-text-sub-title-invert hover:bg-secondary/80 rounded-md',
|
||||
'border-transparent bg-bg-card text-text-secondary rounded-md',
|
||||
success:
|
||||
'border-transparent bg-state-success/5 text-state-success rounded-md',
|
||||
destructive:
|
||||
'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
|
||||
'border-transparent bg-state-error/5 text-state-error rounded-md',
|
||||
outline: 'text-foreground',
|
||||
},
|
||||
},
|
||||
|
||||
@ -3,28 +3,56 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
||||
import * as React from 'react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Loader2, Plus } from 'lucide-react';
|
||||
import { LucideLoader2, Plus } from 'lucide-react';
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
cn(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-0',
|
||||
'disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0',
|
||||
),
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
|
||||
outline:
|
||||
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
|
||||
'bg-text-primary text-bg-base shadow-xs hover:bg-text-primary/90 focus-visible:bg-text-primary/90',
|
||||
|
||||
destructive: `
|
||||
bg-state-error text-white shadow-xs
|
||||
hover:bg-state-error/90 focus-visible:ring-state-error/20 dark:focus-visible:ring-state-error/40
|
||||
`,
|
||||
outline: `
|
||||
text-text-secondary bg-bg-input border-0.5 border-border-button
|
||||
hover:text-text-primary hover:bg-border-button hover:border-border-default
|
||||
focus-visible:text-text-primary focus-visible:bg-border-button focus-visible:border-border-button
|
||||
`,
|
||||
secondary:
|
||||
'bg-bg-input text-text-primary shadow-xs hover:bg-bg-input/80 border border-border-button',
|
||||
ghost:
|
||||
'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
||||
|
||||
ghost: `
|
||||
text-text-secondary
|
||||
hover:bg-border-button hover:text-text-primary
|
||||
focus-visible:text-text-primary focus-visible:bg-border-button
|
||||
`,
|
||||
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
icon: 'bg-colors-background-inverse-standard text-foreground hover:bg-colors-background-inverse-standard/80',
|
||||
dashed: 'border border-dashed border-input hover:bg-accent',
|
||||
transparent: 'bg-transparent hover:bg-accent border',
|
||||
danger: 'bg-transparent border border-state-error text-state-error',
|
||||
|
||||
transparent: `
|
||||
text-text-secondary bg-transparent border-0.5 border-border-button
|
||||
hover:text-text-primary hover:bg-border-button
|
||||
focus-visible:text-text-primary focus-visible:bg-border-button focus-visible:border-border-button
|
||||
`,
|
||||
|
||||
danger: `
|
||||
bg-transparent border border-state-error text-state-error
|
||||
hover:bg-state-error/10 focus-visible:bg-state-error/10
|
||||
`,
|
||||
|
||||
highlighted: `
|
||||
bg-text-primary text-bg-base border-b-4 border-b-accent-primary
|
||||
hover:bg-text-primary/90 focus-visible:bg-text-primary/90
|
||||
`,
|
||||
},
|
||||
size: {
|
||||
default: 'h-8 px-2.5 py-1.5 ',
|
||||
@ -45,46 +73,48 @@ export interface ButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
loading?: boolean;
|
||||
block?: boolean;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
asChild = false,
|
||||
loading = false,
|
||||
disabled = false,
|
||||
block = false,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const Comp = asChild ? Slot : 'button';
|
||||
|
||||
return (
|
||||
<Comp
|
||||
className={cn(
|
||||
'bg-bg-card',
|
||||
{ 'block w-full': block },
|
||||
buttonVariants({ variant, size, className }),
|
||||
)}
|
||||
ref={ref}
|
||||
disabled={loading || disabled}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{loading && <LucideLoader2 className="animate-spin" />}
|
||||
{children}
|
||||
</Comp>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Button.displayName = 'Button';
|
||||
|
||||
export const ButtonLoading = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
Omit<ButtonProps, 'asChild'> & { loading?: boolean }
|
||||
>(
|
||||
(
|
||||
{ className, variant, size, children, loading = false, disabled, ...props },
|
||||
ref,
|
||||
) => {
|
||||
return (
|
||||
<Button
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
disabled={loading || disabled}
|
||||
>
|
||||
{loading && <Loader2 className="animate-spin" />}
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
);
|
||||
export const ButtonLoading = Button;
|
||||
|
||||
ButtonLoading.displayName = 'ButtonLoading';
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ const Card = React.forwardRef<
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'rounded-lg border-border-default border shadow-sm bg-bg-input',
|
||||
'rounded-lg border-border-button border-0.5 shadow-sm bg-bg-input transition-shadow',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -60,7 +60,11 @@ const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('p-6 pt-0 transition-shadow', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CardContent.displayName = 'CardContent';
|
||||
|
||||
|
||||
@ -13,7 +13,11 @@ const Checkbox = React.forwardRef<
|
||||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'peer h-3.5 w-3.5 shrink-0 rounded-sm border border-text-secondary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
||||
'peer size-4 shrink-0 rounded-sm border border-border-button outline-0 transition-colors bg-bg-component',
|
||||
'hover:border-border-default hover:bg-border-button',
|
||||
'focus-visible:border-border-default focus-visible:bg-border-default',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'data-[state=checked]:text-text-primary data-[state=checked]:border-border-default',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -21,7 +25,7 @@ const Checkbox = React.forwardRef<
|
||||
<CheckboxPrimitive.Indicator
|
||||
className={cn('flex items-center justify-center text-current')}
|
||||
>
|
||||
<Check className="h-3.5 w-3.5" />
|
||||
<Check className="size-3" />
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
));
|
||||
|
||||
@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'fixed inset-0 z-50 bg-black/50 backdrop-blur-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -38,13 +38,20 @@ const DialogContent = React.forwardRef<
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-xl translate-x-[-50%] translate-y-[-50%] gap-4 border bg-bg-base p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
'outline-0 fixed left-[50%] top-[50%] z-50 grid w-full max-w-xl translate-x-[-50%] translate-y-[-50%] gap-4 border bg-bg-base p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<DialogPrimitive.Close
|
||||
className="
|
||||
absolute right-4 top-4 p-2 rounded-sm opacity-70 outline-none text-text-secondary transition-colors
|
||||
hover:bg-border-button hover:text-text-primary
|
||||
focus-visible:bg-border-button focus-visible:text-text-primary
|
||||
disabled:pointer-events-none data-[state=open]:bg-bg-accent data-[state=open]:text-muted-foreground
|
||||
"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
@ -102,7 +109,7 @@ const DialogDescription = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn('text-sm text-muted-foreground', className)}
|
||||
className={cn('text-sm text-text-primary', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-bg-base p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -97,19 +97,18 @@ const FormLabel = React.forwardRef<
|
||||
required?: boolean;
|
||||
}
|
||||
>(({ className, tooltip, required = false, ...props }, ref) => {
|
||||
const { error, formItemId } = useFormField();
|
||||
const { formItemId } = useFormField();
|
||||
|
||||
return (
|
||||
<Label
|
||||
ref={ref}
|
||||
className={cn(error && 'text-destructive', className, 'flex pb-0.5')}
|
||||
className={cn(className, 'flex pb-0.5')}
|
||||
htmlFor={formItemId}
|
||||
{...props}
|
||||
>
|
||||
<section>
|
||||
{required && <span className="text-destructive">*</span>}
|
||||
{props.children}
|
||||
</section>
|
||||
{required && <span className="text-state-error">*</span>}
|
||||
{props.children}
|
||||
|
||||
{tooltip && <FormTooltip tooltip={tooltip}></FormTooltip>}
|
||||
</Label>
|
||||
);
|
||||
@ -171,7 +170,7 @@ const FormMessage = React.forwardRef<
|
||||
<p
|
||||
ref={ref}
|
||||
id={formMessageId}
|
||||
className={cn('text-sm font-medium text-destructive', className)}
|
||||
className={cn('text-sm font-medium text-state-error', className)}
|
||||
{...props}
|
||||
>
|
||||
{body}
|
||||
|
||||
@ -3,14 +3,17 @@ import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Eye, EyeOff, Search } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { Button } from './button';
|
||||
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'prefix'> {
|
||||
value?: string | number | readonly string[] | undefined;
|
||||
prefix?: React.ReactNode;
|
||||
suffix?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
({ className, type, value, onChange, ...props }, ref) => {
|
||||
({ className, type, value, onChange, prefix, suffix, ...props }, ref) => {
|
||||
const isControlled = value !== undefined;
|
||||
const { defaultValue, ...restProps } = props;
|
||||
const inputValue = isControlled ? value : defaultValue;
|
||||
@ -29,99 +32,80 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
onChange?.(e);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{type !== 'password' && (
|
||||
<input
|
||||
type={type === 'password' && showPassword ? 'text' : type}
|
||||
className={cn(
|
||||
'flex h-8 w-full rounded-md border border-input bg-bg-input px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-text-primary',
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
value={inputValue ?? ''}
|
||||
onChange={handleChange}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
const isPasswordInput = type === 'password';
|
||||
|
||||
const inputEl = (
|
||||
<input
|
||||
ref={ref}
|
||||
type={isPasswordInput && showPassword ? 'text' : type}
|
||||
className={cn(
|
||||
'flex h-8 w-full rounded-md border-0.5 border-input bg-bg-input px-3 py-2 outline-none text-sm text-text-primary',
|
||||
'file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled',
|
||||
'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent-primary',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50 transition-colors',
|
||||
{
|
||||
'pl-12': !!prefix,
|
||||
'pr-12': !!suffix || isPasswordInput,
|
||||
'pr-24': !!suffix && isPasswordInput,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
{type === 'password' && (
|
||||
<div className="relative w-full">
|
||||
<input
|
||||
type={type === 'password' && showPassword ? 'text' : type}
|
||||
className={cn(
|
||||
'flex h-8 w-full rounded-md border border-input bg-bg-input px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-text-primary',
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
value={inputValue ?? ''}
|
||||
onChange={handleChange}
|
||||
{...restProps}
|
||||
/>
|
||||
<button
|
||||
value={inputValue ?? ''}
|
||||
onChange={handleChange}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
|
||||
if (prefix || suffix || isPasswordInput) {
|
||||
return (
|
||||
<div className="relative">
|
||||
{prefix && (
|
||||
<span className="absolute left-0 top-[50%] translate-y-[-50%]">
|
||||
{prefix}
|
||||
</span>
|
||||
)}
|
||||
{inputEl}
|
||||
{suffix && (
|
||||
<span
|
||||
className={cn('absolute right-0 top-[50%] translate-y-[-50%]', {
|
||||
'right-14': isPasswordInput,
|
||||
})}
|
||||
>
|
||||
{suffix}
|
||||
</span>
|
||||
)}
|
||||
{isPasswordInput && (
|
||||
<Button
|
||||
variant="transparent"
|
||||
type="button"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center"
|
||||
className="border-0 absolute right-1 top-[50%] translate-y-[-50%]"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? (
|
||||
<EyeOff className="h-4 w-4 text-text-secondary" />
|
||||
<EyeOff className="size-[1em]" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4 text-text-secondary" />
|
||||
<Eye className="size-[1em]" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return inputEl;
|
||||
},
|
||||
);
|
||||
|
||||
Input.displayName = 'Input';
|
||||
|
||||
export interface ExpandedInputProps extends Omit<InputProps, 'prefix'> {
|
||||
prefix?: React.ReactNode;
|
||||
suffix?: React.ReactNode;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ExpandedInputProps extends InputProps {}
|
||||
|
||||
const ExpandedInput = ({
|
||||
suffix,
|
||||
prefix,
|
||||
className,
|
||||
...props
|
||||
}: ExpandedInputProps) => {
|
||||
return (
|
||||
<div className="relative">
|
||||
<span
|
||||
className={cn({
|
||||
['absolute left-3 top-[50%] translate-y-[-50%]']: prefix,
|
||||
})}
|
||||
>
|
||||
{prefix}
|
||||
</span>
|
||||
<Input
|
||||
className={cn(
|
||||
{ 'pr-8': !!suffix, 'pl-8': !!prefix },
|
||||
'bg-bg-base',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
></Input>
|
||||
<span
|
||||
className={cn({
|
||||
['absolute right-3 top-[50%] translate-y-[-50%]']: suffix,
|
||||
})}
|
||||
>
|
||||
{suffix}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const ExpandedInput = Input;
|
||||
|
||||
const SearchInput = (props: InputProps) => {
|
||||
return (
|
||||
<ExpandedInput
|
||||
prefix={<Search className="size-3.5" />}
|
||||
{...props}
|
||||
></ExpandedInput>
|
||||
);
|
||||
return <Input {...props} prefix={<Search className="ml-3 size-[1em]" />} />;
|
||||
};
|
||||
|
||||
type Value = string | readonly string[] | number | undefined;
|
||||
|
||||
@ -46,6 +46,7 @@ const PaginationLink = ({
|
||||
...props
|
||||
}: PaginationLinkProps) => (
|
||||
<a
|
||||
href="#"
|
||||
aria-current={isActive ? 'page' : undefined}
|
||||
className={cn(
|
||||
'size-8',
|
||||
@ -70,7 +71,7 @@ const PaginationPrevious = ({
|
||||
className={cn('gap-1 pl-2.5', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
<ChevronLeft className="size-4" />
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationPrevious.displayName = 'PaginationPrevious';
|
||||
@ -85,7 +86,7 @@ const PaginationNext = ({
|
||||
className={cn('gap-1 pr-2.5', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
<ChevronRight className="size-4" />
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationNext.displayName = 'PaginationNext';
|
||||
@ -96,7 +97,7 @@ const PaginationEllipsis = ({
|
||||
}: React.ComponentProps<'span'>) => (
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
||||
className={cn('flex items-center justify-center', className)}
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
|
||||
@ -39,7 +39,11 @@ const PopoverContent = React.forwardRef<
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'z-50 w-72 rounded-md border-0.5 border-border-button bg-bg-base p-4 text-text-primary shadow-lg outline-none',
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
||||
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-9',
|
||||
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -27,7 +27,12 @@ function RadioGroupItem({
|
||||
<RadioGroupPrimitive.Item
|
||||
data-slot="radio-group-item"
|
||||
className={cn(
|
||||
'border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'text-primary aspect-square size-4 shrink-0 rounded-full',
|
||||
'transition-all outline-none border border-border-button bg-bg-component',
|
||||
'hover:border-border-default hover:bg-border-default',
|
||||
'focus-visible:border-border-default focus-visible:bg-border-default',
|
||||
'aria-[invalid]:border-state-error aria-[invalid]:bg-state-error/5 aria-[invalid]:text-state-error',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -36,7 +41,7 @@ function RadioGroupItem({
|
||||
data-slot="radio-group-indicator"
|
||||
className="relative flex items-center justify-center"
|
||||
>
|
||||
<CircleIcon className="fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" />
|
||||
<CircleIcon className="fill-current absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" />
|
||||
</RadioGroupPrimitive.Indicator>
|
||||
</RadioGroupPrimitive.Item>
|
||||
);
|
||||
|
||||
@ -49,7 +49,7 @@ function Radio({ value, checked, disabled, onChange, children }: RadioProps) {
|
||||
<span
|
||||
className={cn(
|
||||
'flex h-4 w-4 items-center justify-center rounded-full border border-border transition-colors',
|
||||
'peer ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||
'peer outline-none focus-visible:border-border-button',
|
||||
isChecked && 'border-primary bg-primary/10',
|
||||
mergedDisabled && 'border-muted',
|
||||
)}
|
||||
|
||||
@ -23,7 +23,7 @@ export type RAGFlowPaginationType = {
|
||||
|
||||
export function RAGFlowPagination({
|
||||
current = 1,
|
||||
pageSize = 10,
|
||||
pageSize = 5,
|
||||
total = 0,
|
||||
onChange,
|
||||
showSizeChanger = true,
|
||||
@ -172,13 +172,14 @@ export function RAGFlowPagination({
|
||||
</PaginationItem>
|
||||
</PaginationContent>
|
||||
</Pagination>
|
||||
|
||||
{showSizeChanger && (
|
||||
<RAGFlowSelect
|
||||
options={sizeChangerOptions}
|
||||
value={currentPageSize}
|
||||
onChange={handlePageSizeChange}
|
||||
triggerClassName="bg-bg-card"
|
||||
></RAGFlowSelect>
|
||||
triggerClassName="bg-bg-card border-transparent"
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
|
||||
@ -26,7 +26,11 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-8 w-full items-center bg-bg-input justify-between rounded-md border border-input px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
'flex h-8 w-full items-center bg-bg-input justify-between rounded-md border-0.5 border-border-button',
|
||||
'px-3 py-2 text-sm outline-none transition-colors text-text-secondary placeholder:text-muted-foreground',
|
||||
'hover:text-text-primary hover:bg-border-button',
|
||||
'focus-visible:text-text-primary focus-visible:bg-border-button',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -91,7 +95,11 @@ const SelectContent = React.forwardRef<
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border-0.5 border-border-card bg-bg-base text-popover-foreground shadow-md',
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
||||
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
||||
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
position === 'popper' &&
|
||||
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||
className,
|
||||
@ -134,7 +142,8 @@ const SelectItem = React.forwardRef<
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-2 text-sm outline-none text-text-secondary',
|
||||
'focus:bg-border-button focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -11,16 +11,23 @@ const Switch = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
'peer inline-flex h-3.5 w-6 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-accent-primary data-[state=unchecked]:bg-text-sub-title',
|
||||
'group/switch inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full',
|
||||
'border-2 border-transparent overflow-hidden transition-colors',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'data-[state=checked]:bg-accent-primary data-[state=unchecked]:bg-text-sub-title',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
'pointer-events-none block size-3 rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-2 data-[state=unchecked]:translate-x-0',
|
||||
)}
|
||||
className="
|
||||
pointer-events-none block w-3 h-3 rounded-full bg-white shadow-lg ring-0 transition-all ease-out
|
||||
group-hover/switch:w-4 group-focus-visible/switch:w-4
|
||||
data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0
|
||||
group-hover/switch:data-[state=checked]:translate-x-2 group-focus-visible/switch:data-[state=checked]:translate-x-2
|
||||
"
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
));
|
||||
|
||||
@ -27,7 +27,10 @@ const TableHeader = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<thead
|
||||
ref={ref}
|
||||
className={cn('[&_tr]:border-b top-0 sticky bg-bg-title z-10', className)}
|
||||
className={cn(
|
||||
'[&_tr]:border-b-0.5 top-0 sticky bg-bg-title z-10',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
@ -52,7 +55,7 @@ const TableFooter = React.forwardRef<
|
||||
<tfoot
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
||||
'border-t-0.5 border-border-button bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -67,7 +70,7 @@ const TableRow = React.forwardRef<
|
||||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-b border-border-button transition-colors hover:bg-bg-card data-[state=selected]:bg-bg-card',
|
||||
'border-b-0.5 border-border-button transition-colors hover:bg-bg-card data-[state=selected]:bg-bg-card',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -82,7 +85,7 @@ const TableHead = React.forwardRef<
|
||||
<th
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'h-12 px-4 text-left align-middle font-normal text-text-secondary [&:has([role=checkbox])]:pr-0 ',
|
||||
'first-of-type:pl-6 last-of-type:pr-6 h-14 px-4 text-left align-middle font-normal text-text-secondary [&:has([role=checkbox])]:pr-0 ',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@ -97,7 +100,7 @@ const TableCell = React.forwardRef<
|
||||
<td
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'p-4 align-middle [&:has([role=checkbox])]:pr-0 text-text-primary font-normal',
|
||||
'first-of-type:pl-6 last-of-type:pr-6 px-4 py-3 align-middle [&:has([role=checkbox])]:pr-0 text-text-primary font-normal',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -29,7 +29,11 @@ const TabsTrigger = React.forwardRef<
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-bg-base data-[state=active]:text-text-primary data-[state=active]:shadow-sm',
|
||||
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5',
|
||||
'text-sm font-medium ring-offset-background transition-all',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||
'disabled:pointer-events-none disabled:opacity-50',
|
||||
'data-[state=active]:bg-bg-base data-[state=active]:text-text-primary data-[state=active]:shadow-sm',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user