mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
168 lines
4.1 KiB
TypeScript
168 lines
4.1 KiB
TypeScript
import type {AriaCheckboxProps} from "@react-types/checkbox";
|
|
import type {HTMLNextUIProps, CSS} from "@nextui-org/system";
|
|
import type {IPressResult, IFocusRingAria} from "@nextui-org/dom-utils";
|
|
|
|
import {useMemo, useRef} from "react";
|
|
import {useToggleState} from "@react-stately/toggle";
|
|
import {useHover, usePress} from "@react-aria/interactions";
|
|
import {useFocusRing} from "@react-aria/focus";
|
|
import {NormalSizes, NormalColors, SimpleColors, __DEV__, warn} from "@nextui-org/shared-utils";
|
|
import {
|
|
useCheckbox as useReactAriaCheckbox,
|
|
useCheckboxGroupItem as useReactAriaCheckboxGroupItem,
|
|
} from "@react-aria/checkbox";
|
|
|
|
import {useCheckboxGroupContext} from "./checkbox-group-context";
|
|
|
|
export interface UseCheckboxProps extends HTMLNextUIProps<"label", AriaCheckboxProps> {
|
|
/**
|
|
* The content to display as the label.
|
|
*/
|
|
label?: string;
|
|
/**
|
|
* The color of the checkbox.
|
|
* @default "default"
|
|
*/
|
|
color?: NormalColors;
|
|
/**
|
|
* The color of the label.
|
|
* @default "default"
|
|
*/
|
|
labelColor?: SimpleColors;
|
|
/**
|
|
* The size of the checkbox.
|
|
* @default "md"
|
|
*/
|
|
size?: NormalSizes;
|
|
/**
|
|
* Whether the checkbox is rounded.
|
|
* @default false
|
|
*/
|
|
isRounded?: boolean;
|
|
/**
|
|
* Line in the middle of the label when the `Checkbox` is checked
|
|
* @default false
|
|
*/
|
|
lineThrough?: boolean;
|
|
/**
|
|
* Whether the checkbox has animations.
|
|
* @default false
|
|
*/
|
|
disableAnimation?: boolean;
|
|
/**
|
|
* Override checkbox container CSS style
|
|
*/
|
|
containerCss?: CSS;
|
|
}
|
|
|
|
export function useCheckbox(props: UseCheckboxProps) {
|
|
const groupContext = useCheckboxGroupContext();
|
|
|
|
const {
|
|
size = groupContext?.size ?? "md",
|
|
color = groupContext?.color ?? "default",
|
|
labelColor = groupContext?.labelColor ?? "default",
|
|
lineThrough,
|
|
isSelected,
|
|
value = "",
|
|
isRounded = false,
|
|
isRequired = false,
|
|
disableAnimation = false,
|
|
isIndeterminate = false,
|
|
defaultSelected,
|
|
onChange,
|
|
containerCss,
|
|
...otherProps
|
|
} = props;
|
|
|
|
if (groupContext && __DEV__) {
|
|
if (isSelected) {
|
|
warn(
|
|
"The Checkbox.Group is being used, `isSelected` will be ignored. Use the `value` of the Checkbox.Group instead.",
|
|
"Checkbox",
|
|
);
|
|
}
|
|
if (defaultSelected) {
|
|
warn(
|
|
"The Checkbox.Group is being used, `defaultSelected` will be ignored. Use the `defaultValue` of the Checkbox.Group instead.",
|
|
"Checkbox",
|
|
);
|
|
}
|
|
}
|
|
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
|
|
const ariaCheckboxProps = useMemo(() => {
|
|
return {
|
|
...otherProps,
|
|
value,
|
|
defaultSelected,
|
|
isSelected,
|
|
isIndeterminate,
|
|
isRequired,
|
|
onChange,
|
|
};
|
|
}, [isIndeterminate, otherProps]);
|
|
|
|
const {inputProps} = groupContext
|
|
? // eslint-disable-next-line
|
|
useReactAriaCheckboxGroupItem(
|
|
{
|
|
...ariaCheckboxProps,
|
|
validationState: otherProps.validationState,
|
|
},
|
|
groupContext.groupState,
|
|
inputRef,
|
|
)
|
|
: useReactAriaCheckbox(ariaCheckboxProps, useToggleState(ariaCheckboxProps), inputRef); // eslint-disable-line
|
|
|
|
if (isRequired) {
|
|
inputProps.required = true;
|
|
}
|
|
|
|
const {hoverProps, isHovered} = useHover({
|
|
isDisabled: inputProps.disabled,
|
|
});
|
|
|
|
// TODO: Event's propagation wasn't stopped https://github.com/adobe/react-spectrum/issues/2383
|
|
const {pressProps}: IPressResult<UseCheckboxProps> = usePress({
|
|
isDisabled: inputProps.disabled,
|
|
});
|
|
|
|
const {focusProps, isFocusVisible}: IFocusRingAria<UseCheckboxProps> = useFocusRing({
|
|
autoFocus: inputProps.autoFocus,
|
|
});
|
|
|
|
const state = useMemo(() => {
|
|
if (isHovered) return "hovered";
|
|
|
|
return isIndeterminate && inputProps.checked
|
|
? "mixed"
|
|
: inputProps.checked
|
|
? "checked"
|
|
: "uncheked";
|
|
}, [isHovered, isIndeterminate, inputProps.checked]);
|
|
|
|
return {
|
|
size,
|
|
color,
|
|
state,
|
|
labelColor,
|
|
isRounded,
|
|
lineThrough,
|
|
disableAnimation,
|
|
isIndeterminate,
|
|
isFocusVisible,
|
|
isHovered,
|
|
inputRef,
|
|
inputProps,
|
|
pressProps,
|
|
hoverProps,
|
|
focusProps,
|
|
containerCss,
|
|
...otherProps,
|
|
};
|
|
}
|
|
|
|
export type UseCheckboxReturn = ReturnType<typeof useCheckbox>;
|