Skip to content

Commit

Permalink
Merge pull request #25588 from storybookjs/shaun/component-types
Browse files Browse the repository at this point in the history
UI: Remove use of React.FC in components
  • Loading branch information
JReinhold authored Jan 25, 2024
2 parents 1010f2f + c3c503a commit ca8da84
Show file tree
Hide file tree
Showing 23 changed files with 97 additions and 90 deletions.
4 changes: 2 additions & 2 deletions code/ui/components/src/components/ActionBar/ActionBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC, MouseEvent, ReactElement } from 'react';
import type { MouseEvent, ReactElement } from 'react';
import React from 'react';

import { styled } from '@storybook/theming';
Expand Down Expand Up @@ -66,7 +66,7 @@ export interface ActionBarProps {
actionItems: ActionItem[];
}

export const ActionBar: FC<ActionBarProps> = ({ actionItems, ...props }) => (
export const ActionBar = ({ actionItems, ...props }: ActionBarProps) => (
<Container {...props}>
{actionItems.map(({ title, className, onClick, disabled }, index: number) => (
<ActionButton key={index} className={className} onClick={onClick} disabled={disabled}>
Expand Down
6 changes: 3 additions & 3 deletions code/ui/components/src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { FC, PropsWithChildren } from 'react';
import React from 'react';
import { styled } from '@storybook/theming';
import { transparentize } from 'polished';
Expand Down Expand Up @@ -80,10 +79,11 @@ const BadgeWrapper = styled.div<BadgeProps>(
}
);

export interface BadgeProps extends PropsWithChildren {
export interface BadgeProps {
status: 'positive' | 'negative' | 'neutral' | 'warning' | 'critical';
children?: React.ReactNode;
}

export const Badge: FC<BadgeProps> = ({ ...props }) => {
export const Badge = ({ ...props }: BadgeProps) => {
return <BadgeWrapper {...props} />;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { global } from '@storybook/global';
import type { FC } from 'react';

import React, { Fragment } from 'react';
import { styled } from '@storybook/theming';

Expand All @@ -20,7 +20,12 @@ const firstLineRegex = /(Error): (.*)\n/;
const linesRegexChromium = /at (?:(.*) )?\(?(.+)\)?/;
const linesRegexFirefox = /([^@]+)?(?:\/<)?@(.+)?/;
const linesRegexSafari = /([^@]+)?@(.+)?/;
export const ErrorFormatter: FC<{ error: Error }> = ({ error }) => {

export interface ErrorFormatterProps {
error: Error;
}

export const ErrorFormatter = ({ error }: ErrorFormatterProps) => {
if (!error) {
return <Fragment>This error has no stack or message</Fragment>;
}
Expand Down
10 changes: 2 additions & 8 deletions code/ui/components/src/components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { transparentize } from 'polished';
import type { ComponentProps, FC } from 'react';
import React from 'react';
import { styled, keyframes } from '@storybook/theming';
import { Icons } from '../icon/icon';
Expand Down Expand Up @@ -98,18 +97,13 @@ interface Progress {
};
}

interface LoaderProps {
interface LoaderProps extends React.HTMLAttributes<HTMLDivElement> {
progress?: Progress;
error?: Error;
size?: number;
}

export const Loader: FC<LoaderProps & ComponentProps<typeof ProgressWrapper>> = ({
progress,
error,
size,
...props
}) => {
export const Loader = ({ progress, error, size, ...props }: LoaderProps) => {
if (error) {
return (
<ProgressWrapper aria-label={error.toString()} aria-live="polite" role="status" {...props}>
Expand Down
5 changes: 2 additions & 3 deletions code/ui/components/src/components/ScrollArea/ScrollArea.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { FC } from 'react';
import React from 'react';
import { styled } from '@storybook/theming';
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
Expand Down Expand Up @@ -76,14 +75,14 @@ const ScrollAreaThumb = styled(ScrollAreaPrimitive.Thumb)(({ theme }) => ({
},
}));

export const ScrollArea: FC<ScrollAreaProps> = ({
export const ScrollArea = ({
children,
horizontal = false,
vertical = false,
offset = 2,
scrollbarSize = 6,
className,
}) => (
}: ScrollAreaProps) => (
<ScrollAreaRoot scrollbarsize={scrollbarSize} offset={offset} className={className}>
<ScrollAreaViewport>{children}</ScrollAreaViewport>
{horizontal && (
Expand Down
26 changes: 17 additions & 9 deletions code/ui/components/src/components/bar/bar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { ComponentProps, FC } from 'react';
import type { ComponentProps } from 'react';
import React, { Children } from 'react';
import { styled } from '@storybook/theming';

import type { ScrollAreaProps } from '../ScrollArea/ScrollArea';
import { ScrollArea } from '../ScrollArea/ScrollArea';

export interface SideProps {
Expand Down Expand Up @@ -39,19 +40,23 @@ export const Side = styled.div<SideProps>(
);
Side.displayName = 'Side';

const UnstyledBar: FC<ComponentProps<typeof ScrollArea> & { scrollable?: boolean }> = ({
children,
className,
scrollable,
}) =>
interface UnstyledBarProps extends ScrollAreaProps {
scrollable?: boolean;
}

const UnstyledBar = ({ children, className, scrollable }: UnstyledBarProps) =>
scrollable ? (
<ScrollArea vertical={false} className={className}>
{children}
</ScrollArea>
) : (
<div className={className}>{children}</div>
);
export const Bar = styled(UnstyledBar)<{ border?: boolean; scrollable?: boolean }>(

export interface BarProps extends UnstyledBarProps {
border?: boolean;
}
export const Bar = styled(UnstyledBar)<BarProps>(
({ theme, scrollable = true }) => ({
color: theme.barTextColor,
width: '100%',
Expand All @@ -70,7 +75,10 @@ export const Bar = styled(UnstyledBar)<{ border?: boolean; scrollable?: boolean
);
Bar.displayName = 'Bar';

const BarInner = styled.div<{ bgColor: string }>(({ bgColor }) => ({
interface BarInnerProps {
bgColor?: string;
}
const BarInner = styled.div<BarInnerProps>(({ bgColor }) => ({
display: 'flex',
justifyContent: 'space-between',
position: 'relative',
Expand All @@ -85,7 +93,7 @@ export interface FlexBarProps extends ComponentProps<typeof Bar> {
backgroundColor?: string;
}

export const FlexBar: FC<FlexBarProps> = ({ children, backgroundColor, ...rest }) => {
export const FlexBar = ({ children, backgroundColor, ...rest }: FlexBarProps) => {
const [left, right] = Children.toArray(children);
return (
<Bar {...rest}>
Expand Down
3 changes: 1 addition & 2 deletions code/ui/components/src/components/bar/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
DetailedHTMLProps,
FC,
ForwardedRef,
ForwardRefExoticComponent,
ReactElement,
Expand Down Expand Up @@ -147,7 +146,7 @@ const IconButtonSkeletonWrapper = styled.div(() => ({
* @deprecated
* This component will be removed in Storybook 9.0
* */
export const IconButtonSkeleton: FC = () => (
export const IconButtonSkeleton = () => (
<IconButtonSkeletonWrapper>
<IconPlaceholder />
</IconButtonSkeletonWrapper>
Expand Down
7 changes: 4 additions & 3 deletions code/ui/components/src/components/bar/separator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import React, { Fragment } from 'react';
import { styled } from '@storybook/theming';

export interface SeparatorProps {
force?: boolean;
}

export const Separator = styled.span<SeparatorProps>(
({ theme }) => ({
width: 1,
Expand Down Expand Up @@ -35,6 +39,3 @@ export const interleaveSeparators = (list: any[]) =>
),
null
);
export interface SeparatorProps {
force?: boolean;
}
3 changes: 1 addition & 2 deletions code/ui/components/src/components/brand/StorybookIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { FC } from 'react';
import React from 'react';

export const StorybookIcon: FC = ({ ...props }) => (
export const StorybookIcon = (props: React.SVGAttributes<SVGElement>) => (
<svg viewBox="0 0 64 64" {...props}>
<title>Storybook icon</title>
<g id="Artboard" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
Expand Down
7 changes: 4 additions & 3 deletions code/ui/components/src/components/brand/StorybookLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { FC } from 'react';
import React from 'react';

export const StorybookLogo: FC<{
type StorybookLogoProps = {
alt: string;
}> = ({ alt, ...props }) => (
} & React.SVGAttributes<SVGSVGElement>;

export const StorybookLogo = ({ alt, ...props }: StorybookLogoProps) => (
<svg width="200px" height="40px" viewBox="0 0 200 40" {...props} role="img">
{alt ? <title>{alt}</title> : null}
<defs>
Expand Down
4 changes: 2 additions & 2 deletions code/ui/components/src/components/form/field/field.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC, ReactNode } from 'react';
import type { ReactNode } from 'react';
import React from 'react';
import { styled } from '@storybook/theming';

Expand Down Expand Up @@ -28,7 +28,7 @@ export interface FieldProps {
label?: ReactNode;
}

export const Field: FC<FieldProps> = ({ label, children, ...props }) => (
export const Field = ({ label, children, ...props }: FieldProps) => (
<Wrapper {...props}>
{label ? (
<Label>
Expand Down
4 changes: 2 additions & 2 deletions code/ui/components/src/components/form/input/input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC, HTMLProps, SelectHTMLAttributes } from 'react';
import type { HTMLProps, SelectHTMLAttributes } from 'react';
import React, { forwardRef } from 'react';
import type { CSSObject, FunctionInterpolation } from '@storybook/theming';
import { styled } from '@storybook/theming';
Expand Down Expand Up @@ -207,7 +207,7 @@ type TextareaProps = Omit<
valid?: ValidationStates;
height?: number;
} & React.RefAttributes<HTMLTextAreaElement>;
export const Textarea: FC<TextareaProps> = Object.assign(
export const Textarea = Object.assign(
styled(
forwardRef<any, TextareaProps>(function Textarea({ size, valid, align, ...props }, ref) {
return <TextareaAutoResize {...props} ref={ref} />;
Expand Down
11 changes: 7 additions & 4 deletions code/ui/components/src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { ComponentProps, FC } from 'react';
import type { ComponentProps } from 'react';
import React, { memo } from 'react';

import * as StorybookIcons from '@storybook/icons';
import { styled } from '@storybook/theming';
import { deprecate, logger } from '@storybook/client-logger';

export type IconType = keyof typeof icons;
type NewIconTypes = (typeof icons)[IconType];

const NEW_ICON_MAP = StorybookIcons as Record<NewIconTypes, (props: unknown) => React.ReactNode>;

const Svg = styled.svg`
display: inline-block;
shape-rendering: inherit;
Expand All @@ -27,7 +30,7 @@ export interface IconsProps extends ComponentProps<typeof Svg> {
* @deprecated No longer used, will be removed in Storybook 9.0
* Please use the `@storybook/icons` package instead.
* */
export const Icons: FC<IconsProps> = ({ icon, useSymbol, ...props }: IconsProps) => {
export const Icons = ({ icon, useSymbol, ...props }: IconsProps) => {
deprecate(
`Use of the deprecated Icons ${
`(${icon})` || ''
Expand All @@ -42,8 +45,8 @@ export const Icons: FC<IconsProps> = ({ icon, useSymbol, ...props }: IconsProps)
);
return null;
}
// TODO: Find a better way to type this component
const Icon: FC = (StorybookIcons as any)[findIcon];

const Icon = NEW_ICON_MAP[findIcon];

return <Icon {...props} />;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { FunctionComponent } from 'react';
import React, { Children } from 'react';
import { styled } from '@storybook/theming';

Expand All @@ -19,7 +18,7 @@ export interface PlaceholderProps {
children?: React.ReactNode;
}

export const Placeholder: FunctionComponent<PlaceholderProps> = ({ children, ...props }) => {
export const Placeholder = ({ children, ...props }: PlaceholderProps) => {
const [title, desc] = Children.toArray(children);
return (
<Message {...props}>
Expand Down
3 changes: 1 addition & 2 deletions code/ui/components/src/components/spaced/Spaced.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { FC } from 'react';
import React from 'react';
import { styled, ignoreSsrWarning } from '@storybook/theming';

Expand Down Expand Up @@ -60,7 +59,7 @@ export interface SpacedProps {
outer?: number | boolean;
}

export const Spaced: FC<SpacedProps> = ({ col, row, outer, children, ...rest }) => {
export const Spaced = ({ col, row, outer, children, ...rest }: SpacedProps) => {
const outerAmount = toNumber(typeof outer === 'number' || !outer ? outer : col || row);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ComponentProps, FC, MouseEvent } from 'react';
import type { MouseEvent } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { logger } from '@storybook/client-logger';
import { styled } from '@storybook/theming';
Expand All @@ -23,6 +23,7 @@ import ReactSyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-ligh
import { createElement } from 'react-syntax-highlighter/dist/esm/index';

import { ActionBar } from '../ActionBar/ActionBar';
import type { ScrollAreaProps } from '../ScrollArea/ScrollArea';
import { ScrollArea } from '../ScrollArea/ScrollArea';

import type {
Expand Down Expand Up @@ -106,7 +107,7 @@ const Wrapper = styled.div<WrapperProps>(
: {}
);

const UnstyledScroller: FC<ComponentProps<typeof ScrollArea>> = ({ children, className }) => (
const UnstyledScroller = ({ children, className }: ScrollAreaProps) => (
<ScrollArea horizontal vertical className={className}>
{children}
</ScrollArea>
Expand Down
8 changes: 4 additions & 4 deletions code/ui/components/src/components/tooltip/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC, ReactNode, ComponentProps } from 'react';
import type { ReactNode, ComponentProps } from 'react';
import React from 'react';
import { styled } from '@storybook/theming';
import memoize from 'memoizerific';
Expand Down Expand Up @@ -170,7 +170,7 @@ const getItemProps = memoize(100)((onClick, href, LinkWrapper) => {
return result;
});

export type LinkWrapperType = FC<any>;
export type LinkWrapperType = (props: any) => ReactNode;

export interface ListItemProps extends Omit<ComponentProps<typeof Item>, 'href' | 'title'> {
loading?: boolean;
Expand All @@ -185,7 +185,7 @@ export interface ListItemProps extends Omit<ComponentProps<typeof Item>, 'href'
isIndented?: boolean;
}

const ListItem: FC<ListItemProps> = ({
const ListItem = ({
loading,
title,
center,
Expand All @@ -198,7 +198,7 @@ const ListItem: FC<ListItemProps> = ({
onClick,
LinkWrapper,
...rest
}) => {
}: ListItemProps) => {
const itemProps = getItemProps(onClick, href, LinkWrapper);
const commonProps = { active, disabled };

Expand Down
Loading

0 comments on commit ca8da84

Please sign in to comment.