Each and every atomic components in our library supports Ariakit's Composition
Atomic components are put together into a single complex component in most of the components. Inorder to customize the behavior of this complex component, we provide two ways to customize it as per the needs.
- Simple Composition
- Advanced Composition
Let's take the Checkbox component to explain the composition.
import { Checkbox } from "@adaptui/react-tailwind";
export const App = (props) => {
return <Checkbox size="md" defaultValue={true} {...props} />;
};
Directly pass the atomic components specific to its complex component as childrens or as render prop.
import {
Checkbox,
CheckboxLabel,
CheckboxIcon,
CheckboxText,
CheckboxDescription,
} from "@adaptui/react-tailwind";
export const App = props => {
return (
<Checkbox label="Checkbox" description="Fruits in the basket">
<CheckboxLabel className="rounded border-2 border-blue-500 p-2" />
<CheckboxIcon className="bg-red-500" />
<CheckboxText className="text-green-500">New Checkbox</CheckboxText>
<CheckboxDescription className="text-orange-500">
New Description
</CheckboxDescription>
</Checkbox>
);
};
import {
Checkbox,
CheckboxLabel,
CheckboxIcon,
CheckboxText,
CheckboxDescription,
} from "@adaptui/react-tailwind";
export const App = props => {
return (
<Checkbox label="Checkbox" description="Fruits in the basket">
{uiProps => {
return (
<>
<CheckboxLabel className="rounded border-2 border-blue-500 p-2" />
<CheckboxIcon
className={
uiProps.isChecked
? "bg-red-500 peer-hover:bg-red-400"
: "bg-green-500 peer-hover:bg-green-400"
}
>
<>
{uiProps.isUnchecked
? withIconA11y(<EyeClose />, {}, {})
: null}
{uiProps.isChecked ? withIconA11y(<EyeOpen />, {}, {}) : null}
</>
</CheckboxIcon>
<CheckboxText className="text-green-500">
Overidden Label
</CheckboxText>
<CheckboxDescription className="text-orange-500">
Overridden Description
</CheckboxDescription>
</>
);
}}
</Checkbox>
);
};
Only compose using the atomic components specific to its complex component
separately with the help of useComponentProps
& useComponentState
.
Basic usage that can be used to add additional DOM elements within these atomic components but cannot change the state or the libraries behavior.
import {
Checkbox,
CheckboxLabel,
CheckboxIcon,
CheckboxText,
CheckboxDescription,
} from "@adaptui/react-tailwind";
export const App = props => {
const {
labelProps,
inputProps,
iconProps,
textWrapperProps,
textProps,
descriptionProps,
uiProps,
} = useCheckboxProps(props);
const { label, description, isChecked, isUnchecked } = uiProps;
return (
<CheckboxLabel
className="rounded border-2 border-blue-500 p-2"
{...labelProps}
>
<CheckboxInput {...inputProps} />
<CheckboxIcon
className={
isChecked
? "bg-red-500 peer-hover:bg-red-400"
: "bg-green-500 peer-hover:bg-green-400"
}
{...iconProps}
>
<>
{isUnchecked ? withIconA11y(<EyeClose />) : null}
{isChecked ? withIconA11y(<EyeOpen />) : null}
</>
</CheckboxIcon>
<div>
<CheckboxText className="text-green-500" {...textProps}>
Label
</CheckboxText>
<CheckboxDescription className="text-orange-500" {...descriptionProps}>
Description
</CheckboxDescription>
</div>
</CheckboxLabel>
);
};
Advanced usage that uses the only the Component State to change the behavior of the component that is different from library logic.
import {
Checkbox,
CheckboxLabel,
CheckboxIcon,
CheckboxText,
CheckboxDescription,
} from "@adaptui/react-tailwind";
import * as Ariakit from "ariakit";
export const App = props => {
const CustomCheckbox = props => {
const {
state,
value,
defaultValue,
setValue,
inputValue,
size,
icon,
label,
description,
className,
style,
children,
...restProps
} = props;
const uiState = useCheckboxUIState({
state,
inputValue,
size,
icon,
label,
description,
});
const uiProps = React.useMemo(
() => ({ state, ...uiState }),
[state, uiState],
);
return (
<CheckboxLabel
{...uiState}
className={tcm("rounded border-2 border-blue-500 px-8 py-2", className)}
>
<CheckboxInput {...uiProps} {...restProps} value={inputValue} />
{uiProps.isChecked ? (
<CheckboxIcon className="absolute inset-y-0 left-0 flex items-center pl-1.5 text-blue-500">
<svg
className="h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
role="img"
focusable={false}
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
</CheckboxIcon>
) : null}
<span className="select-none">{children}</span>
</CheckboxLabel>
);
};
const state = Ariakit.useCheckboxState({ defaultValue: [] });
return (
<>
<CustomCheckbox className=" text-gray-800" inputValue="one" state={state}>
Button one 😁
</CustomCheckbox>
<CustomCheckbox
className="ml-2 text-gray-800"
inputValue="two"
state={state}
>
Button two 🤓
</CustomCheckbox>
<CustomCheckbox
className="ml-2 text-gray-800"
inputValue="three"
state={state}
>
Button three 👻
</CustomCheckbox>
</>
);
};