111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
import {
|
|
createContext,
|
|
forwardRef,
|
|
useContext,
|
|
type ComponentPropsWithoutRef
|
|
} from "react";
|
|
|
|
import {
|
|
inputGroupAffixVariants,
|
|
inputGroupVariants
|
|
} from "./input-group.variants";
|
|
import { cn } from "../lib/cn";
|
|
import type { VariantProps } from "../lib/cva";
|
|
import type { FieldStateProps } from "../lib/contracts";
|
|
import { createDataAttributes, createSlot } from "../lib/contracts";
|
|
import { useFieldContext } from "./field";
|
|
|
|
type InputGroupContextValue = {
|
|
disabled: boolean;
|
|
invalid: boolean;
|
|
readOnly: boolean;
|
|
required: boolean;
|
|
size: Exclude<VariantProps<typeof inputGroupVariants>["size"], null | undefined>;
|
|
};
|
|
|
|
const InputGroupContext = createContext<InputGroupContextValue | null>(null);
|
|
|
|
export function useInputGroupContext() {
|
|
return useContext(InputGroupContext);
|
|
}
|
|
|
|
export type InputGroupProps = ComponentPropsWithoutRef<"div"> &
|
|
FieldStateProps &
|
|
VariantProps<typeof inputGroupVariants>;
|
|
|
|
export const InputGroup = forwardRef<HTMLDivElement, InputGroupProps>(function InputGroup(
|
|
{
|
|
className,
|
|
disabled,
|
|
invalid,
|
|
readOnly,
|
|
required,
|
|
size = "md",
|
|
...props
|
|
},
|
|
ref
|
|
) {
|
|
const field = useFieldContext();
|
|
const resolvedDisabled = disabled ?? field?.disabled ?? false;
|
|
const resolvedInvalid = invalid ?? field?.invalid ?? false;
|
|
const resolvedReadOnly = readOnly ?? field?.readOnly ?? false;
|
|
const resolvedRequired = required ?? field?.required ?? false;
|
|
const resolvedSize = size ?? "md";
|
|
|
|
return (
|
|
<InputGroupContext.Provider
|
|
value={{
|
|
disabled: resolvedDisabled,
|
|
invalid: resolvedInvalid,
|
|
readOnly: resolvedReadOnly,
|
|
required: resolvedRequired,
|
|
size: resolvedSize
|
|
}}
|
|
>
|
|
<div
|
|
{...props}
|
|
{...createSlot("control")}
|
|
{...createDataAttributes({
|
|
disabled: resolvedDisabled,
|
|
invalid: resolvedInvalid,
|
|
readonly: resolvedReadOnly,
|
|
required: resolvedRequired,
|
|
size: resolvedSize
|
|
})}
|
|
className={cn(inputGroupVariants({ size: resolvedSize }), className)}
|
|
ref={ref}
|
|
/>
|
|
</InputGroupContext.Provider>
|
|
);
|
|
});
|
|
|
|
export type InputGroupPrefixProps = ComponentPropsWithoutRef<"div">;
|
|
|
|
export const InputGroupPrefix = forwardRef<HTMLDivElement, InputGroupPrefixProps>(
|
|
function InputGroupPrefix({ className, ...props }, ref) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
{...createSlot("prefix")}
|
|
className={cn(inputGroupAffixVariants(), className)}
|
|
ref={ref}
|
|
/>
|
|
);
|
|
}
|
|
);
|
|
|
|
export type InputGroupSuffixProps = ComponentPropsWithoutRef<"div">;
|
|
|
|
export const InputGroupSuffix = forwardRef<HTMLDivElement, InputGroupSuffixProps>(
|
|
function InputGroupSuffix({ className, ...props }, ref) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
{...createSlot("suffix")}
|
|
className={cn(inputGroupAffixVariants(), className)}
|
|
ref={ref}
|
|
/>
|
|
);
|
|
}
|
|
);
|