Files
cadence-ui/packages/ui/src/components/input-group.tsx
T

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}
/>
);
}
);