[React+Tailwind] Sidebar を TypeScript に書き直してみた | 心を無にして始める React
準備
書き直すベースはこちらの Sidebar コンポーネントです。
JavaScript
ベースの Sidebar.js です。
import React, { forwardRef } from 'react';
import {
Sidebar as FlowbiteSidebar,
} from 'flowbite-react';
const Sidebar = forwardRef((
{
children,
collapseBehavior,
collapsed,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar
collapseBehavior={collapseBehavior}
collapsed={collapsed}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar>
);
});
const SidebarCollapse = forwardRef((
{
active = false,
as,
children,
href,
icon,
label,
labelColor,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.Collapse
active={active}
as={as}
href={href}
icon={icon}
label={label}
labelColor={labelColor}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Collapse>
);
});
const SidebarCTA = forwardRef((
{
children,
color,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.CTA
color={color}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.CTA>
);
});
const SidebarItems = forwardRef((
{
children,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.Items
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Items>
);
});
const SidebarItemGroup = forwardRef((
{
children,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.ItemGroup
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.ItemGroup>
);
});
const SidebarItem = forwardRef((
{
active = false,
as,
children,
href,
icon,
label,
labelColor,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.Item
active={active}
as={as}
href={href}
icon={icon}
label={label}
labelColor={labelColor}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Item>
);
});
const SidebarLogo = forwardRef((
{
children,
className,
href,
img,
imgAlt,
...otherProps
},
ref,
) => {
return (
<FlowbiteSidebar.Logo
className={className}
href={href}
img={img}
imgAlt={imgAlt}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Logo>
);
});
export default Object.assign(Sidebar, {
Collapse: SidebarCollapse,
CTA: SidebarCTA,
Item: SidebarItem,
ItemGroup: SidebarItemGroup,
Items: SidebarItems,
Logo: SidebarLogo,
});
TypeScript
Sidebar.tsx として編集します。
import React, { ComponentProps, forwardRef } from 'react';
import {
Sidebar as FlowbiteSidebar,
SidebarProps as FlowbiteSidebarProps,
} from 'flowbite-react';
import { LegacyRef } from 'react';
type SidebarProps = {} & FlowbiteSidebarProps;
const Sidebar = forwardRef((
{
children,
collapseBehavior,
collapsed,
...otherProps
}: SidebarProps,
ref: LegacyRef<HTMLDivElement>,
) => {
return (
<FlowbiteSidebar
collapseBehavior={collapseBehavior}
collapsed={collapsed}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar>
);
});
type SidebarCollapseProps = {} & ComponentProps<typeof FlowbiteSidebar.Collapse>;
const SidebarCollapse = forwardRef((
{
active = false,
as,
children,
href,
icon,
label,
labelColor,
...otherProps
}: SidebarCollapseProps,
ref: LegacyRef<HTMLDivElement & HTMLButtonElement>,
) => {
return (
<FlowbiteSidebar.Collapse
active={active}
as={as}
href={href}
icon={icon}
label={label}
labelColor={labelColor}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Collapse>
);
});
type SidebarCTAProps = {} & ComponentProps<typeof FlowbiteSidebar.CTA>;
const SidebarCTA = forwardRef((
{
children,
color,
...otherProps
}: SidebarCTAProps,
ref: LegacyRef<HTMLDivElement>,
) => {
return (
<FlowbiteSidebar.CTA
color={color}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.CTA>
);
});
type SidebarItemsProps = {} & ComponentProps<typeof FlowbiteSidebar.Items>;
const SidebarItems = forwardRef((
{
children,
...otherProps
}: SidebarItemsProps,
ref: LegacyRef<HTMLDivElement>,
) => {
return (
<FlowbiteSidebar.Items
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Items>
);
});
type SidebarItemGroupProps = {} & ComponentProps<typeof FlowbiteSidebar.ItemGroup>;
const SidebarItemGroup = forwardRef((
{
children,
...otherProps
}: SidebarItemGroupProps,
ref: LegacyRef<HTMLUListElement>,
) => {
return (
<FlowbiteSidebar.ItemGroup
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.ItemGroup>
);
});
type SidebarItemProps = {} & ComponentProps<typeof FlowbiteSidebar.Item>;
const SidebarItem = forwardRef((
{
active = false,
as,
children,
href,
icon,
label,
labelColor,
...otherProps
}: SidebarItemProps,
ref: LegacyRef<HTMLDivElement>,
) => {
return (
<FlowbiteSidebar.Item
active={active}
as={as}
href={href}
icon={icon}
label={label}
labelColor={labelColor}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Item>
);
});
type SidebarLogoProps = {} & ComponentProps<typeof FlowbiteSidebar.Logo>;
const SidebarLogo = forwardRef((
{
children,
className,
href,
img,
imgAlt,
...otherProps
}: SidebarLogoProps,
ref: LegacyRef<HTMLAnchorElement>,
) => {
return (
<FlowbiteSidebar.Logo
className={className}
href={href}
img={img}
imgAlt={imgAlt}
ref={ref}
{...otherProps}
>
{children}
</FlowbiteSidebar.Logo>
);
});
export default Object.assign(Sidebar, {
Collapse: SidebarCollapse,
CTA: SidebarCTA,
Item: SidebarItem,
ItemGroup: SidebarItemGroup,
Items: SidebarItems,
Logo: SidebarLogo,
});
結果
変化はないので、前と同じ。
はい、できました。