{"version":3,"file":"TextField.cjs","sources":["../../../../src/components/forms/text-field/TextField.tsx"],"sourcesContent":["import { IconButton } from '@components/actions/icon-button'\r\nimport FormLabel from '@components/forms/_shared/components/form-label/FormLabel.tsx'\r\nimport {\r\n    TextFieldStartIcon,\r\n    TextFieldEndAction,\r\n} from '@components/forms/text-field/components/index.ts'\r\nimport { TEXT_FIELD_STYLES } from '@components/forms/text-field/styles/TextField.css.ts'\r\nimport HelperText from '@components/forms/_shared/components/helper-text/HelperText.tsx'\r\nimport { fieldSizeToActionSize } from '@components/forms/text-field/constants'\r\nimport { useTextField } from '@components/forms/text-field/hooks/useTextfield.hook.tsx'\r\nimport type { TextFieldCompound } from '@components/forms/text-field/types'\r\nimport { Flex } from '@components/layout/flex'\r\nimport EyeIcon from '@resources/asset/EyeIcon.svg?react'\r\nimport EyeOffIcon from '@resources/asset/EyeOffIcon.svg?react'\r\nimport { cn } from '@utils/cn.ts'\r\nimport { vars } from '@theme/contract.css.ts'\r\nimport { memo, useCallback } from 'react'\r\nimport type { TextFieldProps } from '@/components'\r\n\r\n/**\r\n  * A styled text input built with a native `<input>` and selectable label text.\r\n  *\r\n  * - `startIcon` - Iconify icon name rendered on the left.\r\n  * - `endAction` - any ReactNode (e.g. `<IconButton>`) rendered on the right.\r\n  * - `type=\"password\"` - auto-shows an eye-toggle `IconButton` (overrides `endAction`).\r\n  * - `width` - overrides the default `100%` wrapper width.\r\n  *\r\n  * Focus ring behavior: visible only on keyboard navigation (Tab). A click on the\r\n  * input shows the primary border without the ring halo, detected via `onMouseDown`\r\n  * and a `data-mouse-focus` attribute.\r\n  *\r\n  * @example\r\n  * ```tsx\r\n  * <TextField label=\"Email\" startIcon=\"lucide:mail\" placeholder=\"you@example.com\" />\r\n  * <TextField label=\"Password\" type=\"password\" />\r\n  * <TextField label=\"Search\" endAction={<IconButton icon=\"lucide:search\" aria-label=\"Search\" variant=\"ghost\" color=\"primary\" />} />\r\n  * <TextField label=\"Amount\" width=\"12rem\" />\r\n  * ```\r\n  */\r\nconst TextField = memo<TextFieldProps>((props) => {\r\n    const {\r\n        inputId,\r\n        helperId,\r\n        hasError,\r\n        hasStartIcon,\r\n        hasEndAction,\r\n        handleMouseDown,\r\n        handleFocus,\r\n        handleBlur,\r\n        resolvedType,\r\n        isPassword,\r\n        showPassword,\r\n        setShowPassword,\r\n    } = useTextField(props)\r\n\r\n    const {\r\n        disabled,\r\n        startIcon,\r\n        className,\r\n        width,\r\n        error,\r\n        helperText,\r\n        label,\r\n        required,\r\n        showRequiredIndicator = true,\r\n        endAction,\r\n        size: sizeProp,\r\n        fontSize: fontSizeProp = 'md',\r\n        placeholder,\r\n        value,\r\n        onChange,\r\n        onKeyDown,\r\n        onKeyUp,\r\n        ref,\r\n        style: inputStyle,\r\n        type: _type,\r\n        'aria-labelledby': ariaLabelledBy,\r\n        ...inputProps\r\n    } = props\r\n    const size = sizeProp ?? 'md'\r\n    const labelId = label && inputId ? `${inputId}-label` : undefined\r\n\r\n    const handleTogglePassword = useCallback(\r\n        () => setShowPassword(!showPassword),\r\n        [setShowPassword, showPassword],\r\n    )\r\n\r\n    const resolvedEndAction = isPassword ? (\r\n        <IconButton\r\n            icon={showPassword ? EyeOffIcon : EyeIcon}\r\n            aria-label={showPassword ? 'Hide password' : 'Show password'}\r\n            variant={'ghost'}\r\n            color={'primary'}\r\n            size={fieldSizeToActionSize[size]}\r\n            type={'button'}\r\n            tabIndex={-1}\r\n            onClick={handleTogglePassword}\r\n        />\r\n    ) : (\r\n        endAction\r\n    )\r\n\r\n    return (\r\n        <Flex\r\n            flexDirection={'column'}\r\n            gap={'xs'}\r\n            width={'100%'}\r\n            alignItems={'start'}\r\n            style={width !== undefined ? { width } : undefined}\r\n        >\r\n            {label && (\r\n                <FormLabel\r\n                    id={labelId}\r\n                    disabled={disabled}\r\n                    required={required && showRequiredIndicator}\r\n                    fontSize={fontSizeProp}\r\n                >\r\n                    {label}\r\n                </FormLabel>\r\n            )}\r\n\r\n            <Flex\r\n                position={'relative'}\r\n                width={'100%'}\r\n                gap={'none'}\r\n            >\r\n                {startIcon && (\r\n                    <TextFieldStartIcon\r\n                        icon={startIcon}\r\n                        size={size}\r\n                    />\r\n                )}\r\n\r\n                <input\r\n                    ref={ref}\r\n                    id={inputId}\r\n                    // `type` is resolved by useTextField for password toggling.\r\n                    type={resolvedType}\r\n                    disabled={disabled}\r\n                    required={required}\r\n                    aria-labelledby={ariaLabelledBy ?? labelId}\r\n                    aria-invalid={hasError || undefined}\r\n                    aria-describedby={error || helperText ? helperId : undefined}\r\n                    onMouseDown={handleMouseDown}\r\n                    onFocus={handleFocus}\r\n                    onBlur={handleBlur}\r\n                    className={cn(\r\n                        TEXT_FIELD_STYLES.recipe({\r\n                            size,\r\n                            hasError,\r\n                            hasStartIcon,\r\n                            hasEndAction,\r\n                        }),\r\n                        className,\r\n                    )}\r\n                    placeholder={placeholder}\r\n                    value={value}\r\n                    onChange={onChange}\r\n                    onKeyDown={onKeyDown}\r\n                    onKeyUp={onKeyUp}\r\n                    {...inputProps}\r\n                    style={{ fontSize: vars.fontSize[fontSizeProp], ...inputStyle }}\r\n                />\r\n\r\n                {hasEndAction && (\r\n                    <TextFieldEndAction>{resolvedEndAction}</TextFieldEndAction>\r\n                )}\r\n            </Flex>\r\n\r\n            {(error || helperText) && (\r\n                <HelperText\r\n                    id={helperId}\r\n                    hasError={hasError}\r\n                >\r\n                    {error ?? helperText}\r\n                </HelperText>\r\n            )}\r\n        </Flex>\r\n    )\r\n}) as unknown as TextFieldCompound\r\n\r\nTextField.displayName = 'TextField'\r\nTextField.Label = FormLabel\r\nTextField.StartIcon = TextFieldStartIcon\r\nTextField.EndAction = TextFieldEndAction\r\n\r\nexport default TextField\r\n"],"names":["TextField","memo","props","inputId","helperId","hasError","hasStartIcon","hasEndAction","handleMouseDown","handleFocus","handleBlur","resolvedType","isPassword","showPassword","setShowPassword","useTextField","disabled","startIcon","className","width","error","helperText","label","required","showRequiredIndicator","endAction","sizeProp","fontSizeProp","placeholder","value","onChange","onKeyDown","onKeyUp","ref","inputStyle","_type","ariaLabelledBy","inputProps","size","labelId","handleTogglePassword","useCallback","resolvedEndAction","jsx","IconButton","EyeOffIcon","EyeIcon","fieldSizeToActionSize","jsxs","Flex","FormLabel","TextFieldStartIcon","cn","TEXT_FIELD_STYLES","vars","TextFieldEndAction","HelperText"],"mappings":"8pCAuCMA,EAAYC,EAAAA,KAAsBC,GAAU,CAC9C,KAAM,CACF,QAAAC,EACA,SAAAC,EACA,SAAAC,EACA,aAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,YAAAC,EACA,WAAAC,EACA,aAAAC,EACA,WAAAC,EACA,aAAAC,EACA,gBAAAC,CAAA,EACAC,EAAAA,aAAab,CAAK,EAEhB,CACF,SAAAc,EACA,UAAAC,EACA,UAAAC,EACA,MAAAC,EACA,MAAAC,EACA,WAAAC,EACA,MAAAC,EACA,SAAAC,EACA,sBAAAC,EAAwB,GACxB,UAAAC,EACA,KAAMC,EACN,SAAUC,EAAe,KACzB,YAAAC,EACA,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,QAAAC,EACA,IAAAC,EACA,MAAOC,EACP,KAAMC,GACN,kBAAmBC,EACnB,GAAGC,CAAA,EACHnC,EACEoC,EAAOZ,GAAY,KACnBa,EAAUjB,GAASnB,EAAU,GAAGA,CAAO,SAAW,OAElDqC,EAAuBC,EAAAA,YACzB,IAAM3B,EAAgB,CAACD,CAAY,EACnC,CAACC,EAAiBD,CAAY,CAAA,EAG5B6B,EAAoB9B,EACtB+B,EAAAA,IAACC,EAAA,CACG,KAAM/B,EAAegC,EAAaC,EAClC,aAAYjC,EAAe,gBAAkB,gBAC7C,QAAS,QACT,MAAO,UACP,KAAMkC,EAAAA,sBAAsBT,CAAI,EAChC,KAAM,SACN,SAAU,GACV,QAASE,CAAA,CAAA,EAGbf,EAGJ,OACIuB,EAAAA,KAACC,EAAA,CACG,cAAe,SACf,IAAK,KACL,MAAO,OACP,WAAY,QACZ,MAAO9B,IAAU,OAAY,CAAE,MAAAA,GAAU,OAExC,SAAA,CAAAG,GACGqB,EAAAA,IAACO,EAAA,CACG,GAAIX,EACJ,SAAAvB,EACA,SAAUO,GAAYC,EACtB,SAAUG,EAET,SAAAL,CAAA,CAAA,EAIT0B,EAAAA,KAACC,EAAA,CACG,SAAU,WACV,MAAO,OACP,IAAK,OAEJ,SAAA,CAAAhC,GACG0B,EAAAA,IAACQ,EAAA,CACG,KAAMlC,EACN,KAAAqB,CAAA,CAAA,EAIRK,EAAAA,IAAC,QAAA,CACG,IAAAV,EACA,GAAI9B,EAEJ,KAAMQ,EACN,SAAAK,EACA,SAAAO,EACA,kBAAiBa,GAAkBG,EACnC,eAAclC,GAAY,OAC1B,mBAAkBe,GAASC,EAAajB,EAAW,OACnD,YAAaI,EACb,QAASC,EACT,OAAQC,EACR,UAAW0C,EAAAA,GACPC,EAAAA,kBAAkB,OAAO,CACrB,KAAAf,EACA,SAAAjC,EACA,aAAAC,EACA,aAAAC,CAAA,CACH,EACDW,CAAA,EAEJ,YAAAU,EACA,MAAAC,EACA,SAAAC,EACA,UAAAC,EACA,QAAAC,EACC,GAAGK,EACJ,MAAO,CAAE,SAAUiB,EAAAA,KAAK,SAAS3B,CAAY,EAAG,GAAGO,CAAA,CAAW,CAAA,EAGjE3B,GACGoC,EAAAA,IAACY,EAAA,CAAoB,SAAAb,CAAA,CAAkB,CAAA,CAAA,CAAA,GAI7CtB,GAASC,IACPsB,EAAAA,IAACa,EAAA,CACG,GAAIpD,EACJ,SAAAC,EAEC,SAAAe,GAASC,CAAA,CAAA,CACd,CAAA,CAAA,CAIhB,CAAC,EAEDrB,EAAU,YAAc,YACxBA,EAAU,MAAQkD,EAClBlD,EAAU,UAAYmD,EACtBnD,EAAU,UAAYuD"}