mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-01 05:05:25 +08:00
Merge pull request #5978 from storybooks/tech/prettier-sync
SYNC prettier printWidth with eslint && FIX resulting linting warnings
This commit is contained in:
commit
baa9c2c760
@ -16,7 +16,9 @@ export const Wrapper = styled(({ children, className }) => (
|
||||
padding: '10px 5px 20px',
|
||||
});
|
||||
|
||||
const ThemedInspector = withTheme(({ theme, ...props }) => <Inspector theme={theme.addonActionsTheme || 'chromeLight'} {...props} />);
|
||||
const ThemedInspector = withTheme(({ theme, ...props }) => (
|
||||
<Inspector theme={theme.addonActionsTheme || 'chromeLight'} {...props} />
|
||||
));
|
||||
|
||||
interface ActionLoggerProps {
|
||||
actions: ActionDisplay[];
|
||||
@ -30,7 +32,12 @@ export const ActionLogger = ({ actions, onClear }: ActionLoggerProps) => (
|
||||
<Action key={action.id}>
|
||||
{action.count > 1 && <Counter>{action.count}</Counter>}
|
||||
<InspectorContainer>
|
||||
<ThemedInspector sortObjectKeys showNonenumerable={false} name={action.data.name} data={action.data.args || action.data} />
|
||||
<ThemedInspector
|
||||
sortObjectKeys
|
||||
showNonenumerable={false}
|
||||
name={action.data.name}
|
||||
data={action.data.args || action.data}
|
||||
/>
|
||||
</InspectorContainer>
|
||||
</Action>
|
||||
))}
|
||||
|
@ -10,7 +10,9 @@ const applyDecorators = (decorators: DecoratorFunction[], actionCallback: Handle
|
||||
};
|
||||
};
|
||||
|
||||
export const decorateAction = (decorators: DecoratorFunction[]): ((name: string, options?: ActionOptions) => HandlerFunction) => {
|
||||
export const decorateAction = (
|
||||
decorators: DecoratorFunction[]
|
||||
): ((name: string, options?: ActionOptions) => HandlerFunction) => {
|
||||
return (name: string, options?: ActionOptions) => {
|
||||
const callAction = action(name, options);
|
||||
return applyDecorators(decorators, callAction);
|
||||
|
@ -50,7 +50,8 @@ const actionsSubscription = (...args: any[]) => {
|
||||
const handlers = createHandlers(...args);
|
||||
lastSubscription = () => {
|
||||
handlers.forEach(({ eventName, handler }) => root.addEventListener(eventName, handler));
|
||||
return () => handlers.forEach(({ eventName, handler }) => root.removeEventListener(eventName, handler));
|
||||
return () =>
|
||||
handlers.forEach(({ eventName, handler }) => root.removeEventListener(eventName, handler));
|
||||
};
|
||||
}
|
||||
return lastSubscription;
|
||||
|
@ -10,5 +10,5 @@ export const ColorIcon = styled.span(
|
||||
}),
|
||||
({ theme }) => ({
|
||||
boxShadow: `${theme.appBorderColor} 0 0 0 1px inset`,
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
@ -31,7 +31,10 @@ const createBackgroundSelectorItem = memoize(1000)(
|
||||
})
|
||||
);
|
||||
|
||||
const getSelectedBackgroundColor = (list: BackgroundConfig[], currentSelectedValue: string): string => {
|
||||
const getSelectedBackgroundColor = (
|
||||
list: BackgroundConfig[],
|
||||
currentSelectedValue: string
|
||||
): string => {
|
||||
if (!list.length) {
|
||||
return 'transparent';
|
||||
}
|
||||
@ -51,30 +54,36 @@ const getSelectedBackgroundColor = (list: BackgroundConfig[], currentSelectedVal
|
||||
return 'transparent';
|
||||
};
|
||||
|
||||
const getDisplayableState = memoize(10)((props: BackgroundToolProps, state: BackgroundToolState, change) => {
|
||||
const data = props.api.getCurrentStoryData();
|
||||
const list: BackgroundConfig[] = (data && data.parameters && data.parameters[PARAM_KEY]) || [];
|
||||
const getDisplayableState = memoize(10)(
|
||||
(props: BackgroundToolProps, state: BackgroundToolState, change) => {
|
||||
const data = props.api.getCurrentStoryData();
|
||||
const list: BackgroundConfig[] = (data && data.parameters && data.parameters[PARAM_KEY]) || [];
|
||||
|
||||
const selectedBackgroundColor = getSelectedBackgroundColor(list, state.selected);
|
||||
const selectedBackgroundColor = getSelectedBackgroundColor(list, state.selected);
|
||||
|
||||
let availableBackgroundSelectorItems: BackgroundSelectorItem[] = [];
|
||||
let availableBackgroundSelectorItems: BackgroundSelectorItem[] = [];
|
||||
|
||||
if (selectedBackgroundColor !== 'transparent') {
|
||||
availableBackgroundSelectorItems.push(createBackgroundSelectorItem('reset', 'Clear background', 'transparent', null, change));
|
||||
if (selectedBackgroundColor !== 'transparent') {
|
||||
availableBackgroundSelectorItems.push(
|
||||
createBackgroundSelectorItem('reset', 'Clear background', 'transparent', null, change)
|
||||
);
|
||||
}
|
||||
|
||||
if (list.length) {
|
||||
availableBackgroundSelectorItems = [
|
||||
...availableBackgroundSelectorItems,
|
||||
...list.map(({ name, value }) =>
|
||||
createBackgroundSelectorItem(null, name, value, true, change)
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
items: availableBackgroundSelectorItems,
|
||||
selectedBackgroundColor,
|
||||
};
|
||||
}
|
||||
|
||||
if (list.length) {
|
||||
availableBackgroundSelectorItems = [
|
||||
...availableBackgroundSelectorItems,
|
||||
...list.map(({ name, value }) => createBackgroundSelectorItem(null, name, value, true, change)),
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
items: availableBackgroundSelectorItems,
|
||||
selectedBackgroundColor,
|
||||
};
|
||||
});
|
||||
);
|
||||
|
||||
interface BackgroundToolProps {
|
||||
api: {
|
||||
@ -119,7 +128,11 @@ export class BackgroundSelector extends Component<BackgroundToolProps, Backgroun
|
||||
|
||||
render() {
|
||||
const { expanded } = this.state;
|
||||
const { items, selectedBackgroundColor } = getDisplayableState(this.props, this.state, this.change);
|
||||
const { items, selectedBackgroundColor } = getDisplayableState(
|
||||
this.props,
|
||||
this.state,
|
||||
this.change
|
||||
);
|
||||
|
||||
return items.length ? (
|
||||
<Fragment>
|
||||
@ -136,11 +149,17 @@ export class BackgroundSelector extends Component<BackgroundToolProps, Backgroun
|
||||
placement="top"
|
||||
trigger="click"
|
||||
tooltipShown={expanded}
|
||||
onVisibilityChange={(newVisibility: boolean) => this.setState({ expanded: newVisibility })}
|
||||
onVisibilityChange={(newVisibility: boolean) =>
|
||||
this.setState({ expanded: newVisibility })
|
||||
}
|
||||
tooltip={<TooltipLinkList links={items} />}
|
||||
closeOnClick
|
||||
>
|
||||
<IconButton key="background" active={selectedBackgroundColor !== 'transparent'} title="Change the background of the preview">
|
||||
<IconButton
|
||||
key="background"
|
||||
active={selectedBackgroundColor !== 'transparent'}
|
||||
title="Change the background of the preview"
|
||||
>
|
||||
<Icons icon="photo" />
|
||||
</IconButton>
|
||||
</WithTooltip>
|
||||
|
@ -4,7 +4,12 @@ import { types } from '@storybook/addons';
|
||||
import { styled } from '@storybook/theming';
|
||||
import { STORY_RENDERED } from '@storybook/core-events';
|
||||
|
||||
import { SyntaxHighlighter as SyntaxHighlighterBase, Placeholder, DocumentFormatting, Link } from '@storybook/components';
|
||||
import {
|
||||
SyntaxHighlighter as SyntaxHighlighterBase,
|
||||
Placeholder,
|
||||
DocumentFormatting,
|
||||
Link,
|
||||
} from '@storybook/components';
|
||||
import Giphy from './giphy';
|
||||
import Markdown from 'markdown-to-jsx';
|
||||
|
||||
@ -46,7 +51,7 @@ export const SyntaxHighlighter = (props: any) => {
|
||||
if (props.className === undefined) {
|
||||
return <code>{props.children}</code>;
|
||||
}
|
||||
//className: "lang-jsx"
|
||||
// className: "lang-jsx"
|
||||
const language = props.className.split('-');
|
||||
return <SyntaxHighlighterBase language={language[1]} bordered copyable {...props} />;
|
||||
};
|
||||
@ -112,7 +117,10 @@ export default class NotesPanel extends React.Component<Props, NotesPanelState>
|
||||
}
|
||||
|
||||
// TODO: memoize
|
||||
const extraElements = Object.entries(api.getElements(types.NOTES_ELEMENT)).reduce((acc, [k, v]) => ({ ...acc, [k]: v.render }), {});
|
||||
const extraElements = Object.entries(api.getElements(types.NOTES_ELEMENT)).reduce(
|
||||
(acc, [k, v]) => ({ ...acc, [k]: v.render }),
|
||||
{}
|
||||
);
|
||||
const options = {
|
||||
...defaultOptions,
|
||||
overrides: { ...defaultOptions.overrides, ...extraElements },
|
||||
@ -129,7 +137,11 @@ export default class NotesPanel extends React.Component<Props, NotesPanelState>
|
||||
<React.Fragment>No notes yet</React.Fragment>
|
||||
<React.Fragment>
|
||||
Learn how to{' '}
|
||||
<Link href="https://github.com/storybooks/storybook/tree/master/addons/notes" target="_blank" withArrow>
|
||||
<Link
|
||||
href="https://github.com/storybooks/storybook/tree/master/addons/notes"
|
||||
target="_blank"
|
||||
withArrow
|
||||
>
|
||||
document components in Markdown
|
||||
</Link>
|
||||
</React.Fragment>
|
||||
|
@ -8,26 +8,32 @@ export const withNotes = makeDecorator({
|
||||
skipIfNoParametersOrOptions: true,
|
||||
allowDeprecatedUsage: true,
|
||||
|
||||
wrapper: deprecate((getStory: StoryGetter, context: StoryContext, { options, parameters }: WrapperSettings) => {
|
||||
const storyOptions = parameters || options;
|
||||
wrapper: deprecate(
|
||||
(getStory: StoryGetter, context: StoryContext, { options, parameters }: WrapperSettings) => {
|
||||
const storyOptions = parameters || options;
|
||||
|
||||
const { text, markdown } =
|
||||
typeof storyOptions === 'string'
|
||||
? {
|
||||
text: storyOptions,
|
||||
markdown: undefined,
|
||||
}
|
||||
: storyOptions;
|
||||
const { text, markdown } =
|
||||
typeof storyOptions === 'string'
|
||||
? {
|
||||
text: storyOptions,
|
||||
markdown: undefined,
|
||||
}
|
||||
: storyOptions;
|
||||
|
||||
if (!text && !markdown) {
|
||||
throw new Error(`Parameter 'notes' must must be a string or an object with 'text' or 'markdown' properties`);
|
||||
}
|
||||
if (!text && !markdown) {
|
||||
throw new Error(
|
||||
`Parameter 'notes' must must be a string or an object with 'text' or 'markdown' properties`
|
||||
);
|
||||
}
|
||||
|
||||
return getStory(context);
|
||||
}, 'withNotes is deprecated'),
|
||||
return getStory(context);
|
||||
},
|
||||
'withNotes is deprecated'
|
||||
),
|
||||
});
|
||||
|
||||
export const withMarkdownNotes = deprecate((text: string, options: any) => {}, 'withMarkdownNotes is deprecated');
|
||||
export const withMarkdownNotes = deprecate((text: string, options: any) => {},
|
||||
'withMarkdownNotes is deprecated');
|
||||
|
||||
if (module && module.hot && module.hot.decline) {
|
||||
module.hot.decline();
|
||||
|
@ -43,7 +43,13 @@ export const initModuleData = (storyObj: NgStory): any => {
|
||||
props,
|
||||
};
|
||||
|
||||
const moduleMeta = getModuleMeta([AppComponent, AnnotatedComponent], [AnnotatedComponent], [AppComponent], story, moduleMetadata);
|
||||
const moduleMeta = getModuleMeta(
|
||||
[AppComponent, AnnotatedComponent],
|
||||
[AnnotatedComponent],
|
||||
[AppComponent],
|
||||
story,
|
||||
moduleMetadata
|
||||
);
|
||||
|
||||
return {
|
||||
AppComponent,
|
||||
|
@ -9,7 +9,10 @@ export const moduleMetadata = (metadata: Partial<NgModuleMetadata>) => (storyFn:
|
||||
...story,
|
||||
moduleMetadata: {
|
||||
declarations: [...(metadata.declarations || []), ...(storyMetadata.declarations || [])],
|
||||
entryComponents: [...(metadata.entryComponents || []), ...(storyMetadata.entryComponents || [])],
|
||||
entryComponents: [
|
||||
...(metadata.entryComponents || []),
|
||||
...(storyMetadata.entryComponents || []),
|
||||
],
|
||||
imports: [...(metadata.imports || []), ...(storyMetadata.imports || [])],
|
||||
schemas: [...(metadata.schemas || []), ...(storyMetadata.schemas || [])],
|
||||
providers: [...(metadata.providers || []), ...(storyMetadata.providers || [])],
|
||||
|
@ -51,7 +51,13 @@ const initModule = (storyFn: IStoryFn) => {
|
||||
props,
|
||||
};
|
||||
|
||||
return getModule([AppComponent, AnnotatedComponent], [AnnotatedComponent], [AppComponent], story, moduleMetadata);
|
||||
return getModule(
|
||||
[AppComponent, AnnotatedComponent],
|
||||
[AnnotatedComponent],
|
||||
[AppComponent],
|
||||
story,
|
||||
moduleMetadata
|
||||
);
|
||||
};
|
||||
|
||||
const staticRoot = document.getElementById('root');
|
||||
|
@ -7,29 +7,39 @@ import { Component, Output, EventEmitter } from '@angular/core';
|
||||
<h1>Welcome to storybook</h1>
|
||||
<p>This is a UI component dev environment for your app.</p>
|
||||
<p>
|
||||
We've added some basic stories inside the <span class="inline-code">src/stories</span> directory. <br />
|
||||
A story is a single state of one or more UI components. You can have as many stories as you want. <br />
|
||||
We've added some basic stories inside the
|
||||
<span class="inline-code">src/stories</span> directory. <br />
|
||||
A story is a single state of one or more UI components. You can have as many stories as you
|
||||
want. <br />
|
||||
(Basically a story is like a visual test case.)
|
||||
</p>
|
||||
<p>
|
||||
See these sample <a (click)="showApp.emit($event)" role="button" tabIndex="0">stories</a> for a component called
|
||||
<span class="inline-code">Button</span> .
|
||||
See these sample
|
||||
<a (click)="showApp.emit($event)" role="button" tabIndex="0">stories</a> for a component
|
||||
called <span class="inline-code">Button</span> .
|
||||
</p>
|
||||
<p>
|
||||
Just like that, you can add your own components as stories. <br />
|
||||
You can also edit those components and see changes right away. <br />
|
||||
(Try editing the <span class="inline-code">Button</span> stories located at <span class="inline-code">src/stories/index.js</span>.)
|
||||
(Try editing the <span class="inline-code">Button</span> stories located at
|
||||
<span class="inline-code">src/stories/index.js</span>.)
|
||||
</p>
|
||||
<p>
|
||||
Usually we create stories with smaller UI components in the app.<br />
|
||||
Have a look at the
|
||||
<a href="https://storybook.js.org/basics/writing-stories" target="_blank" rel="noopener noreferrer"> Writing Stories </a> section in
|
||||
our documentation.
|
||||
<a
|
||||
href="https://storybook.js.org/basics/writing-stories"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Writing Stories
|
||||
</a>
|
||||
section in our documentation.
|
||||
</p>
|
||||
<p class="note">
|
||||
<b>NOTE:</b> <br />
|
||||
Have a look at the <span class="inline-code">.storybook/webpack.config.js</span> to add webpack loaders and plugins you are using in
|
||||
this project.
|
||||
Have a look at the <span class="inline-code">.storybook/webpack.config.js</span> to add
|
||||
webpack loaders and plugins you are using in this project.
|
||||
</p>
|
||||
</main>
|
||||
`,
|
||||
|
@ -7,7 +7,10 @@ import 'zone.js/dist/jasmine-patch';
|
||||
import 'zone.js/dist/async-test';
|
||||
import 'zone.js/dist/fake-async-test';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting,
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
||||
declare const __karma__: any;
|
||||
|
@ -4,7 +4,10 @@ import { AppComponent } from '../app/app.component';
|
||||
|
||||
storiesOf('Addon|Background', module)
|
||||
.addParameters({
|
||||
backgrounds: [{ name: 'twitter', value: '#00aced', default: true }, { name: 'facebook', value: '#3b5998' }],
|
||||
backgrounds: [
|
||||
{ name: 'twitter', value: '#00aced', default: true },
|
||||
{ name: 'facebook', value: '#3b5998' },
|
||||
],
|
||||
})
|
||||
.add('background component', () => ({
|
||||
component: AppComponent,
|
||||
@ -18,7 +21,10 @@ storiesOf('Addon|Background', module)
|
||||
})
|
||||
)
|
||||
.addParameters({
|
||||
backgrounds: [{ name: 'twitter', value: '#00aced', default: true }, { name: 'facebook', value: '#3b5998' }],
|
||||
backgrounds: [
|
||||
{ name: 'twitter', value: '#00aced', default: true },
|
||||
{ name: 'facebook', value: '#3b5998' },
|
||||
],
|
||||
})
|
||||
.add('background template', () => ({
|
||||
template: `<storybook-button-component [text]="text" (onClick)="onClick($event)"></storybook-button-component>`,
|
||||
|
@ -1,7 +1,18 @@
|
||||
import { storiesOf } from '@storybook/angular';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { withKnobs, text, number, boolean, array, select, radios, color, date, button } from '@storybook/addon-knobs';
|
||||
import {
|
||||
withKnobs,
|
||||
text,
|
||||
number,
|
||||
boolean,
|
||||
array,
|
||||
select,
|
||||
radios,
|
||||
color,
|
||||
date,
|
||||
button,
|
||||
} from '@storybook/addon-knobs';
|
||||
|
||||
import { SimpleKnobsComponent } from './knobs.component';
|
||||
import { AllKnobsComponent } from './all-knobs.component';
|
||||
|
@ -3,7 +3,9 @@ import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/cor
|
||||
@Component({
|
||||
selector: 'storybook-simple-knobs-component',
|
||||
template: `
|
||||
<div [ngStyle]="{ border: '2px dotted ' + border, 'padding.px': '8 22', 'border-radius.px': '8' }">
|
||||
<div
|
||||
[ngStyle]="{ border: '2px dotted ' + border, 'padding.px': '8 22', 'border-radius.px': '8' }"
|
||||
>
|
||||
<h1>My name is {{ name }},</h1>
|
||||
<h3>today is {{ today | date }}</h3>
|
||||
<p *ngIf="stock">I have a stock of {{ stock }} {{ fruit }}, costing $ {{ price }} each.</p>
|
||||
|
@ -11,7 +11,11 @@ export class DiComponent {
|
||||
@Input()
|
||||
title: string;
|
||||
|
||||
constructor(protected injector: Injector, protected elRef: ElementRef, @Inject(TEST_TOKEN) protected testToken: number) {}
|
||||
constructor(
|
||||
protected injector: Injector,
|
||||
protected elRef: ElementRef,
|
||||
@Inject(TEST_TOKEN) protected testToken: number
|
||||
) {}
|
||||
|
||||
isAllDeps(): boolean {
|
||||
return Boolean(this.testToken && this.elRef && this.injector && this.title);
|
||||
|
@ -3,6 +3,10 @@ import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import Button from './Button';
|
||||
|
||||
storiesOf('Button', module).add('simple button', () => <Button onClick={action('button clicked')}>OK</Button>, {
|
||||
info: { inline: true },
|
||||
});
|
||||
storiesOf('Button', module).add(
|
||||
'simple button',
|
||||
() => <Button onClick={action('button clicked')}>OK</Button>,
|
||||
{
|
||||
info: { inline: true },
|
||||
}
|
||||
);
|
||||
|
@ -48,7 +48,9 @@ export class AddonStore {
|
||||
getChannel = (): Channel => {
|
||||
// this.channel should get overwritten by setChannel. If it wasn't called (e.g. in non-browser environment), throw.
|
||||
if (!this.channel) {
|
||||
throw new Error('Accessing non-existent addons channel, see https://storybook.js.org/basics/faq/#why-is-there-no-addons-channel');
|
||||
throw new Error(
|
||||
'Accessing non-existent addons channel, see https://storybook.js.org/basics/faq/#why-is-there-no-addons-channel'
|
||||
);
|
||||
}
|
||||
|
||||
return this.channel;
|
||||
|
@ -5,7 +5,11 @@ import { makeDecorator, StoryContext, StoryGetter } from './make-decorator';
|
||||
type DecoratorFn = (fn: StoryGetter, context: StoryContext) => any;
|
||||
|
||||
export const defaultDecorateStory = (getStory: StoryGetter, decorators: DecoratorFn[]) =>
|
||||
decorators.reduce((decorated, decorator) => (context: StoryContext) => decorator(() => decorated(context), context), getStory);
|
||||
decorators.reduce(
|
||||
(decorated, decorator) => (context: StoryContext) =>
|
||||
decorator(() => decorated(context), context),
|
||||
getStory
|
||||
);
|
||||
|
||||
jest.mock('util-deprecate');
|
||||
let deprecatedFns: any[] = [];
|
||||
|
@ -19,7 +19,11 @@ export interface WrapperSettings {
|
||||
|
||||
export type StoryGetter = (context: StoryContext) => any;
|
||||
|
||||
export type StoryWrapper = (getStory: StoryGetter, context: StoryContext, settings: WrapperSettings) => any;
|
||||
export type StoryWrapper = (
|
||||
getStory: StoryGetter,
|
||||
context: StoryContext,
|
||||
settings: WrapperSettings
|
||||
) => any;
|
||||
|
||||
type MakeDecoratorResult = (...args: any) => any;
|
||||
|
||||
|
@ -189,7 +189,8 @@ describe('Channel', () => {
|
||||
const eventName = 'event1';
|
||||
const listenerToBeRemoved = jest.fn();
|
||||
const listeners = [jest.fn(), jest.fn()];
|
||||
const findListener = (listener: Listener) => channel.listeners(eventName).find(_listener => _listener === listener);
|
||||
const findListener = (listener: Listener) =>
|
||||
channel.listeners(eventName).find(_listener => _listener === listener);
|
||||
|
||||
listeners.forEach(fn => channel.addListener(eventName, fn));
|
||||
channel.addListener(eventName, listenerToBeRemoved);
|
||||
|
@ -27,37 +27,43 @@ const sanitizeSafe = (string: string, part: string) => {
|
||||
return sanitized;
|
||||
};
|
||||
|
||||
export const toId = (kind: string, name: string) => `${sanitizeSafe(kind, 'kind')}--${sanitizeSafe(name, 'name')}`;
|
||||
export const toId = (kind: string, name: string) =>
|
||||
`${sanitizeSafe(kind, 'kind')}--${sanitizeSafe(name, 'name')}`;
|
||||
|
||||
export const storyDataFromString: (path: string) => StoryData = memoize(1000)((path: string | undefined | null) => {
|
||||
const result: StoryData = {
|
||||
viewMode: undefined,
|
||||
storyId: undefined,
|
||||
};
|
||||
export const storyDataFromString: (path: string) => StoryData = memoize(1000)(
|
||||
(path: string | undefined | null) => {
|
||||
const result: StoryData = {
|
||||
viewMode: undefined,
|
||||
storyId: undefined,
|
||||
};
|
||||
|
||||
if (path) {
|
||||
const [, viewMode, storyId] = path.match(splitPath) || [undefined, undefined, undefined];
|
||||
if (viewMode && viewMode.match(knownViewModesRegex)) {
|
||||
Object.assign(result, {
|
||||
viewMode,
|
||||
storyId,
|
||||
});
|
||||
if (path) {
|
||||
const [, viewMode, storyId] = path.match(splitPath) || [undefined, undefined, undefined];
|
||||
if (viewMode && viewMode.match(knownViewModesRegex)) {
|
||||
Object.assign(result, {
|
||||
viewMode,
|
||||
storyId,
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
);
|
||||
|
||||
export const queryFromString = memoize(1000)(s => qs.parse(s, { ignoreQueryPrefix: true }));
|
||||
export const queryFromLocation = (location: { search: string }) => queryFromString(location.search);
|
||||
export const stringifyQuery = (query: object) => qs.stringify(query, { addQueryPrefix: true, encode: false });
|
||||
export const stringifyQuery = (query: object) =>
|
||||
qs.stringify(query, { addQueryPrefix: true, encode: false });
|
||||
|
||||
export const getMatch = memoize(1000)((current: string, target: string, startsWith: boolean = true) => {
|
||||
const startsWithTarget = current && startsWith && current.startsWith(target);
|
||||
const currentIsTarget = typeof target === 'string' && current === target;
|
||||
const matchTarget = current && target && current.match(target);
|
||||
export const getMatch = memoize(1000)(
|
||||
(current: string, target: string, startsWith: boolean = true) => {
|
||||
const startsWithTarget = current && startsWith && current.startsWith(target);
|
||||
const currentIsTarget = typeof target === 'string' && current === target;
|
||||
const matchTarget = current && target && current.match(target);
|
||||
|
||||
if (startsWithTarget || currentIsTarget || matchTarget) {
|
||||
return { path: current };
|
||||
if (startsWithTarget || currentIsTarget || matchTarget) {
|
||||
return { path: current };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
);
|
||||
|
@ -9,7 +9,10 @@ import { Theme, color, Color, background, typography, ThemeVars } from './base';
|
||||
import { easing, animation } from './animation';
|
||||
import { create as createSyntax } from './modules/syntax';
|
||||
|
||||
const themes: { light: ThemeVars; dark: ThemeVars } = { light: lightThemeVars, dark: darkThemeVars };
|
||||
const themes: { light: ThemeVars; dark: ThemeVars } = {
|
||||
light: lightThemeVars,
|
||||
dark: darkThemeVars,
|
||||
};
|
||||
|
||||
interface Rest {
|
||||
[key: string]: any;
|
||||
@ -127,7 +130,8 @@ export const convert = (inherit: ThemeVars = lightThemeVars): Theme => {
|
||||
background: {
|
||||
app: appBg,
|
||||
content: appContentBg,
|
||||
hoverable: base === 'light' ? 'rgba(0,0,0,.05)' : 'rgba(250,250,252,.1)' || background.hoverable,
|
||||
hoverable:
|
||||
base === 'light' ? 'rgba(0,0,0,.05)' : 'rgba(250,250,252,.1)' || background.hoverable,
|
||||
|
||||
positive: background.positive,
|
||||
negative: background.negative,
|
||||
|
@ -87,7 +87,15 @@ export const createReset = memoize(1)(
|
||||
);
|
||||
|
||||
export const createGlobal = memoize(1)(
|
||||
({ color, background, typography }: { color: Color; background: Background; typography: Typography }): Return => {
|
||||
({
|
||||
color,
|
||||
background,
|
||||
typography,
|
||||
}: {
|
||||
color: Color;
|
||||
background: Background;
|
||||
typography: Typography;
|
||||
}): Return => {
|
||||
const resetStyles = createReset({ typography });
|
||||
return {
|
||||
...resetStyles,
|
||||
|
@ -416,7 +416,13 @@ export class SimpleKeybinding {
|
||||
|
||||
public readonly keyCode: KeyCode;
|
||||
|
||||
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, keyCode: KeyCode) {
|
||||
constructor(
|
||||
ctrlKey: boolean,
|
||||
shiftKey: boolean,
|
||||
altKey: boolean,
|
||||
metaKey: boolean,
|
||||
keyCode: KeyCode
|
||||
) {
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.altKey = altKey;
|
||||
@ -492,7 +498,10 @@ export function createKeyBinding(keybinding: number, OS: OperatingSystem): Keybi
|
||||
const chordPart = (keybinding & 0xffff0000) >>> 16;
|
||||
|
||||
if (chordPart !== 0) {
|
||||
return new ChordKeybinding(createSimpleKeybinding(firstPart, OS), createSimpleKeybinding(chordPart, OS));
|
||||
return new ChordKeybinding(
|
||||
createSimpleKeybinding(firstPart, OS),
|
||||
createSimpleKeybinding(chordPart, OS)
|
||||
);
|
||||
}
|
||||
|
||||
return createSimpleKeybinding(firstPart, OS);
|
||||
@ -525,7 +534,14 @@ export class ResolveKeybindingPart {
|
||||
|
||||
readonly keyAriaLabel: string | null;
|
||||
|
||||
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, kbLabel: string | null, kbAriaLabel: string | null) {
|
||||
constructor(
|
||||
ctrlKey: boolean,
|
||||
shiftKey: boolean,
|
||||
altKey: boolean,
|
||||
metaKey: boolean,
|
||||
kbLabel: string | null,
|
||||
kbAriaLabel: string | null
|
||||
) {
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.altKey = altKey;
|
||||
|
@ -31,4 +31,8 @@ export const enum OperatingSystem {
|
||||
Linux = 3,
|
||||
}
|
||||
|
||||
export const OS = _isMacintosh ? OperatingSystem.Macintosh : _isWindows ? OperatingSystem.Windows : OperatingSystem.Linux;
|
||||
export const OS = _isMacintosh
|
||||
? OperatingSystem.Macintosh
|
||||
: _isWindows
|
||||
? OperatingSystem.Windows
|
||||
: OperatingSystem.Linux;
|
||||
|
@ -229,7 +229,13 @@ export class ScanCodeBinding {
|
||||
public readonly metaKey: boolean;
|
||||
public readonly scanCode: ScanCode;
|
||||
|
||||
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, scanCode: ScanCode) {
|
||||
constructor(
|
||||
ctrlKey: boolean,
|
||||
shiftKey: boolean,
|
||||
altKey: boolean,
|
||||
metaKey: boolean,
|
||||
scanCode: ScanCode
|
||||
) {
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.altKey = altKey;
|
||||
@ -252,10 +258,14 @@ export class ScanCodeBinding {
|
||||
*/
|
||||
public isDuplicateModifierCase(): boolean {
|
||||
return (
|
||||
(this.ctrlKey && (this.scanCode === ScanCode.ControlLeft || this.scanCode === ScanCode.ControlRight)) ||
|
||||
(this.shiftKey && (this.scanCode === ScanCode.ShiftLeft || this.scanCode === ScanCode.ShiftRight)) ||
|
||||
(this.altKey && (this.scanCode === ScanCode.AltLeft || this.scanCode === ScanCode.AltRight)) ||
|
||||
(this.metaKey && (this.scanCode === ScanCode.MetaLeft || this.scanCode === ScanCode.MetaRight))
|
||||
(this.ctrlKey &&
|
||||
(this.scanCode === ScanCode.ControlLeft || this.scanCode === ScanCode.ControlRight)) ||
|
||||
(this.shiftKey &&
|
||||
(this.scanCode === ScanCode.ShiftLeft || this.scanCode === ScanCode.ShiftRight)) ||
|
||||
(this.altKey &&
|
||||
(this.scanCode === ScanCode.AltLeft || this.scanCode === ScanCode.AltRight)) ||
|
||||
(this.metaKey &&
|
||||
(this.scanCode === ScanCode.MetaLeft || this.scanCode === ScanCode.MetaRight))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,14 @@ import { navigator } from 'global';
|
||||
// The shortcut is our JSON-ifiable representation of a shortcut combination
|
||||
type Shortcut = string[];
|
||||
|
||||
export const isMacLike = () => (navigator && navigator.platform ? !!navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) : false);
|
||||
export const isMacLike = () =>
|
||||
navigator && navigator.platform ? !!navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) : false;
|
||||
export const controlOrMetaSymbol = () => (isMacLike() ? '⌘' : 'ctrl');
|
||||
export const controlOrMetaKey = () => (isMacLike() ? 'meta' : 'control');
|
||||
export const optionOrAltSymbol = () => (isMacLike() ? '⌥' : 'alt');
|
||||
|
||||
export const isShortcutTaken = (arr1: string[], arr2: string[]): boolean => JSON.stringify(arr1) === JSON.stringify(arr2);
|
||||
export const isShortcutTaken = (arr1: string[], arr2: string[]): boolean =>
|
||||
JSON.stringify(arr1) === JSON.stringify(arr2);
|
||||
|
||||
// Map a keyboard event to a keyboard shortcut
|
||||
// NOTE: if we change the fields on the event that we need, we'll need to update the serialization in core/preview/start.js
|
||||
@ -58,7 +60,11 @@ export const eventToShortcut = (e: KeyboardEvent): Shortcut | null => {
|
||||
};
|
||||
|
||||
export const shortcutMatchesShortcut = (inputShortcut: Shortcut, shortcut: Shortcut): boolean => {
|
||||
return inputShortcut && inputShortcut.length === shortcut.length && !inputShortcut.find((key, i) => key !== shortcut[i]);
|
||||
return (
|
||||
inputShortcut &&
|
||||
inputShortcut.length === shortcut.length &&
|
||||
!inputShortcut.find((key, i) => key !== shortcut[i])
|
||||
);
|
||||
};
|
||||
|
||||
// Should this keyboard event trigger this keyboard shortcut?
|
||||
|
@ -5,7 +5,7 @@
|
||||
"prettier": {
|
||||
"severity": "warning",
|
||||
"options": {
|
||||
"printWidth": 140,
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "es5",
|
||||
|
Loading…
x
Reference in New Issue
Block a user