Build Persian SGE Medical website and local product catalog
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
import * as React from 'react';
|
||||
import { mergeProps } from '@base-ui/react/merge-props';
|
||||
import { useRender } from '@base-ui/react/use-render';
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
const attachmentVariants = cva(
|
||||
'rounded-xl w-fit focus-within:ring-1 focus-within:ring-ring/50 group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed',
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
default:
|
||||
'gap-2 has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2 text-sm',
|
||||
sm: 'gap-2.5 has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5 text-xs',
|
||||
xs: 'gap-1.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs rounded-lg',
|
||||
},
|
||||
orientation: {
|
||||
horizontal: 'min-w-40 items-center',
|
||||
vertical: 'w-24 has-data-[slot=attachment-content]:w-30 flex-col',
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
function Attachment({
|
||||
className,
|
||||
state = 'done',
|
||||
size = 'default',
|
||||
orientation = 'horizontal',
|
||||
...props
|
||||
}: React.ComponentProps<'div'> &
|
||||
VariantProps<typeof attachmentVariants> & {
|
||||
state?: 'idle' | 'uploading' | 'processing' | 'error' | 'done';
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
data-slot="attachment"
|
||||
data-state={state}
|
||||
data-size={size}
|
||||
data-orientation={orientation}
|
||||
className={cn(attachmentVariants({ size, orientation }), className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const attachmentMediaVariants = cva(
|
||||
"bg-muted text-foreground w-10 rounded-lg group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md [&_svg:not([class*='size-'])]:size-4 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5 group-data-[orientation=vertical]/attachment:w-full group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
icon: '',
|
||||
image:
|
||||
'opacity-60 group-data-[state=idle]/attachment:opacity-100 group-data-[state=done]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'icon',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
function AttachmentMedia({
|
||||
className,
|
||||
variant = 'icon',
|
||||
...props
|
||||
}: React.ComponentProps<'div'> & VariantProps<typeof attachmentMediaVariants>) {
|
||||
return (
|
||||
<div
|
||||
data-slot="attachment-media"
|
||||
data-variant={variant}
|
||||
className={cn(attachmentMediaVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentContent({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<'div'>) {
|
||||
return (
|
||||
<div
|
||||
data-slot="attachment-content"
|
||||
className={cn(
|
||||
'leading-tight group-data-[orientation=vertical]/attachment:px-1 max-w-full min-w-0 flex-1',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<'span'>) {
|
||||
return (
|
||||
<span
|
||||
data-slot="attachment-title"
|
||||
className={cn(
|
||||
'font-medium block max-w-full min-w-0 truncate group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<'span'>) {
|
||||
return (
|
||||
<span
|
||||
data-slot="attachment-description"
|
||||
className={cn(
|
||||
'mt-0.5 text-xs block min-w-0 truncate text-muted-foreground group-data-[state=error]/attachment:text-destructive/80',
|
||||
'max-w-full',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentActions({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<'div'>) {
|
||||
return (
|
||||
<div
|
||||
data-slot="attachment-actions"
|
||||
className={cn(
|
||||
'group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 relative z-20 group-data-[orientation=vertical]/attachment:gap-1 flex shrink-0 items-center',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentAction({
|
||||
className,
|
||||
variant,
|
||||
size = 'icon-xs',
|
||||
...props
|
||||
}: React.ComponentProps<typeof Button>) {
|
||||
return (
|
||||
<Button
|
||||
data-slot="attachment-action"
|
||||
variant={variant ?? 'ghost'}
|
||||
size={size}
|
||||
className={cn(className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentTrigger({
|
||||
className,
|
||||
render,
|
||||
type,
|
||||
...props
|
||||
}: useRender.ComponentProps<'button'>) {
|
||||
return useRender({
|
||||
defaultTagName: 'button',
|
||||
props: mergeProps<'button'>(
|
||||
{
|
||||
type: render ? type : (type ?? 'button'),
|
||||
className: cn('absolute inset-0 z-10 outline-none', className),
|
||||
},
|
||||
props,
|
||||
),
|
||||
render,
|
||||
state: {
|
||||
slot: 'attachment-trigger',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function AttachmentGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
||||
return (
|
||||
<div
|
||||
data-slot="attachment-group"
|
||||
className={cn(
|
||||
'gap-3 scroll-px-1 py-1 flex min-w-0 scroll-fade-x snap-x snap-mandatory scrollbar-none overflow-x-auto overscroll-x-contain *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export {
|
||||
Attachment,
|
||||
AttachmentGroup,
|
||||
AttachmentMedia,
|
||||
AttachmentContent,
|
||||
AttachmentTitle,
|
||||
AttachmentDescription,
|
||||
AttachmentActions,
|
||||
AttachmentAction,
|
||||
AttachmentTrigger,
|
||||
};
|
||||
Reference in New Issue
Block a user