Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addon-docs: Improved loading state #16709

Merged
merged 14 commits into from
Nov 22, 2021
Merged
2 changes: 1 addition & 1 deletion addons/docs/src/blocks/ArgsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export const StoryTable: FC<
const story = useStory(storyId, context);
// eslint-disable-next-line prefer-const
let [args, updateArgs, resetArgs] = useArgs(storyId, context);
if (!story) return <PureArgsTable isLoading />;
if (!story) return <PureArgsTable isLoading updateArgs={updateArgs} resetArgs={resetArgs} />;

const argTypes = filterArgTypes(story.argTypes, include, exclude);

Expand Down
3 changes: 1 addition & 2 deletions lib/cli/src/automigrate/fixes/eslint-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ export const eslintPlugin: Fix<EslintPluginRunOptions> = {
if (!dryRun) {
logger.info(`✅ Adding Storybook to extends list`);
const extendsConfig = eslint.getFieldValue(['extends']) || [];
const existingConfigValue =
Array.isArray(extendsConfig) ? extendsConfig : [extendsConfig];
const existingConfigValue = Array.isArray(extendsConfig) ? extendsConfig : [extendsConfig];
eslint.setFieldValue(['extends'], [...existingConfigValue, 'plugin:storybook/recommended']);

await writeConfig(eslint);
Expand Down
4 changes: 3 additions & 1 deletion lib/components/src/bar/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ const IconPlaceholder = styled.div(({ theme }) => ({
}));

const IconButtonSkeletonWrapper = styled.div(() => ({
padding: 5,
marginTop: 6,
padding: 7,
height: 28,
}));

export const IconButtonSkeleton = () => (
Expand Down
2 changes: 0 additions & 2 deletions lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ const Template = (args) => <ArgRow {...args} />;
const baseArgs = {
updateArgs: action('updateArgs'),
};
export const Loading = Template.bind({});
Loading.args = { isLoading: true };

export const String = Template.bind({});
String.args = {
Expand Down
17 changes: 2 additions & 15 deletions lib/components/src/blocks/ArgsTable/ArgRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ArgValue } from './ArgValue';
import { ArgControl, ArgControlProps } from './ArgControl';
import { codeCommon } from '../../typography/shared';

interface ArgRowData {
interface ArgRowProps {
row: ArgType;
arg: any;
updateArgs?: (args: Args) => void;
Expand All @@ -17,17 +17,6 @@ interface ArgRowData {
initialExpandedArgs?: boolean;
}

interface ArgRowLoading {
isLoading: true;
}

export const argRowLoadingData: ArgRowData = {
row: { name: 'loading', description: 'loading' },
arg: 0,
};

export type ArgRowProps = ArgRowData | ArgRowLoading;

const Name = styled.span({ fontWeight: 'bold' });

const Required = styled.span(({ theme }) => ({
Expand Down Expand Up @@ -84,9 +73,7 @@ const StyledTd = styled.td<{ expandable: boolean }>(({ theme, expandable }) => (
}));

export const ArgRow: FC<ArgRowProps> = (props) => {
// const isLoading = 'isLoading' in props;
const { row, updateArgs, compact, expandable, initialExpandedArgs } =
'row' in props ? props : argRowLoadingData;
const { row, updateArgs, compact, expandable, initialExpandedArgs } = props;
const { name, description } = row;
const table = (row.table || {}) as TableAnnotation;
const type = table.type || row.type;
Expand Down
1 change: 1 addition & 0 deletions lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const Template = (args) => <ArgsTable {...args} />;

export const Loading = Template.bind({});
Loading.args = { isLoading: true };

export const Normal = Template.bind({});
Normal.args = {
rows: {
Expand Down
220 changes: 68 additions & 152 deletions lib/components/src/blocks/ArgsTable/ArgsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ import pickBy from 'lodash/pickBy';
import { styled, ignoreSsrWarning } from '@storybook/theming';
import { opacify, transparentize, darken, lighten } from 'polished';
import { Icons } from '../../icon/icon';
import { ArgRow, argRowLoadingData } from './ArgRow';
import { ArgRow } from './ArgRow';
import { SectionRow } from './SectionRow';
import { ArgType, ArgTypes, Args } from './types';
import { EmptyBlock } from '../EmptyBlock';
import { Link } from '../../typography/link/link';
import { ResetWrapper } from '../../typography/DocumentFormatting';

export const TableWrapper = styled.table<{ compact?: boolean; inAddonPanel?: boolean }>(
export const TableWrapper = styled.table<{
compact?: boolean;
inAddonPanel?: boolean;
isLoading?: boolean;
}>(
({ theme, compact, inAddonPanel }) => ({
'&&': {
// Resets for cascading/system styles
Expand Down Expand Up @@ -183,7 +187,20 @@ export const TableWrapper = styled.table<{ compact?: boolean; inAddonPanel?: boo
},
// End finicky table styling
},
})
}),
({ isLoading, theme }) =>
isLoading
? {
'th span, td span, td button': {
display: 'inline',
backgroundColor: theme.appBorderColor,
animation: `${theme.animation.glow} 1.5s ease-in-out infinite`,
color: 'transparent',
boxShadow: 'none',
borderRadius: 0,
},
}
: {}
);

const ResetButton = styled.button(({ theme }) => ({
Expand Down Expand Up @@ -240,9 +257,8 @@ const sortFns: Record<SortType, SortFn | null> = {
Number(!!b.type?.required) - Number(!!a.type?.required) || a.name.localeCompare(b.name),
none: undefined,
};
export interface ArgsTableData {
rows: ArgTypes;
args?: Args;

export interface ArgsTableOptionProps {
updateArgs?: (args: Args) => void;
resetArgs?: (argNames?: string[]) => void;
compact?: boolean;
Expand All @@ -251,23 +267,39 @@ export interface ArgsTableData {
isLoading?: boolean;
sort?: SortType;
}
export interface ArgsTableDataProps {
rows: ArgTypes;
args?: Args;
}

export interface ArgsTableErrorProps {
error: ArgsTableError;
}
interface ArgTableLoading {
export interface ArgsTableLoadingProps {
isLoading: true;
}

export const argTableLoadingData: ArgsTableData = {
const rowLoadingData = (key: string) => ({
key,
name: 'propertyName',
description: 'This is a short description',
control: { type: 'text' },
table: {
type: { summary: 'summary' },
defaultValue: { summary: 'defaultValue' },
},
});

export const argsTableLoadingData: ArgsTableDataProps = {
rows: {
row1: argRowLoadingData.row,
row2: argRowLoadingData.row,
row3: argRowLoadingData.row,
row1: rowLoadingData('row1'),
row2: rowLoadingData('row2'),
row3: rowLoadingData('row3'),
},
};

export type ArgsTableProps = ArgsTableData | ArgsTableErrorProps | ArgTableLoading;
export type ArgsTableProps = ArgsTableOptionProps &
(ArgsTableDataProps | ArgsTableErrorProps | ArgsTableLoadingProps);

type Rows = ArgType[];
type Subsection = Rows;
Expand Down Expand Up @@ -338,130 +370,6 @@ const groupRows = (rows: ArgType, sort: SortType) => {
return sorted;
};

const SkeletonHeader = styled.div(({ theme }) => ({
alignContent: 'stretch',
display: 'flex',
gap: 16,
marginTop: 25,
padding: '10px 20px',

div: {
animation: `${theme.animation.glow} 1.5s ease-in-out infinite`,
background: theme.appBorderColor,
flexShrink: 0,
height: 20,

'&:first-child, &:nth-child(4)': {
width: '20%',
},

'&:nth-child(2)': {
width: '30%',
},

'&:nth-child(3)': {
flexGrow: 1,
},

'&:last-child': {
width: 30,
},

'@media ( max-width: 500px )': {
'&:nth-child( n + 4 )': {
display: 'none',
},
},
},
}));

const SkeletonBody = styled.div(({ theme }) => ({
background: theme.background.content,
boxShadow:
theme.base === 'light'
? `rgba(0, 0, 0, 0.10) 0 1px 3px 1px,
${transparentize(0.035, theme.appBorderColor)} 0 0 0 1px`
: `rgba(0, 0, 0, 0.20) 0 2px 5px 1px,
${opacify(0.05, theme.appBorderColor)} 0 0 0 1px`,
borderRadius: theme.appBorderRadius,

'> div': {
alignContent: 'stretch',
borderTopColor:
theme.base === 'light'
? darken(0.1, theme.background.content)
: lighten(0.05, theme.background.content),
borderTopStyle: 'solid',
borderTopWidth: 1,
display: 'flex',
gap: 16,
padding: 20,

'&:first-child': {
borderTop: 0,
},
},

'> div div': {
animation: `${theme.animation.glow} 1.5s ease-in-out infinite`,
background: theme.appBorderColor,
flexShrink: 0,
height: 20,

'&:first-child': {
width: '20%',
},

'&:nth-child(2)': {
width: '30%',
},

'&:nth-child(3)': {
flexGrow: 1,
},

'&:last-child': {
width: 'calc(20% + 47px)',

'@media ( max-width: 500px )': {
display: 'none',
},
},
},
}));

const Skeleton = () => (
<div>
<SkeletonHeader>
<div />
<div />
<div />
<div />
<div />
</SkeletonHeader>
<SkeletonBody>
<div>
<div />
<div />
<div />
<div />
</div>
<div>
<div />
<div />
<div />
<div />
</div>
<div>
<div />
<div />
<div />
<div />
</div>
</SkeletonBody>
</div>
);

/**
* Display the props for a component as a props table. Each row is a collection of
* ArgDefs, usually derived from docgen info for the component.
Expand All @@ -478,21 +386,16 @@ export const ArgsTable: FC<ArgsTableProps> = (props) => {
);
}

const isLoading = 'isLoading' in props;
const {
rows,
args,
updateArgs,
resetArgs,
compact,
inAddonPanel,
initialExpandedArgs,
sort = 'none',
} = 'rows' in props ? props : argTableLoadingData;

if (isLoading) {
return <Skeleton />;
}
} = props;
const isLoading = 'isLoading' in props;
const { rows, args } = 'rows' in props ? props : argsTableLoadingData;

const groups = groupRows(
pickBy(rows, (row) => !row?.table?.disable),
Expand Down Expand Up @@ -523,25 +426,38 @@ export const ArgsTable: FC<ArgsTableProps> = (props) => {

return (
<ResetWrapper>
<TableWrapper {...{ compact, inAddonPanel }} className="docblock-argstable">
<TableWrapper
aria-hidden={isLoading}
{...{ compact, inAddonPanel, isLoading }}
className="docblock-argstable"
>
<thead className="docblock-argstable-head">
<tr>
<th>Name</th>
{compact || <th>Description</th>}
{compact || <th>Default</th>}
{updateArgs && (
<th>
<span>Name</span>
</th>
{compact ? null : (
<th>
<span>Description</span>
</th>
)}
{compact ? null : (
<th>
<span>Default</span>
</th>
)}
{updateArgs ? (
<th>
<ControlHeadingWrapper>
Control{' '}
{resetArgs && (
{!isLoading && resetArgs && (
<ResetButton onClick={() => resetArgs()} title="Reset controls">
<Icons icon="undo" aria-hidden />
</ResetButton>
)}
</ControlHeadingWrapper>
</th>
)}
{null}
) : null}
</tr>
</thead>
<tbody className="docblock-argstable-body">
Expand Down
2 changes: 1 addition & 1 deletion lib/components/src/blocks/DocsPage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const Loading = () => (
</Subtitle>
<Description {...description.Text.args} />
<Preview.Loading />
<argsTable.Loading />
<argsTable.Loading {...argsTable.Loading.args} />
<Source {...source.Loading.args} />
</DocsPageWrapper>
);
Expand Down