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

準備

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

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

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

import { forwardRef } from 'react';
import { Avatar as FlowbiteAvatar } from 'flowbite-react';

const Avatar = forwardRef((
  {
    alt = "",
    bordered = false,
    children,
    img,
    rounded = false,
    size = 'md',
    stacked = false,
    status, // 'away' | 'busy' | 'offline' | 'online'
    statusPosition = "top-right",
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteAvatar
      alt={alt}
      bordered={bordered}
      img={img}
      ref={ref}
      rounded={rounded}
      size={size}
      stacked={stacked}
      status={status}
      statusPosition={statusPosition}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar>
  );
});

const AvatarGroup = (
  {
    children,
    ...otherProps
  },
) => {
  return (
    <FlowbiteAvatar.Group {...otherProps}>
      {children}
    </FlowbiteAvatar.Group>
  );
};

const AvatarGroupCounter = (
  {
    children,
    href,
    total,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteAvatar.Counter
      href={href}
      total={total}
      {...otherProps}
    >
      {children}
    </FlowbiteAvatar.Counter>
  );
};

export default Object.assign(Avatar, {
  Group: AvatarGroup,
  GroupCounter: AvatarGroupCounter,
});

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

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

import Avatar from './components/Avatar';
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">
          <Avatar
            alt="Avatar"
            bordered={true}
            size="xl"
          />
          <Avatar
            alt="A"
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=A"
            rounded={true}
          />
          <Avatar
            alt="v"
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=v"
          />
          <Avatar
            alt="a"
            bordered={true}
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=a"
            rounded={true}
            status="away"
            statusPosition="top-left"
          />
          <Avatar
            alt="t"
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=t"
            status="busy"
            statusPosition="top-right"
          />
          <Avatar
            alt="a"
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=a"
            rounded={true}
            status="offline"
            statusPosition="bottom-left"
          />
          <Avatar
            alt="r"
            bordered={true}
            img="https://placehold.jp/32/3d4070/ffffff/64x64.png?text=r"
            status="online"
            statusPosition="bottom-right"
          />
        </div>
        <div className="mt-4">
          <Avatar.Group>
            <Avatar rounded={true} stacked={true} />
            <Avatar rounded={true} stacked={true} />
            <Avatar rounded={true} stacked={true} />
            <Avatar rounded={true} stacked={true} />
            <Avatar rounded={true} stacked={true} />
            <Avatar.GroupCounter
              href="#"
              total={99}
            />
          </Avatar.Group>
        </div>
      </div>
    </div>
  );
}

export default App;

結果

はい、できました。