{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"inputs","type":"registry:ui","title":"Inputs","description":"Inputs from react-fancy","package":"react-fancy","dependencies":[],"registryDependencies":[],"files":[{"path":"components\/fancy\/inputs\/InputWrapper.tsx","content":"import type { ReactNode } from \"react\";\r\nimport { cn } from \"..\/..\/utils\/cn\";\r\nimport type { AffixPosition } from \".\/inputs.types\";\r\nimport type { Size } from \"..\/..\/utils\/types\";\r\n\r\ninterface InputWrapperProps {\r\n  children: ReactNode;\r\n  prefix?: ReactNode;\r\n  suffix?: ReactNode;\r\n  prefixPosition?: AffixPosition;\r\n  suffixPosition?: AffixPosition;\r\n  size?: Size;\r\n  \/** Extra padding className to apply to the input when affixes are \"inside\" *\/\r\n  insidePrefixPadding?: string;\r\n  insideSuffixPadding?: string;\r\n}\r\n\r\n\/\/ NOTE: these must be COMPLETE, static class strings. Tailwind only detects\r\n\/\/ utilities it can see verbatim in the source \u2014 building the arbitrary variant\r\n\/\/ at runtime (e.g. `[&_input]:${\"pl-9\"}`) means `[&_input]:pl-9` is never\r\n\/\/ emitted to CSS, so the inside affix gets no padding and overlaps the text\r\n\/\/ (issue #6). Keep input\/select\/textarea spelled out here.\r\nconst insidePaddingLeft: Record<Size, string> = {\r\n  xs: \"[&_input]:pl-7 [&_select]:pl-7 [&_textarea]:pl-7\",\r\n  sm: \"[&_input]:pl-8 [&_select]:pl-8 [&_textarea]:pl-8\",\r\n  md: \"[&_input]:pl-9 [&_select]:pl-9 [&_textarea]:pl-9\",\r\n  lg: \"[&_input]:pl-10 [&_select]:pl-10 [&_textarea]:pl-10\",\r\n  xl: \"[&_input]:pl-11 [&_select]:pl-11 [&_textarea]:pl-11\",\r\n};\r\n\r\nconst insidePaddingRight: Record<Size, string> = {\r\n  xs: \"[&_input]:pr-7 [&_select]:pr-7 [&_textarea]:pr-7\",\r\n  sm: \"[&_input]:pr-8 [&_select]:pr-8 [&_textarea]:pr-8\",\r\n  md: \"[&_input]:pr-9 [&_select]:pr-9 [&_textarea]:pr-9\",\r\n  lg: \"[&_input]:pr-10 [&_select]:pr-10 [&_textarea]:pr-10\",\r\n  xl: \"[&_input]:pr-11 [&_select]:pr-11 [&_textarea]:pr-11\",\r\n};\r\n\r\nconst affixOutsideClasses =\r\n  \"inline-flex items-center border border-zinc-300 bg-zinc-50 px-3 text-sm text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-400\";\r\n\r\nexport function InputWrapper({\r\n  children,\r\n  prefix,\r\n  suffix,\r\n  prefixPosition = \"inside\",\r\n  suffixPosition = \"inside\",\r\n  size = \"md\",\r\n}: InputWrapperProps) {\r\n  const hasInsidePrefix = prefix && prefixPosition === \"inside\";\r\n  const hasInsideSuffix = suffix && suffixPosition === \"inside\";\r\n  const hasOutsidePrefix = prefix && prefixPosition === \"outside\";\r\n  const hasOutsideSuffix = suffix && suffixPosition === \"outside\";\r\n  const hasOutside = hasOutsidePrefix || hasOutsideSuffix;\r\n\r\n  if (!prefix && !suffix) {\r\n    return <>{children}<\/>;\r\n  }\r\n\r\n  if (hasOutside) {\r\n    return (\r\n      <div data-react-fancy-input-wrapper=\"\" className=\"flex\">\r\n        {hasOutsidePrefix && (\r\n          <span className={cn(affixOutsideClasses, \"rounded-l-lg border-r-0\")}>\r\n            {prefix}\r\n          <\/span>\r\n        )}\r\n        <div\r\n          className={cn(\r\n            \"relative flex flex-1 items-center\",\r\n            hasInsidePrefix && \"relative\",\r\n          )}\r\n        >\r\n          {hasInsidePrefix && (\r\n            <span className=\"pointer-events-none absolute left-3 z-10 text-zinc-400 dark:text-zinc-500\">\r\n              {prefix}\r\n            <\/span>\r\n          )}\r\n          <div\r\n            className={cn(\r\n              \"w-full [&>*]:w-full\",\r\n              hasOutsidePrefix && !hasOutsideSuffix && \"[&_input]:rounded-l-none [&_select]:rounded-l-none [&_textarea]:rounded-l-none\",\r\n              !hasOutsidePrefix && hasOutsideSuffix && \"[&_input]:rounded-r-none [&_select]:rounded-r-none [&_textarea]:rounded-r-none\",\r\n              hasOutsidePrefix && hasOutsideSuffix && \"[&_input]:rounded-none [&_select]:rounded-none [&_textarea]:rounded-none\",\r\n              hasInsidePrefix && insidePaddingLeft[size],\r\n            )}\r\n          >\r\n            {children}\r\n          <\/div>\r\n          {hasInsideSuffix && (\r\n            <span className=\"pointer-events-none absolute right-3 z-10 text-zinc-400 dark:text-zinc-500\">\r\n              {suffix}\r\n            <\/span>\r\n          )}\r\n        <\/div>\r\n        {hasOutsideSuffix && (\r\n          <span className={cn(affixOutsideClasses, \"rounded-r-lg border-l-0\")}>\r\n            {suffix}\r\n          <\/span>\r\n        )}\r\n      <\/div>\r\n    );\r\n  }\r\n\r\n  \/\/ Both inside\r\n  return (\r\n    <div data-react-fancy-input-wrapper=\"\" className=\"relative flex items-center\">\r\n      {hasInsidePrefix && (\r\n        <span className=\"pointer-events-none absolute left-3 z-10 text-zinc-400 dark:text-zinc-500\">\r\n          {prefix}\r\n        <\/span>\r\n      )}\r\n      <div\r\n        className={cn(\r\n          \"w-full\",\r\n          hasInsidePrefix && insidePaddingLeft[size],\r\n          hasInsideSuffix && insidePaddingRight[size],\r\n        )}\r\n      >\r\n        {children}\r\n      <\/div>\r\n      {hasInsideSuffix && (\r\n        <span className=\"pointer-events-none absolute right-3 z-10 text-zinc-400 dark:text-zinc-500\">\r\n          {suffix}\r\n        <\/span>\r\n      )}\r\n    <\/div>\r\n  );\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/inputs\/InputWrapper.tsx"},{"path":"components\/fancy\/inputs\/index.ts","content":"export { Field } from \".\/Field\";\r\nexport type { FieldProps } from \".\/Field\";\r\n\r\nexport { Input } from \".\/Input\";\r\nexport type { InputProps } from \".\/Input\";\r\n\r\nexport { Textarea } from \".\/Textarea\";\r\nexport type { TextareaProps } from \".\/Textarea\";\r\n\r\nexport { Select } from \".\/Select\";\r\nexport type { SelectProps } from \".\/Select\";\r\n\r\nexport { Checkbox } from \".\/Checkbox\";\r\nexport type { CheckboxProps } from \".\/Checkbox\";\r\n\r\nexport { CheckboxGroup } from \".\/CheckboxGroup\";\r\nexport type { CheckboxGroupProps } from \".\/CheckboxGroup\";\r\n\r\nexport { RadioGroup } from \".\/RadioGroup\";\r\nexport type { RadioGroupProps } from \".\/RadioGroup\";\r\n\r\nexport { Switch } from \".\/Switch\";\r\nexport type { SwitchProps } from \".\/Switch\";\r\n\r\nexport { Slider } from \".\/Slider\";\r\nexport type { SliderProps, SliderSingleProps, SliderRangeProps } from \".\/Slider\";\r\n\r\nexport { MultiSwitch } from \".\/MultiSwitch\";\r\nexport type { MultiSwitchProps } from \".\/MultiSwitch\";\r\n\r\nexport { DatePicker } from \".\/DatePicker\";\r\nexport type { DatePickerProps, DatePickerSingleProps, DatePickerRangeProps } from \".\/DatePicker\";\r\n\r\nexport type { FieldMode, InputBaseProps, InputOption, InputOptionGroup, AffixPosition, InputAffixProps } from \".\/inputs.types\";\r\n\r\n\/\/ Display-mode form binding: <Form mode>\/<FormProvider mode> + useFieldMode + DisplayValue.\r\nexport * from \".\/mode\";\r\n","type":"registry:ui","target":"components\/fancy\/inputs\/index.ts"},{"path":"components\/fancy\/inputs\/inputs.types.ts","content":"import type { ReactNode } from \"react\";\r\nimport type { Size } from \"..\/..\/utils\/types\";\r\n\r\nexport type InputOption<V = string> =\r\n  | string\r\n  | { value: V; label: string; disabled?: boolean; description?: string };\r\n\r\nexport type InputOptionGroup<V = string> = {\r\n  label: string;\r\n  options: InputOption<V>[];\r\n};\r\n\r\n\/**\r\n * Edit vs. read-only display. In `\"view\"` mode an input renders the bound value\r\n * as static text instead of an interactive control \u2014 the React\/Inertia analog of\r\n * Livewire's public\/bindable properties. Declared here (rather than in `mode\/`)\r\n * to keep `InputBaseProps` free of an import cycle. Resolved per input via\r\n * {@link useFieldMode}: explicit prop \u2192 `<Form>`\/`<FormProvider>` context \u2192 `\"edit\"`.\r\n *\/\r\nexport type FieldMode = \"edit\" | \"view\";\r\n\r\nexport interface InputBaseProps {\r\n  size?: Size;\r\n  dirty?: boolean;\r\n  error?: string;\r\n  label?: string;\r\n  description?: string;\r\n  required?: boolean;\r\n  disabled?: boolean;\r\n  className?: string;\r\n  id?: string;\r\n  name?: string;\r\n  \/** `\"edit\"` (default) renders the control; `\"view\"` renders the value as text. Overrides the `<Form mode>` context. *\/\r\n  mode?: FieldMode;\r\n}\r\n\r\nexport type AffixPosition = \"inside\" | \"outside\";\r\n\r\nexport interface InputAffixProps {\r\n  prefix?: ReactNode;\r\n  suffix?: ReactNode;\r\n  prefixPosition?: AffixPosition;\r\n  suffixPosition?: AffixPosition;\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/inputs\/inputs.types.ts"},{"path":"components\/fancy\/inputs\/inputs.utils.ts","content":"import type { Size } from \"..\/..\/utils\/types\";\r\nimport type { InputOption } from \".\/inputs.types\";\r\n\r\nexport const inputSizeClasses: Record<Size, string> = {\r\n  xs: \"px-2 py-1 text-xs rounded\",\r\n  sm: \"px-2.5 py-1.5 text-sm rounded-md\",\r\n  md: \"px-3 py-2 text-sm rounded-lg\",\r\n  lg: \"px-4 py-2.5 text-base rounded-lg\",\r\n  xl: \"px-5 py-3 text-lg rounded-xl\",\r\n};\r\n\r\nexport const labelSizeClasses: Record<Size, string> = {\r\n  xs: \"text-xs\",\r\n  sm: \"text-xs\",\r\n  md: \"text-sm\",\r\n  lg: \"text-sm\",\r\n  xl: \"text-base\",\r\n};\r\n\r\nexport function dirtyClasses(dirty?: boolean): string {\r\n  return dirty ? \"border-l-[3px] border-l-amber-400\" : \"\";\r\n}\r\n\r\nexport function dirtyRingClasses(dirty?: boolean): string {\r\n  return dirty ? \"ring-2 ring-amber-400\/50\" : \"\";\r\n}\r\n\r\nexport function errorClasses(error?: string): string {\r\n  return error ? \"border-red-500 focus:ring-red-500\" : \"\";\r\n}\r\n\r\nexport const inputBaseClasses =\r\n  \"border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 transition-[border-color,box-shadow] duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500\/40 focus:border-blue-500 disabled:opacity-50 disabled:cursor-not-allowed dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:focus:border-blue-400 dark:focus:ring-blue-400\/20\";\r\n\r\nexport function resolveOption<V = string>(\r\n  option: InputOption<V>,\r\n): { value: V; label: string; disabled?: boolean; description?: string } {\r\n  if (typeof option === \"string\") {\r\n    return { value: option as unknown as V, label: option };\r\n  }\r\n  return option;\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/inputs\/inputs.utils.ts"}]}