'use client'
import type { Input as BaseInputNS } from '@base-ui/react/input'
import type { VariantProps } from 'class-variance-authority'
import { Input as BaseInput } from '@base-ui/react/input'
import { cva } from 'class-variance-authority'
import * as React from 'react'
import { cn } from '../cn'
const interactiveElementSelector =
'button,a[href],[role="button"],[role="link"],select,[tabindex]:not([tabindex="-1"]),input:not([type="hidden"]):not([disabled]),[contenteditable]:not([contenteditable="false"]),textarea:not([disabled])'
type InputGroupProps = React.ComponentProps<'div'>
function InputGroup({ className, onMouseDown, ...props }: InputGroupProps) {
return (
// oxlint-disable-next-line jsx-a11y/no-static-element-interactions -- The handler extends the native input's pointer target; keyboard users reach the input directly.
input:enabled]:not-has-[>input[readonly]]:hover:border-components-input-border-hover has-[>input:enabled]:not-has-[>input[readonly]]:hover:bg-components-input-bg-hover',
'has-[>input:focus]:not-has-[>input[readonly]]:border-components-input-border-active has-[>input:focus]:not-has-[>input[readonly]]:bg-components-input-bg-active has-[>input:focus]:not-has-[>input[readonly]]:shadow-xs',
'has-[>input[data-invalid]]:border-components-input-border-destructive has-[>input[data-invalid]]:bg-components-input-bg-destructive',
'has-[>input[data-disabled]]:cursor-not-allowed has-[>input[data-disabled]]:border-transparent has-[>input[data-disabled]]:bg-components-input-bg-disabled has-[>input[data-disabled]]:text-components-input-text-filled-disabled',
'has-[>input[data-disabled]]:*:data-align:cursor-not-allowed has-[>input[data-disabled]]:*:data-align:text-components-input-text-filled-disabled',
'has-[>input[readonly]]:cursor-default has-[>input[readonly]]:*:data-align:cursor-default',
'has-[>input[readonly]:focus-visible]:ring-2 has-[>input[readonly]:focus-visible]:ring-state-accent-solid',
'has-[>[data-align=inline-start]]:[&>input]:ps-0',
'has-[>[data-align=inline-end]]:[&>input]:pe-0',
'motion-reduce:transition-none',
],
className,
)}
onMouseDown={(event) => {
onMouseDown?.(event)
if (event.defaultPrevented || event.button !== 0) return
const eventPath = event.nativeEvent.composedPath()
if (!eventPath.includes(event.currentTarget)) return
const target = eventPath[0]
const ElementConstructor = event.currentTarget.ownerDocument.defaultView?.Element
if (!ElementConstructor || !(target instanceof ElementConstructor)) return
if (target !== event.currentTarget && target.closest(interactiveElementSelector)) return
const input = event.currentTarget.querySelector
(':scope > input')
if (!input || input.disabled) return
event.preventDefault()
input.focus()
}}
/>
)
}
type InputGroupInputProps = Omit & {
className?: string
}
function InputGroupInput({ className, ...props }: InputGroupInputProps) {
return (
)
}
const inputGroupAddonVariants = cva(
'flex shrink-0 cursor-text items-center self-stretch system-sm-regular text-text-secondary select-none',
{
variants: {
align: {
'inline-start': 'order-first ps-2 pe-1',
'inline-end': 'order-last ps-1 pe-2',
},
},
defaultVariants: {
align: 'inline-start',
},
},
)
type InputGroupAddonProps = Omit, 'className'> &
VariantProps & {
className?: string
}
function InputGroupAddon({ align = 'inline-start', className, ...props }: InputGroupAddonProps) {
return (
)
}
export { InputGroup, InputGroupAddon, InputGroupInput }
export type { InputGroupAddonProps, InputGroupInputProps, InputGroupProps }