All checks were successful
Deploy / deploy (push) Successful in 9m29s
- Modified redirects in next.config.ts to change the destination for "/sohbet" to "/listem". - Added new dependencies in package.json: marked, motion, react-markdown, remark-breaks, remark-gfm, shiki, and use-stick-to-bottom. - Updated pnpm-lock.yaml to reflect the new package versions and dependencies. - Removed obsolete stack files for Flutter, Nuxt, Nuxt.js, React Native, and Svelte from the UI/UX Pro Max skill data. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
234 lines
5.3 KiB
TypeScript
234 lines
5.3 KiB
TypeScript
"use client"
|
|
|
|
import { Textarea } from "@/components/ui/textarea"
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from "@/components/ui/tooltip"
|
|
import { cn } from "@/lib/utils"
|
|
import React, {
|
|
createContext,
|
|
useContext,
|
|
useLayoutEffect,
|
|
useRef,
|
|
useState,
|
|
} from "react"
|
|
|
|
type PromptInputContextType = {
|
|
isLoading: boolean
|
|
value: string
|
|
setValue: (value: string) => void
|
|
maxHeight: number | string
|
|
onSubmit?: () => void
|
|
disabled?: boolean
|
|
textareaRef: React.RefObject<HTMLTextAreaElement | null>
|
|
}
|
|
|
|
const PromptInputContext = createContext<PromptInputContextType>({
|
|
isLoading: false,
|
|
value: "",
|
|
setValue: () => {},
|
|
maxHeight: 240,
|
|
onSubmit: undefined,
|
|
disabled: false,
|
|
textareaRef: React.createRef<HTMLTextAreaElement>(),
|
|
})
|
|
|
|
function usePromptInput() {
|
|
return useContext(PromptInputContext)
|
|
}
|
|
|
|
export type PromptInputProps = {
|
|
isLoading?: boolean
|
|
value?: string
|
|
onValueChange?: (value: string) => void
|
|
maxHeight?: number | string
|
|
onSubmit?: () => void
|
|
children: React.ReactNode
|
|
className?: string
|
|
disabled?: boolean
|
|
} & React.ComponentProps<"div">
|
|
|
|
function PromptInput({
|
|
className,
|
|
isLoading = false,
|
|
maxHeight = 240,
|
|
value,
|
|
onValueChange,
|
|
onSubmit,
|
|
children,
|
|
disabled = false,
|
|
onClick,
|
|
...props
|
|
}: PromptInputProps) {
|
|
const [internalValue, setInternalValue] = useState(value || "")
|
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
|
|
|
const handleChange = (newValue: string) => {
|
|
setInternalValue(newValue)
|
|
onValueChange?.(newValue)
|
|
}
|
|
|
|
const handleClick: React.MouseEventHandler<HTMLDivElement> = (e) => {
|
|
if (!disabled) textareaRef.current?.focus()
|
|
onClick?.(e)
|
|
}
|
|
|
|
return (
|
|
<TooltipProvider>
|
|
<PromptInputContext.Provider
|
|
value={{
|
|
isLoading,
|
|
value: value ?? internalValue,
|
|
setValue: onValueChange ?? handleChange,
|
|
maxHeight,
|
|
onSubmit,
|
|
disabled,
|
|
textareaRef,
|
|
}}
|
|
>
|
|
<div
|
|
onClick={handleClick}
|
|
className={cn(
|
|
"border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs",
|
|
disabled && "cursor-not-allowed opacity-60",
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</div>
|
|
</PromptInputContext.Provider>
|
|
</TooltipProvider>
|
|
)
|
|
}
|
|
|
|
export type PromptInputTextareaProps = {
|
|
disableAutosize?: boolean
|
|
} & React.ComponentProps<typeof Textarea>
|
|
|
|
function PromptInputTextarea({
|
|
className,
|
|
onKeyDown,
|
|
disableAutosize = false,
|
|
...props
|
|
}: PromptInputTextareaProps) {
|
|
const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } =
|
|
usePromptInput()
|
|
|
|
const adjustHeight = (el: HTMLTextAreaElement | null) => {
|
|
if (!el || disableAutosize) return
|
|
|
|
el.style.height = "auto"
|
|
|
|
if (typeof maxHeight === "number") {
|
|
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`
|
|
} else {
|
|
el.style.height = `min(${el.scrollHeight}px, ${maxHeight})`
|
|
}
|
|
}
|
|
|
|
const handleRef = (el: HTMLTextAreaElement | null) => {
|
|
textareaRef.current = el
|
|
adjustHeight(el)
|
|
}
|
|
|
|
useLayoutEffect(() => {
|
|
if (!textareaRef.current || disableAutosize) return
|
|
|
|
const el = textareaRef.current
|
|
el.style.height = "auto"
|
|
|
|
if (typeof maxHeight === "number") {
|
|
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`
|
|
} else {
|
|
el.style.height = `min(${el.scrollHeight}px, ${maxHeight})`
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [value, maxHeight, disableAutosize])
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
adjustHeight(e.target)
|
|
setValue(e.target.value)
|
|
}
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
e.preventDefault()
|
|
onSubmit?.()
|
|
}
|
|
onKeyDown?.(e)
|
|
}
|
|
|
|
return (
|
|
<Textarea
|
|
ref={handleRef}
|
|
value={value}
|
|
onChange={handleChange}
|
|
onKeyDown={handleKeyDown}
|
|
className={cn(
|
|
"text-primary min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0",
|
|
className
|
|
)}
|
|
rows={1}
|
|
disabled={disabled}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export type PromptInputActionsProps = React.HTMLAttributes<HTMLDivElement>
|
|
|
|
function PromptInputActions({
|
|
children,
|
|
className,
|
|
...props
|
|
}: PromptInputActionsProps) {
|
|
return (
|
|
<div className={cn("flex items-center gap-2", className)} {...props}>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export type PromptInputActionProps = {
|
|
className?: string
|
|
tooltip: React.ReactNode
|
|
children: React.ReactNode
|
|
side?: "top" | "bottom" | "left" | "right"
|
|
} & React.ComponentProps<typeof Tooltip>
|
|
|
|
function PromptInputAction({
|
|
tooltip,
|
|
children,
|
|
className,
|
|
side = "top",
|
|
...props
|
|
}: PromptInputActionProps) {
|
|
const { disabled } = usePromptInput()
|
|
|
|
return (
|
|
<Tooltip {...props}>
|
|
<TooltipTrigger
|
|
asChild
|
|
disabled={disabled}
|
|
onClick={(event) => event.stopPropagation()}
|
|
>
|
|
{children}
|
|
</TooltipTrigger>
|
|
<TooltipContent side={side} className={className}>
|
|
{tooltip}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
}
|
|
|
|
export {
|
|
PromptInput,
|
|
PromptInputTextarea,
|
|
PromptInputActions,
|
|
PromptInputAction,
|
|
}
|