[React+Tailwind] Timeline を TypeScript に書き直してみた | 心を無にして始める React

準備

書き直すベースはこちらの Timeline コンポーネントです。

JavaScript

ベースの Timeline.js です。

import React, { forwardRef } from 'react';
import {
  Timeline as FlowbiteTimeline,
} from 'flowbite-react';

const Timeline = (
  {
    children,
    className,
    horizontal,
    ...otherProps
  },
) => {
  return (
    <FlowbiteTimeline
      className={className}
      horizontal={horizontal}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline>
  );
};

const TimelineItem = forwardRef((
  {
    children,
    className,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Item
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Item>
  );
});

const TimelinePoint = forwardRef((
  {
    children,
    className,
    icon,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Point
      className={className}
      icon={icon}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Point>
  );
});

const TimelineContent = forwardRef((
  {
    children,
    className,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Content
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Content>
  );
});

const TimelineTime = forwardRef((
  {
    children,
    className,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Time
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Time>
  );
});

const TimelineTitle = forwardRef((
  {
    as,
    children,
    className,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Title
      as={as}
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Title>
  );
});

const TimelineBody = forwardRef((
  {
    children,
    className,
    ...otherProps
  },
  ref,
) => {
  return (
    <FlowbiteTimeline.Body
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Body>
  );
});

export default Object.assign(Timeline, {
  Item: TimelineItem,
  Point: TimelinePoint,
  Content: TimelineContent,
  Time: TimelineTime,
  Title: TimelineTitle,
  Body: TimelineBody,
});

TypeScript

Timeline.tsx として編集します。

import React, { ComponentProps, forwardRef, LegacyRef } from 'react';
import {
  Timeline as FlowbiteTimeline,
  TimelineProps as FlowbiteTimelineProps,
} from 'flowbite-react';

type TimelineProps = {} & FlowbiteTimelineProps;

const Timeline = (
  {
    children,
    className,
    horizontal,
    ...otherProps
  }: TimelineProps,
) => {
  return (
    <FlowbiteTimeline
      className={className}
      horizontal={horizontal}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline>
  );
};

type TimelineItemProps = {} & ComponentProps<typeof FlowbiteTimeline.Item>;

const TimelineItem = forwardRef((
  {
    children,
    className,
    ...otherProps
  }: TimelineItemProps,
  ref: LegacyRef<HTMLLIElement>,
) => {
  return (
    <FlowbiteTimeline.Item
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Item>
  );
});

type TimelinePointProps = {} & ComponentProps<typeof FlowbiteTimeline.Point>;

const TimelinePoint = forwardRef((
  {
    children,
    className,
    icon,
    ...otherProps
  }: TimelinePointProps,
  ref: LegacyRef<HTMLDivElement>,
) => {
  return (
    <FlowbiteTimeline.Point
      className={className}
      icon={icon}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Point>
  );
});

type TimelineContentProps = {} & ComponentProps<typeof FlowbiteTimeline.Content>;

const TimelineContent = forwardRef((
  {
    children,
    className,
    ...otherProps
  }: TimelineContentProps,
  ref: LegacyRef<HTMLDivElement>,
) => {
  return (
    <FlowbiteTimeline.Content
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Content>
  );
});

type TimelineTimeProps = {} & ComponentProps<typeof FlowbiteTimeline.Time>;

const TimelineTime = forwardRef((
  {
    children,
    className,
    ...otherProps
  }: TimelineTimeProps,
  ref: LegacyRef<HTMLTimeElement>,
) => {
  return (
    <FlowbiteTimeline.Time
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Time>
  );
});

type TimelineTitleProps = {} & ComponentProps<typeof FlowbiteTimeline.Title>;

const TimelineTitle = forwardRef((
  {
    as,
    children,
    className,
    ...otherProps
  }: TimelineTitleProps,
  ref: LegacyRef<HTMLHeadingElement>,
) => {
  return (
    <FlowbiteTimeline.Title
      as={as}
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Title>
  );
});

type TimelineBodyProps = {} & ComponentProps<typeof FlowbiteTimeline.Body>;

const TimelineBody = forwardRef((
  {
    children,
    className,
    ...otherProps
  }: TimelineBodyProps,
  ref: LegacyRef<HTMLParagraphElement>,
) => {
  return (
    <FlowbiteTimeline.Body
      className={className}
      ref={ref}
      {...otherProps}
    >
      {children}
    </FlowbiteTimeline.Body>
  );
});

export default Object.assign(Timeline, {
  Item: TimelineItem,
  Point: TimelinePoint,
  Content: TimelineContent,
  Time: TimelineTime,
  Title: TimelineTitle,
  Body: TimelineBody,
});

結果

変化はないので、前と同じ。

はい、できました。