Skip to content

Commit

Permalink
add storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-burel committed Apr 19, 2019
1 parent 81a333b commit 87502ed
Show file tree
Hide file tree
Showing 17 changed files with 16,878 additions and 5,804 deletions.
20 changes: 10 additions & 10 deletions .meteor/versions
@@ -1,7 +1,7 @@
accounts-base@1.4.3
accounts-password@1.5.1
allow-deny@1.1.0
apollo@3.0.0
apollo@3.0.1
autoupdate@1.5.0
babel-compiler@7.2.1
babel-runtime@1.3.0
Expand Down Expand Up @@ -38,6 +38,7 @@ htmljs@1.0.11
http@1.4.1
id-map@1.1.0
inter-process-messaging@0.1.0
littledata:synced-cron@1.5.0
lmieulet:meteor-coverage@2.0.2
localstorage@1.2.0
logging@1.1.20
Expand All @@ -60,7 +61,6 @@ mongo-id@1.0.7
npm-bcrypt@0.9.3
npm-mongo@3.1.1
ordered-dict@1.1.0
littledata:synced-cron@1.3.1
promise@0.11.1
random@1.1.0
rate-limit@1.0.9
Expand All @@ -82,13 +82,13 @@ templating-tools@1.1.2
tracker@1.2.0
underscore@1.0.10
url@1.2.0
vulcan:core@1.12.8
vulcan:debug@1.12.8
vulcan:email@1.12.8
vulcan:i18n@1.12.8
vulcan:i18n-en-us@1.12.8
vulcan:lib@1.12.8
vulcan:routing@1.12.8
vulcan:users@1.12.8
vulcan:core@1.13.0
vulcan:debug@1.13.0
vulcan:email@1.13.0
vulcan:i18n@1.13.0
vulcan:i18n-en-us@1.13.0
vulcan:lib@1.13.0
vulcan:routing@1.13.0
vulcan:users@1.13.0
webapp@1.7.0
webapp-hashing@1.0.9
1 change: 1 addition & 0 deletions .meteorignore
@@ -0,0 +1 @@
stories
4 changes: 4 additions & 0 deletions .storybook/addons.js
@@ -0,0 +1,4 @@
// Init storybook addons here
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import 'storybook-addon-intl/register';
75 changes: 75 additions & 0 deletions .storybook/config.js
@@ -0,0 +1,75 @@
/**
* Global configuration of the stories
*/
import { addDecorator, configure } from '@storybook/react';

// init UI using a Decorator
import BootstrapDecorator from './decorators/BootstrapDecorator'
addDecorator(BootstrapDecorator)
// Uncomment to activate material UI instead
//import MaterialUIDecorator from './decorators/MaterialUIDecorator'
//addDecorator(MaterialUIDecorator)

/*
Standard Config
*/
// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /.stories.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}

/*
React Router Config
See https://github.com/gvaldambrini/storybook-router/tree/master/packages/react
*/
import StoryRouter from 'storybook-react-router';
addDecorator(StoryRouter());

/*
Vulcan core Components
*/

import 'meteor/vulcan:core'

/*
i18n
See https://github.com/truffls/storybook-addon-intl
*/

import { setIntlConfig, withIntl } from 'storybook-addon-intl';
import { addLocaleData } from 'react-intl';
import { Strings, Locales } from './helpers.js';

const getMessages = locale => Strings[locale];

/*
En
*/
import enLocaleData from 'react-intl/locale-data/en';
addLocaleData(enLocaleData);
//import 'EnUS';

// Set intl configuration
setIntlConfig({
locales: Locales.map(locale => locale.id),
defaultLocale: 'en',
getMessages,
});

// Register decorator
addDecorator(withIntl);

// Run storybook
configure(loadStories, module);
13 changes: 13 additions & 0 deletions .storybook/decorators/BootstrapDecorator.js
@@ -0,0 +1,13 @@
/**
* Use this decorator to setup Bootstrap
*/
import React from 'react'

import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/bootstrap.min.css';
import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/style.scss';
import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/datetime.scss';

// load UI components
import 'meteor/vulcan:ui-bootstrap/lib/modules/components.js';

export default storyFn => (<div>{storyFn()}</div>)
10 changes: 10 additions & 0 deletions .storybook/decorators/MaterialUIDecorator.js
@@ -0,0 +1,10 @@
/*
Use this decorator to load Material UI
*/
// load UI components
import React from 'react'
import 'meteor/vulcan:ui-material/lib/modules/components.js';

export default storyFn => (<div>{storyFn()}</div>)
163 changes: 163 additions & 0 deletions .storybook/helpers.js
@@ -0,0 +1,163 @@
import merge from 'lodash/merge';

/*
Simplified versions of Vulcan APIs and helpers
*/

/*
Components
*/
export const Components = {}; // will be populated on startup (see vulcan:routing)

export const ComponentsMockProps = {};

export const getMockProps = (componentName, overrideProps) => {
return merge({}, ComponentsMockProps[componentName], overrideProps);
};

export function registerComponent(name, rawComponent, ...hocs) {
// support single-argument syntax
if (typeof arguments[0] === 'object') {
// note: cannot use `const` because name, components, hocs are already defined
// as arguments so destructuring cannot work
// eslint-disable-next-line no-redeclare
var { name, component, hocs = [] } = arguments[0];
rawComponent = component;
}
// store the component in the table
Components[name] = rawComponent
}

