{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "clearable-input",
  "title": "ClearableInput",
  "description": "A text field with a clear button that puts focus back in the field.",
  "registryDependencies": [
    "https://creance.pages.dev/r/creance-base.json",
    "https://creance.pages.dev/r/input.json"
  ],
  "files": [
    {
      "path": "clearable-input/ClearableInput.css",
      "content": ".cr-clearable {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n}\n\n.cr-clearable > .cr-input {\n  padding-inline-end: 96px;\n}\n\n.cr-clearable[data-leading] > .cr-input {\n  padding-inline-start: 40px;\n}\n\n.cr-clearable[data-shape='pill'] > .cr-input {\n  border-radius: var(--cr-radius-full);\n}\n\n.cr-clearable__leading {\n  position: absolute;\n  left: 14px;\n  display: flex;\n  color: var(--cr-color-text-muted);\n  pointer-events: none;\n}\n\n.cr-clearable__trailing {\n  position: absolute;\n  right: 7px;\n  display: flex;\n  align-items: center;\n  gap: var(--cr-space-2);\n}\n\n.cr-clearable__clear {\n  display: grid;\n  place-items: center;\n  width: 30px;\n  height: 30px;\n  border: 0;\n  border-radius: var(--cr-radius-full);\n  background: var(--cr-color-bg-subtle);\n  color: var(--cr-color-text-secondary);\n  font-size: 12px;\n  cursor: pointer;\n}\n\n.cr-clearable__clear:hover {\n  color: var(--cr-color-text-default);\n}\n\n.cr-clearable__clear:focus-visible {\n  outline: var(--cr-focus-width) solid var(--cr-color-focus);\n  outline-offset: var(--cr-focus-offset);\n}\n\n/* Hints such as a shortcut only make sense while the field is empty. */\n.cr-clearable:not([data-empty]) .cr-clearable__hint {\n  display: none;\n}\n\n/* Chrome and Safari give a search field a clear button of their own; this component has one already. */\n.cr-clearable > .cr-input::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n  appearance: none;\n}\n",
      "type": "registry:file",
      "target": "@components/creance/clearable-input/ClearableInput.css"
    },
    {
      "path": "clearable-input/ClearableInput.tsx",
      "content": "'use client';\n\nimport { forwardRef, useImperativeHandle, useRef, useState, type ReactNode } from 'react';\nimport { Input, type InputProps } from '@/components/creance/input/Input';\nimport { cx } from '@/lib/creance/cx';\nimport { CrossIcon } from '@/lib/creance/icons';\nimport './ClearableInput.css';\n\nexport interface ClearableInputProps extends InputProps {\n  /** Called after the field is cleared. With a controlled `value`, set it to '' here. */\n  onClear?: () => void;\n  /** Accessible name of the clear button. Default \"Clear\". */\n  clearLabel?: string;\n  /** Shown at the start of the field. Decorative. */\n  leading?: ReactNode;\n  /** Shown before the clear button: a shortcut hint or a spinner. */\n  trailing?: ReactNode;\n  /** Round ends, for search. */\n  shape?: 'rounded' | 'pill';\n}\n\n/** A text field with a clear button that appears when there is text, and puts focus back in the field. */\nexport const ClearableInput = forwardRef<HTMLInputElement, ClearableInputProps>(function ClearableInput(\n  { onClear, clearLabel = 'Clear', leading, trailing, shape = 'rounded', className, value, defaultValue, onChange, ...props },\n  ref,\n) {\n  const inner = useRef<HTMLInputElement>(null);\n  useImperativeHandle(ref, () => inner.current as HTMLInputElement);\n  const [own, setOwn] = useState(String(defaultValue ?? ''));\n  const text = value === undefined ? own : String(value);\n\n  return (\n    <span\n      className={cx('cr-clearable', className)}\n      data-shape={shape}\n      data-leading={leading ? '' : undefined}\n      data-empty={text ? undefined : ''}\n    >\n      {leading && <span className=\"cr-clearable__leading\">{leading}</span>}\n      <Input\n        ref={inner}\n        value={text}\n        onChange={(e) => {\n          if (value === undefined) setOwn(e.currentTarget.value);\n          onChange?.(e);\n        }}\n        {...props}\n      />\n      <span className=\"cr-clearable__trailing\">\n        {trailing}\n        {text && !props.disabled && !props.readOnly && (\n          <button\n            type=\"button\"\n            className=\"cr-clearable__clear\"\n            aria-label={clearLabel}\n            onClick={() => {\n              if (value === undefined) setOwn('');\n              onClear?.();\n              inner.current?.focus();\n            }}\n          >\n            <CrossIcon />\n          </button>\n        )}\n      </span>\n    </span>\n  );\n});\n",
      "type": "registry:ui",
      "target": "@components/creance/clearable-input/ClearableInput.tsx"
    }
  ],
  "categories": [
    "molecule",
    "forms"
  ],
  "type": "registry:ui"
}