[React+Tailwind] Flowbite で Dropdown を表示してみる | 心を無にして始める React

準備

Flowbite が使えるプロジェクトを準備します。

Dropdown コンポーネントをつくる

./src/components 配下に Dropdown.js を作ります。

import { forwardRef } from 'react';
import { Dropdown as FlowbiteDropdown } from 'flowbite-react';

const Dropdown = forwardRef((
  {
    arrowIcon = true,
    children,
    floatingArrow = false,
    inline = false,
    label,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteDropdown
      arrowIcon={arrowIcon}
      floatingArrow={floatingArrow}
      inline={inline}
      label={label}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteDropdown>
  );
});

const DropdownDivider = (
  {
    ...otherProps
  },
) => {
  return (
    <FlowbiteDropdown.Divider
      {...otherProps}
    />
  );
};

const DropdownHeader = forwardRef((
  {
    children,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteDropdown.Header
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteDropdown.Header>
  );
});

const DropdownItem = (
  {
    children,
    icon,
    onClick,
    ...otherProps
  },
) => {
  return (
    <FlowbiteDropdown.Item
      icon={icon}
      onClick={onClick}
      {...otherProps}
    >
      {children}
    </FlowbiteDropdown.Item>
  );
};

export default Object.assign(Dropdown, {
  Divider: DropdownDivider,
  Header: DropdownHeader,
  Item: DropdownItem,
});

Dropdown コンポーネントをつかう

いつものように App.js を編集していきます。

import { CubeIcon } from '@heroicons/react/24/solid';

import Dropdown from './components/Dropdown';
import './App.css';

function App() {
  return (
    <div className="dark">
      <div className="h-screen p-8 flex flex-col justify-center items-center dark:!bg-gray-900">
        <div className="flex gap-3">
          <Dropdown label="Dropdown button">
            <Dropdown.Item>
              Dashboard
            </Dropdown.Item>
            <Dropdown.Item>
              Settings
            </Dropdown.Item>
            <Dropdown.Item>
              Earnings
            </Dropdown.Item>
            <Dropdown.Item>
              Sign out
            </Dropdown.Item>
          </Dropdown>
        </div>
        <div className="mt-4 flex gap-3 dark:text-white">
          <Dropdown
            label="Dropdown"
            inline={true}
            placement="bottom-start"
          >
            <Dropdown.Header>
              <span className="block text-sm">
                Bonnie Green
              </span>
              <span className="block text-sm font-medium truncate">
                bonnie@example.com
              </span>
            </Dropdown.Header>
            <Dropdown.Item icon={CubeIcon}>
              Dashboard
            </Dropdown.Item>
            <Dropdown.Item icon={CubeIcon}>
              Settings
            </Dropdown.Item>
            <Dropdown.Item icon={CubeIcon}>
              Earnings
            </Dropdown.Item>
            <Dropdown.Divider />
            <Dropdown.Item icon={CubeIcon}>
              Sign out
            </Dropdown.Item>
          </Dropdown>
        </div>
      </div>
    </div>
  );
}

export default App;

結果

はい、できました。