feat(input): refactor input component to support compound pattern
Add new Input component with support for Password and Button variants through compound pattern. Move input implementation to new directory structure and enhance with label and caption support. Remove old input implementation.
This commit is contained in:
@@ -84,7 +84,7 @@ export { Sortable } from './composites/Sortable'
|
||||
export * from './primitives/button'
|
||||
export * from './primitives/command'
|
||||
export * from './primitives/dialog'
|
||||
export * from './primitives/input'
|
||||
export * from './primitives/Input'
|
||||
export * from './primitives/popover'
|
||||
export * from './primitives/radioGroup'
|
||||
export * from './primitives/shadcn-io/dropzone'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export function WithButton() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { WithButton } from './button'
|
||||
import { Input as InternalInput } from './input'
|
||||
import { Password } from './password'
|
||||
|
||||
type CompoundedComponent = typeof InternalInput & {
|
||||
Password: typeof Password
|
||||
Button: typeof WithButton
|
||||
}
|
||||
|
||||
const Input: CompoundedComponent = InternalInput as CompoundedComponent
|
||||
Input.Password = Password
|
||||
Input.Button = WithButton
|
||||
|
||||
export { Input }
|
||||
@@ -0,0 +1,50 @@
|
||||
import { cn } from '@cherrystudio/ui/utils'
|
||||
import React from 'react'
|
||||
|
||||
interface BaseInputProps extends React.ComponentPropsWithRef<'input'> {
|
||||
startContent?: React.ReactNode
|
||||
endContent?: React.ReactNode
|
||||
}
|
||||
|
||||
interface WithLabel extends BaseInputProps {
|
||||
label: string
|
||||
caption?: string
|
||||
}
|
||||
|
||||
interface WithoutLabel extends BaseInputProps {
|
||||
label?: never
|
||||
caption?: never
|
||||
}
|
||||
|
||||
type InputProps = WithLabel | WithoutLabel
|
||||
|
||||
export function Input({ className, type, required, label, caption, ...props }: InputProps) {
|
||||
const id = React.useId()
|
||||
const input = (
|
||||
<input
|
||||
type={type}
|
||||
data-slot="input"
|
||||
id={id}
|
||||
className={cn(
|
||||
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-2xs border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'focus-visible:border-primary focus-visible:ring-primary/50 focus-visible:ring-[3px]',
|
||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||
className
|
||||
)}
|
||||
required={required}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
if (label !== undefined) {
|
||||
return (
|
||||
<div className="flex flex-col w-full">
|
||||
<label htmlFor={id}>{label}</label>
|
||||
{input}
|
||||
{caption && <div className="text-muted-foreground">{caption}</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export function Password() {}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { cn } from '@cherrystudio/ui/utils'
|
||||
import * as React from 'react'
|
||||
|
||||
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
data-slot="input"
|
||||
className={cn(
|
||||
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'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',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Input }
|
||||
Reference in New Issue
Block a user