Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(textarea): auto resizable #1681

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/www/content/docs/components/textarea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ import { Textarea } from "@/components/ui/textarea"

<ComponentPreview name="textarea-with-label" className="[&_div.grid]:w-full" />

### With autoResize

<ComponentPreview name="textarea-with-autoresize" />

### With Text

<ComponentPreview name="textarea-with-text" />
Expand Down
29 changes: 29 additions & 0 deletions apps/www/hooks/use-auto-resize-textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from "react"

export const useAutoResizeTextarea = (ref: React.ForwardedRef<HTMLTextAreaElement>, autoResize: boolean) => {

const textAreaRef = React.useRef<HTMLTextAreaElement>(null)

React.useImperativeHandle(ref, () => textAreaRef.current!);

React.useEffect(() => {
const ref = textAreaRef?.current

const updateTextareaHeight = () => {
if (ref && autoResize) {
ref.style.height = "auto"
ref.style.height = ref?.scrollHeight + "px"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need this:

const scrollHeight = `${ref.scrollHeight}px`;
const computedStyleMap = ref.computedStyleMap();
const borderTopWidth = computedStyleMap.get("border-top-width")?.toString() ?? "0";
const borderBottomWidth = computedStyleMap.get("border-bottom-width")?.toString() ?? "0";

ref.style.height = `calc(${scrollHeight} + ${borderTopWidth} + ${borderBottomWidth})`;

}
}

updateTextareaHeight()

ref?.addEventListener("input", updateTextareaHeight)

return () => ref?.removeEventListener("input", updateTextareaHeight)

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return { textAreaRef }
}
2 changes: 1 addition & 1 deletion apps/www/public/registry/styles/default/accordion.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"files": [
{
"name": "accordion.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\nimport { ChevronDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Accordion = AccordionPrimitive.Root\n\nconst AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <AccordionPrimitive.Item\n ref={ref}\n className={cn(\"border-b\", className)}\n {...props}\n />\n))\nAccordionItem.displayName = \"AccordionItem\"\n\nconst AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n))\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName\n\nconst AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <AccordionPrimitive.Content\n ref={ref}\n className=\"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n {...props}\n >\n <div className={cn(\"pb-4 pt-0\", className)}>{children}</div>\n </AccordionPrimitive.Content>\n))\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n"
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\r\nimport { ChevronDown } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst Accordion = AccordionPrimitive.Root\r\n\r\nconst AccordionItem = React.forwardRef<\r\n React.ElementRef<typeof AccordionPrimitive.Item>,\r\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\r\n>(({ className, ...props }, ref) => (\r\n <AccordionPrimitive.Item\r\n ref={ref}\r\n className={cn(\"border-b\", className)}\r\n {...props}\r\n />\r\n))\r\nAccordionItem.displayName = \"AccordionItem\"\r\n\r\nconst AccordionTrigger = React.forwardRef<\r\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\r\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\r\n>(({ className, children, ...props }, ref) => (\r\n <AccordionPrimitive.Header className=\"flex\">\r\n <AccordionPrimitive.Trigger\r\n ref={ref}\r\n className={cn(\r\n \"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />\r\n </AccordionPrimitive.Trigger>\r\n </AccordionPrimitive.Header>\r\n))\r\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName\r\n\r\nconst AccordionContent = React.forwardRef<\r\n React.ElementRef<typeof AccordionPrimitive.Content>,\r\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\r\n>(({ className, children, ...props }, ref) => (\r\n <AccordionPrimitive.Content\r\n ref={ref}\r\n className=\"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\r\n {...props}\r\n >\r\n <div className={cn(\"pb-4 pt-0\", className)}>{children}</div>\r\n </AccordionPrimitive.Content>\r\n))\r\n\r\nAccordionContent.displayName = AccordionPrimitive.Content.displayName\r\n\r\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\r\n"
}
],
"type": "components:ui"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/styles/default/alert-dialog.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"files": [
{
"name": "alert-dialog.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/default/ui/button\"\n\nconst AlertDialog = AlertDialogPrimitive.Root\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n className={cn(\n \"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\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName\n\nconst AlertDialogContent = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background 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\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n))\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName\n\nconst AlertDialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n)\nAlertDialogHeader.displayName = \"AlertDialogHeader\"\n\nconst AlertDialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nAlertDialogFooter.displayName = \"AlertDialogFooter\"\n\nconst AlertDialogTitle = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n))\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName\n\nconst AlertDialogDescription = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName\n\nconst AlertDialogAction = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Action>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Action\n ref={ref}\n className={cn(buttonVariants(), className)}\n {...props}\n />\n))\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName\n\nconst AlertDialogCancel = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel\n ref={ref}\n className={cn(\n buttonVariants({ variant: \"outline\" }),\n \"mt-2 sm:mt-0\",\n className\n )}\n {...props}\n />\n))\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n}\n"
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { buttonVariants } from \"@/registry/default/ui/button\"\r\n\r\nconst AlertDialog = AlertDialogPrimitive.Root\r\n\r\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger\r\n\r\nconst AlertDialogPortal = AlertDialogPrimitive.Portal\r\n\r\nconst AlertDialogOverlay = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPrimitive.Overlay\r\n className={cn(\r\n \"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\",\r\n className\r\n )}\r\n {...props}\r\n ref={ref}\r\n />\r\n))\r\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName\r\n\r\nconst AlertDialogContent = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Content>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPortal>\r\n <AlertDialogOverlay />\r\n <AlertDialogPrimitive.Content\r\n ref={ref}\r\n className={cn(\r\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background 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\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </AlertDialogPortal>\r\n))\r\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName\r\n\r\nconst AlertDialogHeader = ({\r\n className,\r\n ...props\r\n}: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div\r\n className={cn(\r\n \"flex flex-col space-y-2 text-center sm:text-left\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n)\r\nAlertDialogHeader.displayName = \"AlertDialogHeader\"\r\n\r\nconst AlertDialogFooter = ({\r\n className,\r\n ...props\r\n}: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div\r\n className={cn(\r\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n)\r\nAlertDialogFooter.displayName = \"AlertDialogFooter\"\r\n\r\nconst AlertDialogTitle = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Title>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPrimitive.Title\r\n ref={ref}\r\n className={cn(\"text-lg font-semibold\", className)}\r\n {...props}\r\n />\r\n))\r\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName\r\n\r\nconst AlertDialogDescription = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Description>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPrimitive.Description\r\n ref={ref}\r\n className={cn(\"text-sm text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n))\r\nAlertDialogDescription.displayName =\r\n AlertDialogPrimitive.Description.displayName\r\n\r\nconst AlertDialogAction = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Action>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPrimitive.Action\r\n ref={ref}\r\n className={cn(buttonVariants(), className)}\r\n {...props}\r\n />\r\n))\r\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName\r\n\r\nconst AlertDialogCancel = React.forwardRef<\r\n React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\r\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\r\n>(({ className, ...props }, ref) => (\r\n <AlertDialogPrimitive.Cancel\r\n ref={ref}\r\n className={cn(\r\n buttonVariants({ variant: \"outline\" }),\r\n \"mt-2 sm:mt-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n))\r\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName\r\n\r\nexport {\r\n AlertDialog,\r\n AlertDialogPortal,\r\n AlertDialogOverlay,\r\n AlertDialogTrigger,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogFooter,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n}\r\n"
}
],
"type": "components:ui"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/styles/default/alert.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": [
{
"name": "alert.tsx",
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
"content": "import * as React from \"react\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst alertVariants = cva(\r\n \"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-background text-foreground\",\r\n destructive:\r\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n },\r\n }\r\n)\r\n\r\nconst Alert = React.forwardRef<\r\n HTMLDivElement,\r\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\r\n>(({ className, variant, ...props }, ref) => (\r\n <div\r\n ref={ref}\r\n role=\"alert\"\r\n className={cn(alertVariants({ variant }), className)}\r\n {...props}\r\n />\r\n))\r\nAlert.displayName = \"Alert\"\r\n\r\nconst AlertTitle = React.forwardRef<\r\n HTMLParagraphElement,\r\n React.HTMLAttributes<HTMLHeadingElement>\r\n>(({ className, ...props }, ref) => (\r\n <h5\r\n ref={ref}\r\n className={cn(\"mb-1 font-medium leading-none tracking-tight\", className)}\r\n {...props}\r\n />\r\n))\r\nAlertTitle.displayName = \"AlertTitle\"\r\n\r\nconst AlertDescription = React.forwardRef<\r\n HTMLParagraphElement,\r\n React.HTMLAttributes<HTMLParagraphElement>\r\n>(({ className, ...props }, ref) => (\r\n <div\r\n ref={ref}\r\n className={cn(\"text-sm [&_p]:leading-relaxed\", className)}\r\n {...props}\r\n />\r\n))\r\nAlertDescription.displayName = \"AlertDescription\"\r\n\r\nexport { Alert, AlertTitle, AlertDescription }\r\n"
}
],
"type": "components:ui"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/styles/default/aspect-ratio.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"files": [
{
"name": "aspect-ratio.tsx",
"content": "\"use client\"\n\nimport * as AspectRatioPrimitive from \"@radix-ui/react-aspect-ratio\"\n\nconst AspectRatio = AspectRatioPrimitive.Root\n\nexport { AspectRatio }\n"
"content": "\"use client\"\r\n\r\nimport * as AspectRatioPrimitive from \"@radix-ui/react-aspect-ratio\"\r\n\r\nconst AspectRatio = AspectRatioPrimitive.Root\r\n\r\nexport { AspectRatio }\r\n"
}
],
"type": "components:ui"
Expand Down
Loading