Skip to content

Latest commit

 

History

History
285 lines (244 loc) · 6.61 KB

composition.mdx

File metadata and controls

285 lines (244 loc) · 6.61 KB

Composition

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.

Basic Usage

import { Checkbox } from "@adaptui/react-tailwind";

export const App = (props) => {
  return <Checkbox size="md" defaultValue={true} {...props} />;
};

Simple Composition

Directly pass the atomic components specific to its complex component as childrens or as render prop.

Without state as childrens

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

With State 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">
      {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>
  );
};

Advanced Composition

Only compose using the atomic components specific to its complex component separately with the help of useComponentProps & useComponentState.

Using useComponentProps

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

Using useComponentState

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