Skip to content

Commit

Permalink
Merge branch 'next' into pr/18323
Browse files Browse the repository at this point in the history
  • Loading branch information
shilman committed Jun 29, 2022
2 parents 86bec96 + 008b542 commit ad02c64
Show file tree
Hide file tree
Showing 169 changed files with 2,632 additions and 1,009 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@ jobs:
- run:
name: run e2e tests cra
command: yarn test:e2e-framework --pnp cra
- run:
name: run e2e tests vue
command: yarn test:e2e-framework --pnp sfcVue
# - run:
# name: run e2e tests vue
# command: yarn test:e2e-framework --pnp sfcVue
- run:
name: prep artifacts
when: always
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ It allows you to browse a component library, view the different states of each c

<p align="center">
View README for:<br/>
<a href="https://github.com/storybookjs/storybook/blob/main/README.md" title="latest"><img alt="latest" src="https://img.shields.io/npm/v/@storybook/core/latest.svg" /></a>
<a href="https://github.com/storybookjs/storybook/blob/next/README.md" title="next"><img alt="next" src="https://img.shields.io/npm/v/@storybook/core/next.svg" /></a>
<a href="https://github.com/storybookjs/storybook/blob/main/README.md" title="latest"><img alt="latest" src="https://img.shields.io/npm/v/@storybook/core/latest?style=for-the-badge&logo=storybook&logoColor=ffffff&color=ff4785" /></a>
<a href="https://github.com/storybookjs/storybook/blob/next/README.md" title="next"><img alt="next" src="https://img.shields.io/npm/v/@storybook/core/next?style=for-the-badge&logo=storybook&logoColor=ffffff&color=purple" /></a>
</p>

