Files
medusa-store/packages/admin-ui/ui/src/components/molecules/textarea/index.tsx
T
2023-03-03 10:09:16 +01:00

115 lines
3.2 KiB
TypeScript

import clsx from "clsx"
import React, { useImperativeHandle, useRef } from "react"
import InputError from "../../atoms/input-error"
import InputHeader from "../../fundamentals/input-header"
import EmojiPicker from "../emoji-picker"
type TextareaProps = React.ComponentPropsWithRef<"textarea"> & {
errors?: { [x: string]: unknown }
label: string
key?: string
enableEmoji?: boolean
withTooltip?: boolean
tooltipText?: string
tooltipProps?: any
children?: React.ReactNode
containerProps?: React.HTMLAttributes<HTMLDivElement>
}
const TextArea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
(
{
placeholder,
label,
name,
key,
required,
withTooltip = false,
tooltipText,
tooltipProps = {},
containerProps,
className,
enableEmoji = false,
rows = 2,
children,
errors,
...props
}: TextareaProps,
ref
) => {
const inputRef = useRef<HTMLTextAreaElement | null>(null)
useImperativeHandle<HTMLTextAreaElement | null, HTMLTextAreaElement | null>(
ref,
() => inputRef.current
)
const scrollToTop = () => {
if (inputRef.current) {
inputRef.current.scrollTop = 0
}
}
const handleAddEmoji = (emoji: string) => {
if (!inputRef.current) {
return
}
const position = inputRef.current.selectionStart || 0
const newValue = `${inputRef.current?.value.substring(
0,
position
)}${emoji}${inputRef.current?.value.substring(position)}`
inputRef.current.value = newValue
}
return (
<div className={className} {...containerProps}>
{label && (
<InputHeader
{...{ label, required, withTooltip, tooltipText, tooltipProps }}
className="mb-xsmall"
/>
)}
<div
className={clsx(
"w-full flex flex-col focus-within:shadow-input focus-within:border-violet-60 px-small py-xsmall bg-grey-5 border border-grey-20 rounded-rounded",
{
"border-rose-50 focus-within:shadow-cta focus-within:shadow-rose-60/10 focus-within:border-rose-50":
errors && name && errors[name],
}
)}
>
<textarea
className={clsx(
"relative text-justify overflow-hidden focus:overflow-auto resize-none bg-inherit outline-none outline-0",
"w-full remove-number-spinner leading-base text-grey-90 font-normal caret-violet-60 placeholder-grey-40",
"line-clamp-[var(--lines)] focus:line-clamp-none"
)}
style={
{
"--lines": rows,
} as React.CSSProperties
}
ref={inputRef}
autoComplete="off"
name={name}
key={key || name}
placeholder={placeholder || "Placeholder"}
onBlur={scrollToTop}
onSelect={(e) => {}}
rows={rows}
{...props}
/>
{enableEmoji && <EmojiPicker onEmojiClick={handleAddEmoji} />}
</div>
<InputError name={name} errors={errors} />
</div>
)
}
)
export default TextArea