Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/.storybook/bench/bench.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default {
return (
<iframe
src="/bundle-analyzer/index.html"
style={{ border: 'none', width: '100%', height: '100vh' }}
style={{ position: 'fixed', width: '100vw', height: '100vh', border: 'none' }}
key={args.metafile} // force re-render on args change
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CheckIcon, EllipsisIcon, PlayAllHollowIcon } from '@storybook/icons';

import { Badge, Form, ProgressSpinner } from '../..';
import preview from '../../../../../.storybook/preview';
import { Shortcut } from '../../../manager/container/Menu';
import { Shortcut } from '../../../manager/components/Shortcut';
import { ActionList } from './ActionList';

const meta = preview.meta({
Expand Down
12 changes: 6 additions & 6 deletions code/core/src/components/components/Zoom/ZoomIFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export class ZoomIFrame extends Component<IZoomIFrameProps> {
try {
// @ts-expect-error (non strict)
Object.assign(this.iframe.contentDocument.body.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
width: `${(1 / scale) * 100}%`,
height: `${(1 / scale) * 100}%`,
transform: `scale(${scale})`,
Comment thread
ghengeveld marked this conversation as resolved.
transformOrigin: 'top left',
});
} catch (e) {
Expand All @@ -51,9 +51,9 @@ export class ZoomIFrame extends Component<IZoomIFrameProps> {

setIframeZoom(scale: number) {
Object.assign(this.iframe.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
width: `${(1 / scale) * 100}%`,
height: `${(1 / scale) * 100}%`,
transform: `scale(${scale})`,
transformOrigin: 'top left',
});
}
Expand Down
19 changes: 11 additions & 8 deletions code/core/src/manager-api/modules/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ export interface SubAPI {
* @param shortcuts The new shortcuts to set.
* @returns A promise that resolves to the new shortcuts.
*/
setShortcuts(shortcuts: API_Shortcuts): Promise<API_Shortcuts>;
setShortcuts(
update: API_Shortcuts | ((shortcuts: API_Shortcuts) => API_Shortcuts)
): Promise<API_Shortcuts>;
/**
* Sets the shortcut for the given action to the given value.
*
Expand Down Expand Up @@ -205,24 +207,25 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) => {

return defaults;
},
async setShortcuts(shortcuts: API_Shortcuts) {
await store.setState({ shortcuts }, { persistence: 'permanent' });
async setShortcuts(update) {
const { shortcuts } = await store.setState(
(state) => ({ shortcuts: typeof update === 'function' ? update(state.shortcuts) : update }),
{ persistence: 'permanent' }
);
return shortcuts;
},
async restoreAllDefaultShortcuts() {
return api.setShortcuts(api.getDefaultShortcuts() as API_Shortcuts);
},
async setShortcut(action, value) {
const shortcuts = api.getShortcutKeys();
await api.setShortcuts({ ...shortcuts, [action]: value });
await api.setShortcuts((shortcuts) => ({ ...shortcuts, [action]: value }));
return value;
},
async setAddonShortcut(addon: string, shortcut: API_AddonShortcut) {
const shortcuts = api.getShortcutKeys();
await api.setShortcuts({
await api.setShortcuts((shortcuts) => ({
...shortcuts,
[`${addon}-${shortcut.actionName}`]: shortcut.defaultShortcut,
});
}));
addonsShortcuts[`${addon}-${shortcut.actionName}`] = shortcut;
return shortcut;
},
Expand Down
4 changes: 3 additions & 1 deletion code/core/src/manager-api/tests/shortcuts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ function createMockStore() {
let state = {};
return {
getState: vi.fn().mockImplementation(() => state),
setState: vi.fn().mockImplementation((s) => {
setState: vi.fn().mockImplementation((update) => {
const s = typeof update === 'function' ? update(state) : update;
state = { ...state, ...s };
return state;
}),
};
}
Expand Down
36 changes: 36 additions & 0 deletions code/core/src/manager/components/Shortcut.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';

import { shortcutToHumanString } from 'storybook/manager-api';
import { styled } from 'storybook/theming';

const Wrapper = styled.span(({ theme }) => ({
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: 16,
fontSize: '11px',
fontWeight: theme.typography.weight.regular,
background: theme.base === 'light' ? 'rgba(0,0,0,0.05)' : 'rgba(255,255,255,0.05)',
color: theme.base === 'light' ? theme.color.dark : theme.textMutedColor,
borderRadius: 2,
userSelect: 'none',
pointerEvents: 'none',
padding: '0 4px',
}));

const Key = styled.kbd(({ theme }) => ({
padding: 0,
fontFamily: theme.typography.fonts.base,
verticalAlign: 'middle',
'& + &': {
marginLeft: 6,
},
}));

export const Shortcut = ({ keys }: { keys: string[] }) => (
<Wrapper>
{keys.map((key) => (
<Key key={key}>{shortcutToHumanString([key])}</Key>
))}
</Wrapper>
);
105 changes: 105 additions & 0 deletions code/core/src/manager/components/preview/NumericInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { expect, fireEvent, fn } from 'storybook/test';

import preview from '../../../../../.storybook/preview';
import { NumericInput } from './NumericInput';

const meta = preview.meta({
component: NumericInput,
tags: ['autodocs'],
args: {
setValue: fn(),
},
});

export default meta;

export const Default = meta.story({
args: {
value: '10',
},
play: async ({ args, canvas }) => {
const input = await canvas.findByRole('textbox');
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(input).toHaveValue('11');
expect(args.setValue).toHaveBeenNthCalledWith(1, '11');
expect(args.setValue).toHaveBeenNthCalledWith(2, '12');
expect(args.setValue).toHaveBeenNthCalledWith(3, '11');
},
});

export const WithParsedUnit = meta.story({
args: {
value: '10em',
},
play: async ({ args, canvas }) => {
const input = await canvas.findByRole('textbox');
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(input).toHaveValue('11em');
expect(args.setValue).toHaveBeenNthCalledWith(1, '11em');
expect(args.setValue).toHaveBeenNthCalledWith(2, '12em');
expect(args.setValue).toHaveBeenNthCalledWith(3, '11em');
},
});

export const WithExplicitUnit = meta.story({
args: {
value: '10',
unit: 'vw',
},
play: async ({ args, canvas }) => {
const input = await canvas.findByRole('textbox');
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(input).toHaveValue('11vw');
expect(args.setValue).toHaveBeenNthCalledWith(1, '11vw');
expect(args.setValue).toHaveBeenNthCalledWith(2, '12vw');
expect(args.setValue).toHaveBeenNthCalledWith(3, '11vw');
},
});

export const WithBaseUnit = meta.story({
args: {
value: '10em',
baseUnit: 'em',
},
play: async ({ args, canvas }) => {
const input = await canvas.findByRole('textbox');
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(input).toHaveValue('11');
expect(args.setValue).toHaveBeenNthCalledWith(1, '11em');
expect(args.setValue).toHaveBeenNthCalledWith(2, '12em');
expect(args.setValue).toHaveBeenNthCalledWith(3, '11em');
},
});

export const WithMinAndMax = meta.story({
args: {
value: '10em',
minValue: 9,
maxValue: 11,
},
play: async ({ args, canvas }) => {
const input = await canvas.findByRole('textbox');
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
fireEvent.keyDown(input, { key: 'ArrowUp' });
expect(input).toHaveValue('11em');
fireEvent.keyDown(input, { key: 'ArrowDown' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(input).toHaveValue('9em');
expect(args.setValue).toHaveBeenNthCalledWith(1, '11em');
expect(args.setValue).toHaveBeenNthCalledWith(2, '11em');
expect(args.setValue).toHaveBeenNthCalledWith(3, '11em');
expect(args.setValue).toHaveBeenNthCalledWith(4, '10em');
expect(args.setValue).toHaveBeenNthCalledWith(5, '9em');
expect(args.setValue).toHaveBeenNthCalledWith(6, '9em');
},
});
Loading
Loading