## Table of contents
Expand Down Expand Up @@ -92,19 +92,19 @@ For additional help, join us in the [Storybook Discord](https://discord.gg/story

### Supported Frameworks

| Framework | Demo | |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [React](app/react) | [v6.4.x](https://storybookjs.netlify.com/official-storybook/?path=/story/*) | [![React](https://img.shields.io/npm/dm/@storybook/react.svg)](app/react) |
| [Vue](app/vue) | [v6.4.x](https://storybookjs.netlify.com/vue-kitchen-sink/) | [![Vue](https://img.shields.io/npm/dm/@storybook/vue.svg)](app/vue) |
| [Angular](app/angular) | [v6.4.x](https://storybookjs.netlify.com/angular-cli/) | [![Angular](https://img.shields.io/npm/dm/@storybook/angular.svg)](app/angular) |
| [Web components](app/web-components) | [v6.4.x](https://storybookjs.netlify.com/web-components-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/web-components.svg)](app/web-components) |
| [React Native](https://github.com/storybookjs/react-native) | - | [![React Native](https://img.shields.io/npm/dm/@storybook/react-native.svg)](https://github.com/storybookjs/react-native) |
| [HTML](app/html) | [v6.4.x](https://storybookjs.netlify.com/html-kitchen-sink/) | [![HTML](https://img.shields.io/npm/dm/@storybook/html.svg)](app/html) |
| [Ember](app/ember) | [v6.4.x](https://storybookjs.netlify.com/ember-cli/) | [![Ember](https://img.shields.io/npm/dm/@storybook/ember.svg)](app/ember) |
| [Svelte](app/svelte) | [v6.4.x](https://storybookjs.netlify.com/svelte-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/svelte.svg)](app/svelte) |
| [Preact](app/preact) | [v6.4.x](https://storybookjs.netlify.com/preact-kitchen-sink/) | [![Preact](https://img.shields.io/npm/dm/@storybook/preact.svg)](app/preact) |
| [Marionette.js](https://github.com/storybookjs/marionette) | - | [![Marionette.js](https://img.shields.io/npm/dm/@storybook/marionette.svg)](https://github.com/storybookjs/marionette) |
| [Android, iOS, Flutter](https://github.com/storybookjs/native) | [v6.4.x](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html) | [![Native](https://img.shields.io/npm/dm/@storybook/native.svg)](https://github.com/storybookjs/native) |
| Framework | Demo | |
| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| [React](app/react) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/react/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/official-storybook/?path=/story/*) | [![React](https://img.shields.io/npm/dm/@storybook/react?style=flat-square&color=eee)](app/react) |
| [Vue](app/vue) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/vue/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/vue-kitchen-sink/) | [![Vue](https://img.shields.io/npm/dm/@storybook/vue?style=flat-square&color=eee)](app/vue) |
| [Angular](app/angular) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/angular/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/angular-cli/) | [![Angular](https://img.shields.io/npm/dm/@storybook/angular?style=flat-square&color=eee)](app/angular) |
| [Web components](app/web-components) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/web-components/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/web-components-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/web-components?style=flat-square&color=eee)](app/web-components) |
| [React Native](https://github.com/storybookjs/react-native) | - | [![React Native](https://img.shields.io/npm/dm/@storybook/react-native?style=flat-square&color=eee)](https://github.com/storybookjs/react-native) |
| [HTML](app/html) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/html/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/html-kitchen-sink/) | [![HTML](https://img.shields.io/npm/dm/@storybook/html?style=flat-square&color=eee)](app/html) |
| [Ember](app/ember) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/ember/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/ember-cli/) | [![Ember](https://img.shields.io/npm/dm/@storybook/ember?style=flat-square&color=eee)](app/ember) |
| [Svelte](app/svelte) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/svelte/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/svelte-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/svelte?style=flat-square&color=eee)](app/svelte) |
| [Preact](app/preact) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/preact/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/preact-kitchen-sink/) | [![Preact](https://img.shields.io/npm/dm/@storybook/preact?style=flat-square&color=eee)](app/preact) |
| [Marionette.js](https://github.com/storybookjs/marionette) | - | [![Marionette.js](https://img.shields.io/npm/dm/@storybook/marionette?style=flat-square&color=eee)](https://github.com/storybookjs/marionette) |
| [Android, iOS, Flutter](https://github.com/storybookjs/native) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/native/latest?style=flat-square&color=blue&label)](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html) | [![Native](https://img.shields.io/npm/dm/@storybook/native?style=flat-square&color=eee)](https://github.com/storybookjs/native) |

### Sub Projects

Expand Down
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Supported Versions

| Version | Supported |
| ---------- | ------------------ |
| 6.3, 6.4 | :white_check_mark: |
| Version | Supported |
| --------------- | ------------------ |
| 6.3, 6.4, 6.5 | :white_check_mark: |

## Reporting a Vulnerability

Expand Down
4 changes: 2 additions & 2 deletions addons/a11y/src/components/VisionSimulator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Vision Simulator', () => {
await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument());
});

it('should display tooltip on click', async () => {
it.skip('should display tooltip on click', async () => {
// given
render(<ThemedVisionSimulator />);
await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument());
Expand All @@ -45,7 +45,7 @@ describe('Vision Simulator', () => {
);
});

it('should set filter', async () => {
it.skip('should set filter', async () => {
// given
render(<ThemedVisionSimulator />);
await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument());
Expand Down
2 changes: 1 addition & 1 deletion addons/interactions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
},
"devDependencies": {
"@storybook/jest": "^0.0.5",
"@storybook/testing-library": "^0.0.7",
"@storybook/testing-library": "0.0.14-next.0",
"formik": "^2.2.9"
},
"peerDependencies": {
Expand Down
17 changes: 10 additions & 7 deletions addons/interactions/src/Panel.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ComponentStoryObj, ComponentMeta } from '@storybook/react';
import { CallStates } from '@storybook/instrumenter';
import { styled } from '@storybook/theming';

import { getCall } from './mocks';
import { getCalls, getInteractions } from './mocks';
import { AddonPanelPure } from './Panel';
import SubnavStories from './components/Subnav/Subnav.stories';

Expand All @@ -20,6 +20,8 @@ const StyledWrapper = styled.div(({ theme }) => ({
overflow: 'auto',
}));

const interactions = getInteractions(CallStates.DONE);

export default {
title: 'Addons/Interactions/Panel',
component: AddonPanelPure,
Expand All @@ -34,10 +36,10 @@ export default {
layout: 'fullscreen',
},
args: {
calls: new Map(),
calls: new Map(getCalls(CallStates.DONE).map((call) => [call.id, call])),
controls: SubnavStories.args.controls,
controlStates: SubnavStories.args.controlStates,
interactions: [getCall(CallStates.DONE)],
interactions,
fileName: 'addon-interactions.stories.tsx',
hasException: false,
isPlaying: false,
Expand All @@ -52,14 +54,14 @@ type Story = ComponentStoryObj<typeof AddonPanelPure>;

export const Passing: Story = {
args: {
interactions: [getCall(CallStates.DONE)],
interactions: getInteractions(CallStates.DONE),
},
};

export const Paused: Story = {
args: {
isPlaying: true,
interactions: [getCall(CallStates.WAITING)],
interactions: getInteractions(CallStates.WAITING),
controlStates: {
debugger: true,
start: false,
Expand All @@ -68,20 +70,21 @@ export const Paused: Story = {
next: true,
end: true,
},
pausedAt: interactions[interactions.length - 1].id,
},
};

export const Playing: Story = {
args: {
isPlaying: true,
interactions: [getCall(CallStates.ACTIVE)],
interactions: getInteractions(CallStates.ACTIVE),
},
};

export const Failed: Story = {
args: {
hasException: true,
interactions: [getCall(CallStates.ERROR)],
interactions: getInteractions(CallStates.ERROR),
},
};

Expand Down
74 changes: 61 additions & 13 deletions addons/interactions/src/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ interface InteractionsPanelProps {
active: boolean;
controls: Controls;
controlStates: ControlStates;
interactions: (Call & { status?: CallStates })[];
interactions: (Call & {
status?: CallStates;
childCallIds: Call['id'][];
isCollapsed: boolean;
toggleCollapsed: () => void;
})[];
fileName?: string;
hasException?: boolean;
isPlaying?: boolean;
pausedAt?: Call['id'];
calls: Map<string, any>;
endRef?: React.Ref<HTMLDivElement>;
onScrollToEnd?: () => void;
Expand Down Expand Up @@ -66,6 +72,7 @@ export const AddonPanelPure: React.FC<InteractionsPanelProps> = React.memo(
fileName,
hasException,
isPlaying,
pausedAt,
onScrollToEnd,
endRef,
isRerunAnimating,
Expand All @@ -87,15 +94,21 @@ export const AddonPanelPure: React.FC<InteractionsPanelProps> = React.memo(
setIsRerunAnimating={setIsRerunAnimating}
/>
)}
{interactions.map((call) => (
<Interaction
key={call.id}
call={call}
callsById={calls}
controls={controls}
controlStates={controlStates}
/>
))}
<div>
{interactions.map((call) => (
<Interaction
key={call.id}
call={call}
callsById={calls}
controls={controls}
controlStates={controlStates}
childCallIds={call.childCallIds}
isCollapsed={call.isCollapsed}
toggleCollapsed={call.toggleCollapsed}
pausedAt={pausedAt}
/>
))}
</div>
<div ref={endRef} />
{!isPlaying && interactions.length === 0 && (
<Placeholder>
Expand All @@ -116,17 +129,17 @@ export const AddonPanelPure: React.FC<InteractionsPanelProps> = React.memo(
export const Panel: React.FC<AddonPanelProps> = (props) => {
const [storyId, setStoryId] = React.useState<StoryId>();
const [controlStates, setControlStates] = React.useState<ControlStates>(INITIAL_CONTROL_STATES);
const [pausedAt, setPausedAt] = React.useState<Call['id']>();
const [isPlaying, setPlaying] = React.useState(false);
const [isRerunAnimating, setIsRerunAnimating] = React.useState(false);
const [scrollTarget, setScrollTarget] = React.useState<HTMLElement>();
const [collapsed, setCollapsed] = React.useState<Set<Call['id']>>(new Set());
const [log, setLog] = React.useState<LogItem[]>([]);

// Calls are tracked in a ref so we don't needlessly rerender.
const calls = React.useRef<Map<Call['id'], Omit<Call, 'status'>>>(new Map());
const setCall = ({ status, ...call }: Call) => calls.current.set(call.id, call);

const [log, setLog] = React.useState<LogItem[]>([]);
const interactions = log.map(({ callId, status }) => ({ ...calls.current.get(callId), status }));

const endRef = React.useRef();
React.useEffect(() => {
let observer: IntersectionObserver;
Expand All @@ -146,10 +159,12 @@ export const Panel: React.FC<AddonPanelProps> = (props) => {
[EVENTS.SYNC]: (payload) => {
setControlStates(payload.controlStates);
setLog(payload.logItems);
setPausedAt(payload.pausedAt);
},
[STORY_RENDER_PHASE_CHANGED]: (event) => {
setStoryId(event.storyId);
setPlaying(event.newPhase === 'playing');
setPausedAt(undefined);
},
},
[]
Expand Down Expand Up @@ -177,6 +192,38 @@ export const Panel: React.FC<AddonPanelProps> = (props) => {
const showStatus = log.length > 0 && !isPlaying;
const hasException = log.some((item) => item.status === CallStates.ERROR);

const interactions = React.useMemo(() => {
const callsById = new Map<Call['id'], Call>();
const childCallMap = new Map<Call['id'], Call['id'][]>();
return log
.filter(({ callId, parentId }) => {
if (!parentId) return true;
childCallMap.set(parentId, (childCallMap.get(parentId) || []).concat(callId));
return !collapsed.has(parentId);
})
.map(({ callId, status }) => ({ ...calls.current.get(callId), status } as Call))
.map((call) => {
const status =
call.status === CallStates.ERROR &&
callsById.get(call.parentId)?.status === CallStates.ACTIVE
? CallStates.ACTIVE
: call.status;
callsById.set(call.id, { ...call, status });
return {
...call,
status,
childCallIds: childCallMap.get(call.id),
isCollapsed: collapsed.has(call.id),
toggleCollapsed: () =>
setCollapsed((ids) => {
if (ids.has(call.id)) ids.delete(call.id);
else ids.add(call.id);
return new Set(ids);
}),
};
});
}, [log, collapsed]);

return (
<React.Fragment key="interactions">
<TabStatus>
Expand All @@ -191,6 +238,7 @@ export const Panel: React.FC<AddonPanelProps> = (props) => {
fileName={fileName}
hasException={hasException}
isPlaying={isPlaying}
pausedAt={pausedAt}
endRef={endRef}
onScrollToEnd={scrollTarget && scrollToTarget}
isRerunAnimating={isRerunAnimating}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export const Demo: CSF2Story = (args) => (
Demo.play = async ({ args, canvasElement }) => {
await userEvent.click(within(canvasElement).getByRole('button'));
await expect(args.onSubmit).toHaveBeenCalledWith(expect.stringMatching(/([A-Z])\w+/gi));
await expect([{ name: 'John', age: 42 }]).toEqual(
expect.arrayContaining([
expect.objectContaining({ name: 'John' }),
expect.objectContaining({ age: 42 }),
])
);
};

export const FindBy: CSF2Story = (args) => {
Expand Down Expand Up @@ -131,7 +137,7 @@ export const StandardEmailFailed: CSF3Story = {
await userEvent.click(canvas.getByRole('button', { name: /create account/i }));

await canvas.findByText('Please enter a correctly formatted email address');
expect(args.onSubmit).not.toHaveBeenCalled();
await expect(args.onSubmit).not.toHaveBeenCalled();
},
};

Expand Down
Loading

0 comments on commit ad02c64

Please sign in to comment.