mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-09 00:19:13 +08:00
add UI in context
This commit is contained in:
parent
a2d07fbfbc
commit
82c5cde97e
@ -1,16 +1,34 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { type FC, type SyntheticEvent, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { AddonPanel, Badge, Link as LinkComponent, Spaced } from 'storybook/internal/components';
|
||||
import {
|
||||
AddonPanel,
|
||||
Badge,
|
||||
Button,
|
||||
Link as LinkComponent,
|
||||
type ListItem,
|
||||
Spaced,
|
||||
} from 'storybook/internal/components';
|
||||
import { TESTING_MODULE_RUN_ALL_REQUEST } from 'storybook/internal/core-events';
|
||||
import type { Combo } from 'storybook/internal/manager-api';
|
||||
import { Consumer, addons, types, useAddonState } from 'storybook/internal/manager-api';
|
||||
import {
|
||||
Consumer,
|
||||
addons,
|
||||
types,
|
||||
useAddonState,
|
||||
useStorybookApi,
|
||||
} from 'storybook/internal/manager-api';
|
||||
import {
|
||||
type API_HashEntry,
|
||||
type API_StatusObject,
|
||||
type API_StatusValue,
|
||||
type Addon_TestProviderState,
|
||||
type Addon_TestProviderType,
|
||||
Addon_TypesEnum,
|
||||
} from 'storybook/internal/types';
|
||||
|
||||
import { PlayIcon } from '@storybook/icons';
|
||||
import { useTheme } from '@storybook/theming';
|
||||
|
||||
import { Panel } from './Panel';
|
||||
import { GlobalErrorModal } from './components/GlobalErrorModal';
|
||||
import { ADDON_ID, PANEL_ID, TEST_PROVIDER_ID } from './constants';
|
||||
@ -79,18 +97,38 @@ const RelativeTime = ({ timestamp, testCount }: { timestamp: Date; testCount: nu
|
||||
);
|
||||
};
|
||||
|
||||
const COunter = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
const ContextMenuItem: FC<{
|
||||
context: API_HashEntry;
|
||||
state: Addon_TestProviderState<{
|
||||
testResults: TestResult[];
|
||||
}>;
|
||||
ListItem: typeof ListItem;
|
||||
}> = ({ context, state, ListItem }) => {
|
||||
const api = useStorybookApi();
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setCount((prev) => prev + 1);
|
||||
}, 1000);
|
||||
const onClick = useCallback(
|
||||
(event: SyntheticEvent) => {
|
||||
event.stopPropagation();
|
||||
// TODO - actually send along a sub-set based on `context` to test.
|
||||
api.getChannel().emit(TESTING_MODULE_RUN_ALL_REQUEST, { providerId: TEST_PROVIDER_ID });
|
||||
},
|
||||
[api]
|
||||
);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
const theme = useTheme();
|
||||
|
||||
return <div>{count}</div>;
|
||||
return (
|
||||
<ListItem
|
||||
title={'Component tests'}
|
||||
right={
|
||||
<Button variant="ghost" padding="small" disabled={state.crashed || state.running}>
|
||||
<PlayIcon fill={theme.barTextColor} />
|
||||
</Button>
|
||||
}
|
||||
center={state.running ? 'Running...' : 'Run tests'}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
addons.register(ADDON_ID, (api) => {
|
||||
@ -107,17 +145,12 @@ addons.register(ADDON_ID, (api) => {
|
||||
watchable: true,
|
||||
|
||||
name: 'Component tests',
|
||||
contextMenu: ({ context, state }) => {
|
||||
contextMenu: ({ context, state }, { ListItem }) => {
|
||||
if (context.type === 'docs') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
Testing {state?.progress?.percentageCompleted} {state.running ? '!' : '?'}
|
||||
</div>
|
||||
);
|
||||
// return <COunter />;
|
||||
return <ContextMenuItem context={context} state={state} ListItem={ListItem} />;
|
||||
},
|
||||
title: ({ crashed, failed }) =>
|
||||
crashed || failed ? 'Component tests failed' : 'Component tests',
|
||||
@ -207,20 +240,20 @@ addons.register(ADDON_ID, (api) => {
|
||||
}>);
|
||||
}
|
||||
|
||||
const filter = ({ state }: Combo) => {
|
||||
return {
|
||||
storyId: state.storyId,
|
||||
};
|
||||
};
|
||||
|
||||
addons.add(PANEL_ID, {
|
||||
type: types.PANEL,
|
||||
title: Title,
|
||||
match: ({ viewMode }) => viewMode === 'story',
|
||||
render: ({ active }) => {
|
||||
const newLocal = useCallback(({ state }: Combo) => {
|
||||
return {
|
||||
storyId: state.storyId,
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AddonPanel active={active}>
|
||||
<Consumer filter={newLocal}>{({ storyId }) => <Panel storyId={storyId} />}</Consumer>
|
||||
<Consumer filter={filter}>{({ storyId }) => <Panel storyId={storyId} />}</Consumer>
|
||||
</AddonPanel>
|
||||
);
|
||||
},
|
||||
|
@ -15,7 +15,8 @@ const List = styled.div(
|
||||
},
|
||||
({ theme }) => ({
|
||||
borderRadius: theme.appBorderRadius + 2,
|
||||
})
|
||||
}),
|
||||
({ theme }) => (theme.base === 'dark' ? { background: theme.background.content } : {})
|
||||
);
|
||||
|
||||
const Group = styled.div(({ theme }) => ({
|
||||
|
@ -1,7 +1,13 @@
|
||||
import type { ComponentProps, FC, MutableRefObject } from 'react';
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { Button, IconButton, TooltipLinkList, WithTooltip } from '@storybook/core/components';
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
ListItem,
|
||||
TooltipLinkList,
|
||||
WithTooltip,
|
||||
} from '@storybook/core/components';
|
||||
import { styled, useTheme } from '@storybook/core/theming';
|
||||
import {
|
||||
type API_HashEntry,
|
||||
@ -176,6 +182,10 @@ const StatusIconMap = {
|
||||
unknown: null,
|
||||
};
|
||||
|
||||
const ContextMenu = {
|
||||
ListItem,
|
||||
};
|
||||
|
||||
const statusOrder: API_StatusValue[] = ['success', 'error', 'warn', 'pending', 'unknown'];
|
||||
|
||||
const Node = React.memo<NodeProps>(function Node({
|
||||
@ -746,7 +756,7 @@ function generateTestProviderLinks(testProviders: TestProviders, context: API_Ha
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = e.contextMenu?.({ context, state });
|
||||
const content = e.contextMenu?.({ context, state }, ContextMenu);
|
||||
|
||||
if (!content) {
|
||||
return null;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import type { FC, PropsWithChildren, ReactElement, ReactNode } from 'react';
|
||||
|
||||
import type { ListItem } from '../../components';
|
||||
import type { TestingModuleProgressReportProgress } from '../../core-events';
|
||||
import type { Addon, StoryEntry } from '../../manager-api';
|
||||
import type { RenderData as RouterData } from '../../router/types';
|
||||
@ -476,10 +477,13 @@ export interface Addon_TestProviderType<
|
||||
name: string;
|
||||
title: (state: Addon_TestProviderState<Details>) => ReactNode;
|
||||
description: (state: Addon_TestProviderState<Details>) => ReactNode;
|
||||
contextMenu?: (options: {
|
||||
context: API_HashEntry;
|
||||
state: Addon_TestProviderState<Details>;
|
||||
}) => ReactNode;
|
||||
contextMenu?: (
|
||||
options: {
|
||||
context: API_HashEntry;
|
||||
state: Addon_TestProviderState<Details>;
|
||||
},
|
||||
components: { ListItem: typeof ListItem }
|
||||
) => ReactNode;
|
||||
mapStatusUpdate?: (
|
||||
state: Addon_TestProviderState<Details>
|
||||
) => API_StatusUpdate | ((state: API_StatusState) => API_StatusUpdate);
|
||||
|
Loading…
x
Reference in New Issue
Block a user