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

準備

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

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

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

import { forwardRef } from 'react';
import { Footer as FlowbiteFooter } from 'flowbite-react';

const Footer = forwardRef((
  {
    bgDark = false,
    children,
    container = false,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter
      bgDark={bgDark}
      container={container}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter>
  );
});

const FooterBrand = forwardRef((
  {
    alt,
    children,
    href,
    name,
    src,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Brand
      alt={alt}
      href={href}
      name={name}
      ref={ref}
      src={src}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Brand>
  );
});

const FooterCopyright = forwardRef((
  {
    by,
    children,
    href,
    year,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Copyright
      by={by}
      href={href}
      ref={ref}
      year={year}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Copyright>
  );
});

const FooterDivider = (
  {
    ...otherProps
  },
) => {
  return (
    <FlowbiteFooter.Divider
      {...otherProps}
    />
  );
};

const FooterIcon = forwardRef((
  {
    ariaLabel,
    children,
    href,
    icon,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Icon
      ariaLabel={ariaLabel}
      href={href}
      icon={icon}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Icon>
  );
});

const FooterLink = forwardRef((
  {
    children,
    href,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Link
      href={href}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Link>
  );
});

const FooterLinkGroup = forwardRef((
  {
    children,
    col = false,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.LinkGroup
      col={col}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.LinkGroup>
  );
});

const FooterTitle = forwardRef((
  {
    children,
    title,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteFooter.Title
      ref={ref}
      title={title}
      {...otherProps}
    >
      {children}
    </FlowbiteFooter.Title>
  );
});

export default Object.assign(Footer, {
  Brand: FooterBrand,
  Copyright: FooterCopyright,
  Divider: FooterDivider,
  Icon: FooterIcon,
  Link: FooterLink,
  LinkGroup: FooterLinkGroup,
  Title: FooterTitle,
});

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

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

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

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

function App() {
  return (
    <div className="dark">
      
      <div className="min-h-screen p-8 gap-4 flex flex-col justify-center items-center dark:!bg-gray-900">
        <div className="w-full">
          <Footer container={true}>
            <Footer.Copyright
              href="https://neko-note.org"
              by="それなら猫の手で"
              year={2022}
            />
            <Footer.LinkGroup>
              <Footer.Link href="#">About</Footer.Link>
              <Footer.Link href="#">Privacy Policy</Footer.Link>
              <Footer.Link href="#">Licensing</Footer.Link>
              <Footer.Link href="#">Contact</Footer.Link>
            </Footer.LinkGroup>
          </Footer>
        </div>
        <div className="w-full">
          <Footer container={true}>
            <div className="w-full">
              <div className="grid w-full justify-between sm:flex sm:justify-between md:flex md:grid-cols-1">
                <div>
                  <Footer.Brand
                    href="https://neko-note.org"
                    name="それなら猫の手で"
                  />
                </div>
                <div className="grid grid-cols-2 gap-8 sm:mt-4 sm:grid-cols-3 sm:gap-6">
                  <div>
                    <Footer.Title title="about" />
                    <Footer.LinkGroup col={true}>
                      <Footer.Link href="#">Flowbite</Footer.Link>
                      <Footer.Link href="#">Tailwind CSS</Footer.Link>
                    </Footer.LinkGroup>
                  </div>
                  <div>
                    <Footer.Title title="Follow us" />
                    <Footer.LinkGroup col={true}>
                      <Footer.Link href="#">Github</Footer.Link>
                      <Footer.Link href="#">Discord</Footer.Link>
                    </Footer.LinkGroup>
                  </div>
                  <div>
                    <Footer.Title title="Legal" />
                    <Footer.LinkGroup col={true}>
                      <Footer.Link href="#">Privacy Policy</Footer.Link>
                      <Footer.Link href="#">Terms & Conditions</Footer.Link>
                    </Footer.LinkGroup>
                  </div>
                </div>
              </div>
              <Footer.Divider />
              <div className="w-full sm:flex sm:items-center sm:justify-between">
                <Footer.Copyright
                  href="https://neko-note.org"
                  by="それなら猫の手で"
                  year={2022}
                />
                <div className="mt-4 flex space-x-6 sm:mt-0 sm:justify-center">
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                </div>
              </div>
            </div>
          </Footer>
        </div>
        <div className="w-full">
          <Footer bgDark={true}>
            <div className="w-full">
              <div className="grid w-full grid-cols-2 gap-8 py-8 px-6 md:grid-cols-4">
                <div>
                  <Footer.Title title="Company" />
                  <Footer.LinkGroup col={true}>
                    <Footer.Link href="#">About</Footer.Link>
                    <Footer.Link href="#">Careers</Footer.Link>
                    <Footer.Link href="#">Brand Center</Footer.Link>
                    <Footer.Link href="#">Blog</Footer.Link>
                  </Footer.LinkGroup>
                </div>
                <div>
                  <Footer.Title title="help center" />
                  <Footer.LinkGroup col={true}>
                    <Footer.Link href="#">Discord Server</Footer.Link>
                    <Footer.Link href="#">Twitter</Footer.Link>
                    <Footer.Link href="#">Facebook</Footer.Link>
                    <Footer.Link href="#">Contact Us</Footer.Link>
                  </Footer.LinkGroup>
                </div>
                <div>
                  <Footer.Title title="legal" />
                  <Footer.LinkGroup col={true}>
                    <Footer.Link href="#">Privacy Policy</Footer.Link>
                    <Footer.Link href="#">Licensing</Footer.Link>
                    <Footer.Link href="#">Terms & Conditions</Footer.Link>
                  </Footer.LinkGroup>
                </div>
                <div>
                  <Footer.Title title="download" />
                  <Footer.LinkGroup col={true}>
                    <Footer.Link href="#">iOS</Footer.Link>
                    <Footer.Link href="#">Android</Footer.Link>
                    <Footer.Link href="#">Windows</Footer.Link>
                    <Footer.Link href="#">MacOS</Footer.Link>
                  </Footer.LinkGroup>
                </div>
              </div>
              <div className="w-full bg-gray-700 py-6 px-4 sm:flex sm:items-center sm:justify-between">
                <Footer.Copyright
                  href="https://neko-note.org"
                  by="それなら猫の手で"
                  year={2022}
                />
                <div className="mt-4 flex space-x-6 sm:mt-0 sm:justify-center">
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                  <Footer.Icon href="#" icon={CubeIcon} />
                </div>
              </div>
            </div>
          </Footer>
        </div>
      </div>
    </div>
  );
}

export default App;

結果

はい、できました。