export const replaceComponent = registerComponent;

export const instantiateComponent = (component, props) => {
if (!component) {
return null;
} else if (typeof component === 'string') {
const Component = getComponent(component);
return <Component {...props} />;
} else if (
typeof component === 'function' &&
component.prototype &&
component.prototype.isReactComponent
) {
const Component = component;
return <Component {...props} />;
} else if (typeof component === 'function') {
return component(props);
} else {
return component;
}
};

export const coreComponents = [
'Alert',
'Button',
'Dropdown',
'Modal',
'ModalTrigger',
'Table',
'FormComponentCheckbox',
'FormComponentCheckboxGroup',
'FormComponentDate',
'FormComponentDate2',
'FormComponentDateTime',
'FormComponentDefault',
'FormComponentText',
'FormComponentEmail',
'FormComponentNumber',
'FormComponentRadioGroup',
'FormComponentSelect',
'FormComponentSelectMultiple',
'FormComponentStaticText',
'FormComponentTextarea',
'FormComponentTime',
'FormComponentUrl',
'FormControl',
'FormElement',
'FormItem',
];

/*
i18n
*/

export const Strings = {};

export const addStrings = (language, strings) => {
if (typeof Strings[language] === 'undefined') {
Strings[language] = {};
}
Strings[language] = {
...Strings[language],
...strings
};
};

export const Locales = [];

export const registerLocale = locale => {
Locales.push(locale);
};

/*
Users
*/

export const isAdmin = () => true;
export const getProfileUrl = (user, isAbsolute) => {
if (typeof user === 'undefined') {
return '';
}
isAbsolute = typeof isAbsolute === 'undefined' ? false : isAbsolute; // default to false
var prefix = isAbsolute ? Utils.getSiteUrl().slice(0, -1) : '';
if (user.slug) {
return `${prefix}/users/${user.slug}`;
} else {
return '';
}
};
export const getDisplayName = (user) => {
if (!user) {
return '';
} else {
return user.displayName ? user.displayName : Users.getUserName(user);
}
};
export const avatar = {
getUrl: user => 'https://api.adorable.io/avatars/285/abotaat@adorable.io.png',
getInitials: user => 'SG',
}
/*
Helpers
*/

export function capitalize(string) {
return string.replace(/\-/, ' ').split(' ').map(word => {
return word.charAt(0).toUpperCase() + word.slice(1);
}).join(' ');
}

/*
Other Exports
*/

export const getSetting = (name, defaultSetting) => defaultSetting;

export const track = () => {};
export const addCallback = () => {};

export const withCurrentUser = c => c;
export const withUpdate = c => c;
37 changes: 37 additions & 0 deletions .storybook/loaders/starter-example-loader.js
@@ -0,0 +1,37 @@
/**
*
* Load the local Vulcan packages, inspired by vulcan-loader
*
*/
const { getOptions } = require('loader-utils');
module.exports = function loader(source) {
const options = getOptions(this)

const { packagesDir, environment = 'client' } = options
// prefixing your packages name makes it easier to write a loader
const prefix = `${packagesDir}/example-`
const defaultPath = `/lib/${environment}/main.js`

const result = source.replace(
// This regex will match:
// meteor/example-{packageName}{some-optional-import-path}
//
// Example:
// meteor/example-forum => match, packageName="forum"
// meteor/example-forum/foobar.js => match, packageName="forum", importPath="/foobar.js"
// meteor/another-package => do not match
//
// Explanation:
// .+?(?=something) matches every char until "something" is met, excluding something
// we use it to matche the package name, until we meet a ' or "
/meteor\/example-(.*?(?=\/|'|"))(.*?(?=\'|\"))/g, // match Meteor packages that are lfg packages, + the import path (without the quotes)
(match, packageName, importPath) => {
console.log("Found Starter example package", packageName)
if (importPath){
return `${prefix}${packageName}${importPath}`
}
return `${prefix}${packageName}${defaultPath}`
}
)
return result
}
9 changes: 9 additions & 0 deletions .storybook/mocks/Meteor.js
@@ -0,0 +1,9 @@
// FIXME: we can't use ES6 imports in mocks, not sure why
module.exports = {
settings: {},
startup: () => { },
_localStorage: window ? window.localStorage : { setItem: () => {}, getItem: () => {} },
isClient: () => true,
isServer: () => false,
absoluteUrl: () => 'http://vulcanjs.org/'
}
3 changes: 3 additions & 0 deletions .storybook/mocks/Mongo.js
@@ -0,0 +1,3 @@
module.exports = {
Collection: class Collection {}
}
3 changes: 3 additions & 0 deletions .storybook/mocks/Vulcan.js
@@ -0,0 +1,3 @@
module.exports = {

}
3 changes: 3 additions & 0 deletions .storybook/mocks/meteor-apollo.js
@@ -0,0 +1,3 @@
module.exports = {
MeteorAccountsLink: class MeteorAccountsLink {}
}
3 changes: 3 additions & 0 deletions .storybook/mocks/vulcan-email.js
@@ -0,0 +1,3 @@
module.exports = {
addEmails: () => {}
}

0 comments on commit 87502ed

Please sign in to comment.