UNPKG

react-carousel-query

Version:

A infinite carousel component made with react that handles the pagination for you.

377 lines (317 loc) 12.9 kB
const _excluded = ["globals", "globalTypes"], _excluded2 = ["decorators", "loaders", "component", "args", "argTypes"], _excluded3 = ["component", "args", "argTypes"]; function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; import global from 'global'; import { logger } from '@storybook/client-logger'; import { toId, sanitize } from '@storybook/csf'; import { combineParameters, normalizeInputTypes } from '@storybook/store'; import { StoryStoreFacade } from './StoryStoreFacade'; // ClientApi (and StoreStore) are really singletons. However they are not created until the // relevant framework instanciates them via `start.js`. The good news is this happens right away. let singleton; const warningAlternatives = { addDecorator: `Instead, use \`export const decorators = [];\` in your \`preview.js\`.`, addParameters: `Instead, use \`export const parameters = {};\` in your \`preview.js\`.`, addLoaders: `Instead, use \`export const loaders = [];\` in your \`preview.js\`.` }; const warningMessage = method => deprecate(() => {}, dedent` \`${method}\` is deprecated, and will be removed in Storybook 7.0. ${warningAlternatives[method]} Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).`); const warnings = { addDecorator: warningMessage('addDecorator'), addParameters: warningMessage('addParameters'), addLoaders: warningMessage('addLoaders') }; const checkMethod = (method, deprecationWarning) => { var _global$FEATURES; if ((_global$FEATURES = global.FEATURES) !== null && _global$FEATURES !== void 0 && _global$FEATURES.storyStoreV7) { throw new Error(dedent`You cannot use \`${method}\` with the new Story Store. ${warningAlternatives[method]}`); } if (!singleton) { throw new Error(`Singleton client API not yet initialized, cannot call \`${method}\`.`); } if (deprecationWarning) { warnings[method](); } }; export const addDecorator = (decorator, deprecationWarning = true) => { checkMethod('addDecorator', deprecationWarning); singleton.addDecorator(decorator); }; export const addParameters = (parameters, deprecationWarning = true) => { checkMethod('addParameters', deprecationWarning); singleton.addParameters(parameters); }; export const addLoader = (loader, deprecationWarning = true) => { checkMethod('addLoader', deprecationWarning); singleton.addLoader(loader); }; export const addArgs = args => { checkMethod('addArgs', false); singleton.addArgs(args); }; export const addArgTypes = argTypes => { checkMethod('addArgTypes', false); singleton.addArgTypes(argTypes); }; export const addArgsEnhancer = enhancer => { checkMethod('addArgsEnhancer', false); singleton.addArgsEnhancer(enhancer); }; export const addArgTypesEnhancer = enhancer => { checkMethod('addArgTypesEnhancer', false); singleton.addArgTypesEnhancer(enhancer); }; export const getGlobalRender = () => { checkMethod('getGlobalRender', false); return singleton.facade.projectAnnotations.render; }; export const setGlobalRender = render => { checkMethod('setGlobalRender', false); singleton.facade.projectAnnotations.render = render; }; const invalidStoryTypes = new Set(['string', 'number', 'boolean', 'symbol']); export class ClientApi { // If we don't get passed modules so don't know filenames, we can // just use numeric indexes constructor({ storyStore } = {}) { this.facade = void 0; this.storyStore = void 0; this.addons = void 0; this.onImportFnChanged = void 0; this.lastFileName = 0; this.setAddon = deprecate(addon => { this.addons = Object.assign({}, this.addons, addon); }, dedent` \`setAddon\` is deprecated and will be removed in Storybook 7.0. https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-setaddon `); this.addDecorator = decorator => { this.facade.projectAnnotations.decorators.push(decorator); }; this.clearDecorators = deprecate(() => { this.facade.projectAnnotations.decorators = []; }, dedent` \`clearDecorators\` is deprecated and will be removed in Storybook 7.0. https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-cleardecorators `); this.addParameters = _ref => { let { globals, globalTypes } = _ref, parameters = _objectWithoutPropertiesLoose(_ref, _excluded); this.facade.projectAnnotations.parameters = combineParameters(this.facade.projectAnnotations.parameters, parameters); if (globals) { this.facade.projectAnnotations.globals = Object.assign({}, this.facade.projectAnnotations.globals, globals); } if (globalTypes) { this.facade.projectAnnotations.globalTypes = Object.assign({}, this.facade.projectAnnotations.globalTypes, normalizeInputTypes(globalTypes)); } }; this.addLoader = loader => { this.facade.projectAnnotations.loaders.push(loader); }; this.addArgs = args => { this.facade.projectAnnotations.args = Object.assign({}, this.facade.projectAnnotations.args, args); }; this.addArgTypes = argTypes => { this.facade.projectAnnotations.argTypes = Object.assign({}, this.facade.projectAnnotations.argTypes, normalizeInputTypes(argTypes)); }; this.addArgsEnhancer = enhancer => { this.facade.projectAnnotations.argsEnhancers.push(enhancer); }; this.addArgTypesEnhancer = enhancer => { this.facade.projectAnnotations.argTypesEnhancers.push(enhancer); }; this.storiesOf = (kind, m) => { if (!kind && typeof kind !== 'string') { throw new Error('Invalid or missing kind provided for stories, should be a string'); } if (!m) { logger.warn(`Missing 'module' parameter for story with a kind of '${kind}'. It will break your HMR`); } if (m) { const proto = Object.getPrototypeOf(m); if (proto.exports && proto.exports.default) { // FIXME: throw an error in SB6.0 logger.error(`Illegal mix of CSF default export and storiesOf calls in a single file: ${proto.i}`); } } // eslint-disable-next-line no-plusplus const baseFilename = m && m.id ? `${m.id}` : (this.lastFileName++).toString(); let fileName = baseFilename; let i = 1; // Deal with `storiesOf()` being called twice in the same file. // On HMR, `this.csfExports[fileName]` will be reset to `{}`, so an empty object is due // to this export, not a second call of `storiesOf()`. while (this.facade.csfExports[fileName] && Object.keys(this.facade.csfExports[fileName]).length > 0) { i += 1; fileName = `${baseFilename}-${i}`; } if (m && m.hot && m.hot.accept) { // This module used storiesOf(), so when it re-runs on HMR, it will reload // itself automatically without us needing to look at our imports m.hot.accept(); m.hot.dispose(() => { this.facade.clearFilenameExports(fileName); // We need to update the importFn as soon as the module re-evaluates // (and calls storiesOf() again, etc). We could call `onImportFnChanged()` // at the end of every setStories call (somehow), but then we'd need to // debounce it somehow for initial startup. Instead, we'll take advantage of // the fact that the evaluation of the module happens immediately in the same tick setTimeout(() => { var _this$onImportFnChang; (_this$onImportFnChang = this.onImportFnChanged) === null || _this$onImportFnChang === void 0 ? void 0 : _this$onImportFnChang.call(this, { importFn: this.importFn.bind(this) }); }, 0); }); } let hasAdded = false; const api = { kind: kind.toString(), add: () => api, addDecorator: () => api, addLoader: () => api, addParameters: () => api }; // apply addons Object.keys(this.addons).forEach(name => { const addon = this.addons[name]; api[name] = (...args) => { addon.apply(api, args); return api; }; }); const meta = { id: sanitize(kind), title: kind, decorators: [], loaders: [], parameters: {} }; // We map these back to a simple default export, even though we have type guarantees at this point this.facade.csfExports[fileName] = { default: meta }; let counter = 0; api.add = (storyName, storyFn, parameters = {}) => { hasAdded = true; if (typeof storyName !== 'string') { throw new Error(`Invalid or missing storyName provided for a "${kind}" story.`); } if (!storyFn || Array.isArray(storyFn) || invalidStoryTypes.has(typeof storyFn)) { throw new Error(`Cannot load story "${storyName}" in "${kind}" due to invalid format. Storybook expected a function/object but received ${typeof storyFn} instead.`); } const { decorators, loaders, component, args, argTypes } = parameters, storyParameters = _objectWithoutPropertiesLoose(parameters, _excluded2); // eslint-disable-next-line no-underscore-dangle const storyId = parameters.__id || toId(kind, storyName); const csfExports = this.facade.csfExports[fileName]; // Whack a _ on the front incase it is "default" csfExports[`story${counter}`] = { name: storyName, parameters: Object.assign({ fileName, __id: storyId }, storyParameters), decorators, loaders, args, argTypes, component, render: storyFn }; counter += 1; this.facade.stories[storyId] = { id: storyId, title: csfExports.default.title, name: storyName, importPath: fileName }; return api; }; api.addDecorator = decorator => { if (hasAdded) throw new Error(`You cannot add a decorator after the first story for a kind. Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.md#can-no-longer-add-decoratorsparameters-after-stories`); meta.decorators.push(decorator); return api; }; api.addLoader = loader => { if (hasAdded) throw new Error(`You cannot add a loader after the first story for a kind.`); meta.loaders.push(loader); return api; }; api.addParameters = _ref2 => { let { component, args, argTypes } = _ref2, parameters = _objectWithoutPropertiesLoose(_ref2, _excluded3); if (hasAdded) throw new Error(`You cannot add parameters after the first story for a kind. Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.md#can-no-longer-add-decoratorsparameters-after-stories`); meta.parameters = combineParameters(meta.parameters, parameters); if (component) meta.component = component; if (args) meta.args = Object.assign({}, meta.args, args); if (argTypes) meta.argTypes = Object.assign({}, meta.argTypes, argTypes); return api; }; return api; }; this.getStorybook = () => { const { stories } = this.storyStore.storyIndex; const kinds = {}; Object.entries(stories).forEach(([storyId, { title, name, importPath }]) => { if (!kinds[title]) { kinds[title] = { kind: title, fileName: importPath, stories: [] }; } const { storyFn } = this.storyStore.fromId(storyId); kinds[title].stories.push({ name, render: storyFn }); }); return Object.values(kinds); }; this.raw = () => { return this.storyStore.raw(); }; this.facade = new StoryStoreFacade(); this.addons = {}; this.storyStore = storyStore; singleton = this; } importFn(path) { return this.facade.importFn(path); } getStoryIndex() { if (!this.storyStore) { throw new Error('Cannot get story index before setting storyStore'); } return this.facade.getStoryIndex(this.storyStore); } // @deprecated get _storyStore() { return this.storyStore; } }