├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .github
└── workflows
│ └── codacy-analysis.yml
├── .gitignore
├── .npmignore
├── .scripts
├── deployer
│ ├── index.js
│ └── utils.js
├── lint.js
├── npm-postpublish.js
├── npm-prepare.js
├── npm-status.js
├── run_tests
│ ├── index.js
│ └── mocha_runner.js
├── ver.js
└── watch.js
├── .storybook
├── .themes
│ ├── customTheme1.js
│ ├── customTheme2.js
│ ├── customTheme3.js
│ ├── customTheme4.js
│ └── customTheme5.js
├── addons.js
├── config.js
└── stories.js
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── docs
├── WatchMe.gif
├── logos
│ ├── Storybook.png
│ └── material-ui.png
├── screen1.png
├── screen2.png
├── screen3.png
├── screen4.png
├── screen5.png
├── screen6.png
└── screenshorts.md
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── register.js
├── src
├── .themes
│ └── index.js
├── UI
│ ├── AddonPanel.js
│ ├── FullTheme.js
│ ├── MuiDecorator.js
│ ├── Overridings.js
│ └── Palette.js
├── Utils
│ ├── index.js
│ ├── svg_package.js
│ ├── uiTheme.js
│ └── ui_package.jsx
├── adk
│ ├── ChannelHOC.js
│ ├── ChannelStore.js
│ ├── WithChannel.js
│ ├── decorator.js
│ └── panel.js
├── components
│ ├── AddonPanel.jsx
│ ├── ThemePropBlock.jsx
│ ├── ThemePropItem.jsx
│ └── ThemeSideBar.jsx
├── config.js
├── containers
│ ├── MuiTheme.jsx
│ └── PanelContainer.jsx
├── index.js
├── material-desktop
│ ├── SclAvatar.jsx
│ ├── SclToggle.jsx
│ ├── SvgButton.jsx
│ └── SvgIcon.jsx
├── muiTheme.js
├── preset.js
└── register.js
├── storybook-addon-material-ui.d.ts
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-react"],
3 | "plugins": ["@babel/plugin-proposal-class-properties"]
4 | }
5 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | *.d.ts
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const error = 2;
2 | const warn = 1;
3 | const ignore = 0;
4 |
5 | module.exports = {
6 | root: true,
7 | extends: ['eslint-config-airbnb', 'plugin:jest/recommended', 'prettier'],
8 | plugins: ['prettier', 'jest', 'json'],
9 | parser: 'babel-eslint',
10 | parserOptions: {
11 | sourceType: 'module'
12 | },
13 | env: {
14 | es6: true,
15 | node: true,
16 | 'jest/globals': true
17 | },
18 | rules: {
19 | // "prettier/prettier": error,
20 | 'no-console': ignore,
21 | 'react/jsx-filename-extension': ignore,
22 | 'react/destructuring-assignment': ignore,
23 | 'import/prefer-default-export': ignore,
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/.github/workflows/codacy-analysis.yml:
--------------------------------------------------------------------------------
1 | # This workflow checks out code, performs a Codacy security scan
2 | # and integrates the results with the
3 | # GitHub Advanced Security code scanning feature. For more information on
4 | # the Codacy security scan action usage and parameters, see
5 | # https://github.com/codacy/codacy-analysis-cli-action.
6 | # For more information on Codacy Analysis CLI in general, see
7 | # https://github.com/codacy/codacy-analysis-cli.
8 |
9 | name: Codacy Security Scan
10 |
11 | on:
12 | push:
13 | branches: [ version-1 ]
14 | pull_request:
15 | branches: [ version-1 ]
16 |
17 | jobs:
18 | codacy-security-scan:
19 | name: Codacy Security Scan
20 | runs-on: ubuntu-latest
21 | steps:
22 | # Checkout the repository to the GitHub Actions runner
23 | - name: Checkout code
24 | uses: actions/checkout@v2
25 |
26 | # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
27 | - name: Run Codacy Analysis CLI
28 | uses: codacy/codacy-analysis-cli-action@1.1.0
29 | with:
30 | # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
31 | # You can also omit the token and run the tools that support default configurations
32 | project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
33 | verbose: true
34 | output: results.sarif
35 | format: sarif
36 | # Adjust severity of non-security issues
37 | gh-code-scanning-compat: true
38 | # Force 0 exit code to allow SARIF file generation
39 | # This will handover control about PR rejection to the GitHub side
40 | max-allowed-issues: 50
41 |
42 | # Upload the SARIF file generated in the previous step
43 | - name: Upload SARIF results file
44 | uses: github/codeql-action/upload-sarif@v1
45 | with:
46 | sarif_file: results.sarif
47 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .idea
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
24 | /dist
25 |
26 | .vscode/settings.json
27 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | develop
3 | example
4 | src
5 | docs
6 | .babelrc
7 | .eslintrc
8 | .scripts
9 | .storybook
10 |
--------------------------------------------------------------------------------
/.scripts/deployer/index.js:
--------------------------------------------------------------------------------
1 | var shell = require('shelljs');
2 | var chalk = require('chalk');
3 | var publishUtils = require('./utils');
4 | var path = require('path');
5 | var packageJson = require(path.resolve('./package.json'));
6 |
7 | var OUTPUT_DIR = 'out' + Math.ceil(Math.random() * 9999);
8 |
9 | shell.echo(chalk.bold(`${packageJson.name}@${packageJson.version}\n`));
10 |
11 | // get GIT url
12 | console.log(chalk.grey('=> Getting the git remote URL'));
13 | var GIT_URL = publishUtils.exec('git config --get remote.origin.url');
14 | if (!GIT_URL) {
15 | console.log('This project is not configured with a remote git repo');
16 | process.exit(-1);
17 | }
18 |
19 | // clear and re-create the out directory
20 | shell.rm('-rf', OUTPUT_DIR);
21 | shell.mkdir(OUTPUT_DIR);
22 |
23 | // run our compile script
24 | console.log(chalk.grey('=> Building storybook'));
25 | if (packageJson.scripts['build-storybook']) {
26 | publishUtils.exec('npm run build-storybook -- -o ' + OUTPUT_DIR);
27 | } else {
28 | publishUtils.exec('build-storybook -o ' + OUTPUT_DIR);
29 | }
30 |
31 | // go to the out directory and create a *new* Git repo
32 | shell.cd(OUTPUT_DIR);
33 | publishUtils.exec('git init');
34 |
35 | // inside this git repo we'll pretend to be a new user
36 | publishUtils.exec('git config user.name "GH Pages Bot"');
37 | publishUtils.exec('git config user.email "hello@ghbot.com"');
38 |
39 | // The first and only commit to this new Git repo contains all the
40 | // files present with the commit message "Deploy to GitHub Pages".
41 | publishUtils.exec('git add .');
42 | publishUtils.exec('git commit -m "Deploy Storybook to GitHub Pages"');
43 |
44 | // Force push from the current repo's master branch to the remote
45 | // repo's gh-pages branch. (All previous history on the gh-pages branch
46 | // will be lost, since we are overwriting it.) We redirect any output to
47 | // /dev/null to hide any sensitive credential data that might otherwise be exposed.
48 | console.log(chalk.grey('=> Deploying storybook'));
49 | publishUtils.exec('git push --force --quiet ' + GIT_URL + ' master:gh-pages')
50 | shell.cd('..');
51 | shell.rm('-rf', OUTPUT_DIR);
52 |
53 | console.log();
54 | console.log(chalk.grey('=> Storybook deployed to: ') +
55 | chalk.cyan(publishUtils.getGHPagesUrl(GIT_URL)));
56 |
--------------------------------------------------------------------------------
/.scripts/deployer/utils.js:
--------------------------------------------------------------------------------
1 | var shell = require('shelljs');
2 | var chalk = require('chalk');
3 | var parseGitUrl = require('git-url-parse');
4 |
5 | module.exports.exec = function exec(command) {
6 | shell.echo(chalk.grey(" executing: ") + command);
7 | const options = { silent: true };
8 | const ref = shell.exec(command, options);
9 | if (ref.code === 0) {
10 | return ref.stdout.trim();
11 | }
12 |
13 | const message =
14 | 'Exec code(' + ref.code + ') on executing: ' + command + '\n' +
15 | shell.stderr;
16 |
17 | throw new Error(message);
18 | };
19 |
20 | module.exports.getGHPagesUrl = function getGHPagesUrl(ghUrl) {
21 | var parsedUrl = parseGitUrl(ghUrl);
22 | var ghPagesUrl = 'https://' + parsedUrl.owner + '.github.io/' + parsedUrl.name + '/';
23 | return ghPagesUrl;
24 | };
25 |
--------------------------------------------------------------------------------
/.scripts/lint.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const shell = require('shelljs');
3 | const chalk = require('chalk');
4 |
5 |
6 | const isJSON = process.argv.includes('-f') && process.argv.includes('json');
7 | const out = isJSON ? ['-o .scripts/lintresult.json'] : [];
8 |
9 | const lint = ['node_modules', '.bin', 'eslint'].join(path.sep);
10 | const args = [
11 | 'src',
12 | '--ext .jsx,.js',
13 | '--color',
14 | ...process.argv.slice(2),
15 | ...out,
16 | ].join(' ');
17 | const cmd = `${lint} ${args}`;
18 |
19 | if(isJSON) {
20 | shell.echo('\nESLint:');
21 | } else {
22 | require('./ver');
23 | }
24 | shell.echo(chalk.gray(cmd));
25 | shell.exec(cmd);
26 |
27 | if(isJSON) {
28 | shell.echo('');
29 | const lintresult = require('./lintresult.json');
30 | lintresult.forEach( val => {
31 | const err = val.errorCount;
32 | const war = val.warningCount;
33 | const fpath = path.relative(process.cwd(), val.filePath);
34 | if (err || war) {
35 | shell.echo(`${chalk.grey(fpath)} ${err ? chalk.red(`errors: ${err}` + (war ? ', ' : '')) : ''}${war ? chalk.yellow(`warnings: ${war}`) : ''}`);
36 |
37 |
38 | }
39 | })
40 | shell.rm('.scripts/lintresult.json');
41 | }
42 |
--------------------------------------------------------------------------------
/.scripts/npm-postpublish.js:
--------------------------------------------------------------------------------
1 | var shell = require('shelljs');
2 | var chalk = require('chalk');
3 | const packageJson = require('../package.json');
4 |
5 | shell.echo(chalk.grey(`${packageJson.name}@${packageJson.version} was successfully published.`));
6 |
--------------------------------------------------------------------------------
/.scripts/npm-prepare.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var shell = require('shelljs');
3 | var chalk = require('chalk');
4 | var babel = ['node_modules', '.bin', 'babel'].join(path.sep);
5 |
6 | require('./ver');
7 |
8 |
9 | const args = '--ignore tests,stories,story.jsx,story.js src --out-dir dist --verbose';
10 | const cmd = `${babel} ${args}`;
11 | shell.echo(chalk.gray(cmd));
12 | shell.rm('-rf', 'dist');
13 |
14 | shell.echo('');
15 | shell.echo(chalk.gray('Transpiling \'src\' into ES5 ...'));
16 | shell.exec(cmd);
17 | shell.echo(chalk.gray('Transpiling completed.'));
18 | shell.echo('');
19 |
--------------------------------------------------------------------------------
/.scripts/npm-status.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var shell = require('shelljs');
3 | var chalk = require('chalk');
4 | var semver = require('semver');
5 | var dateFormat = require('dateformat');
6 | const packageJson = require('../package.json');
7 |
8 | const ref = shell.exec('npm view --json', { silent: true });
9 | if (ref.code === 0) {
10 | const data = JSON.parse(ref.stdout);
11 | const lastVersion = data.version;
12 | const lastName = data.name;
13 | const lastPublish = data.time[lastVersion];
14 | const maintainers = data.maintainers.reduce((str, val) => `${str}, ${val}` );
15 |
16 | if (lastVersion === packageJson.version) {
17 | shell.echo(chalk.bold(`\n${packageJson.name}@${packageJson.version}`));
18 | shell.echo(chalk.grey('was published to NPM at ' + dateFormat(lastPublish, 'dd-mmm-yyyy, HH:MM')));
19 |
20 | } else {
21 | const diff = semver.diff(lastVersion, packageJson.version);
22 | const verColor = diff.match(/major/) ? 'red' : diff.match(/minor/) ? 'yellow' : 'bold';
23 |
24 | shell.echo(chalk.grey('\nthe current version: ') + chalk.white(`${packageJson.name}`) + chalk[verColor](`@${packageJson.version}`));
25 | shell.echo(chalk.grey('the latest published version: ') + chalk.white(`${lastName}@${lastVersion}`));
26 | shell.echo(
27 | chalk.grey('was published to NPM at ') +
28 | chalk.white(dateFormat(lastPublish, 'dd-mmm-yyyy, HH:MM')) +
29 | chalk.grey(` by ${maintainers}`)
30 | );
31 | }
32 | } else {
33 | if ( ref.stderr.match('npm ERR! code E404')) {
34 | shell.echo(chalk.bold(`\n${packageJson.name}@${packageJson.version}`));
35 | shell.echo(chalk.grey('wasn\'t published to NPM yet'));
36 | } else {
37 | console.log(ref.stderr);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/.scripts/run_tests/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const shell = require('shelljs');
3 | const chalk = require('chalk');
4 |
5 | const isMin = process.argv.includes('-R') && process.argv.includes('min');
6 | const mocha = ['node_modules', '.bin', 'mocha'].join(path.sep);
7 |
8 | const args = [
9 | '--require .scripts/run_tests/mocha_runner',
10 | 'src/**/tests/**/*.js',
11 | '--colors',
12 | ...process.argv.slice(2),
13 | ].join(' ');
14 |
15 | const cmd = `${mocha} ${args}`;
16 |
17 | shell.echo(`${isMin ? '\nMocha:\n' : ''}${chalk.grey(cmd)}`);
18 | shell.exec(cmd);
19 |
--------------------------------------------------------------------------------
/.scripts/run_tests/mocha_runner.js:
--------------------------------------------------------------------------------
1 | // This is an auto generated file with React CDK.
2 |
3 | require('babel-core/register');
4 | require('babel-polyfill');
5 |
6 | // pass images
7 | require.extensions['.svg'] = function(){ return null; }
8 | require.extensions['.png'] = function(){ return null; }
9 | require.extensions['.gif'] = function(){ return null; }
10 | require.extensions['.jpg'] = function(){ return null; }
11 |
12 |
13 | var packageJson = require('../../package.json');
14 |
15 | // Add jsdom support, which is required for enzyme.
16 | var jsdom = require('jsdom').jsdom;
17 |
18 | var exposedProperties = ['window', 'navigator', 'document'];
19 |
20 | global.document = jsdom('');
21 | global.window = document.defaultView;
22 | Object.keys(document.defaultView).forEach((property) => {
23 | if (typeof global[property] === 'undefined') {
24 | exposedProperties.push(property);
25 | global[property] = document.defaultView[property];
26 | }
27 | });
28 |
29 | global.navigator = {
30 | userAgent: 'node.js'
31 | };
32 |
33 | // Add packageJson to have it accessible from any folder
34 | global.packageJson = packageJson;
35 |
36 | process.on('unhandledRejection', function (error) {
37 | console.error('Unhandled Promise Rejection:');
38 | console.error(error && error.stack || error);
39 | });
40 |
41 |
--------------------------------------------------------------------------------
/.scripts/ver.js:
--------------------------------------------------------------------------------
1 | const shell = require('shelljs');
2 | const chalk = require('chalk');
3 | const packageJson = require('../package.json');
4 |
5 | shell.echo(chalk.bold(`${packageJson.name}@${packageJson.version}`));
6 |
--------------------------------------------------------------------------------
/.scripts/watch.js:
--------------------------------------------------------------------------------
1 | const shell = require('shelljs');
2 | const chalk = require('chalk');
3 |
4 | shell.exec('nodemon src -e js,jsx,json --exec "npm run status"');
5 |
--------------------------------------------------------------------------------
/.storybook/.themes/customTheme1.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import green from '@material-ui/core/colors/green';
3 | import purple from '@material-ui/core/colors/purple';
4 | import blue from '@material-ui/core/colors/blue';
5 | import red from '@material-ui/core/colors/red';
6 | import yellow from '@material-ui/core/colors/yellow';
7 |
8 | const primaryGreen = green[500];
9 | const accentGreen = green.A200;
10 | const darkGreen = green[900];
11 | const primaryPurple = purple[500];
12 | const accentPurple = purple.A200;
13 | const darkPurple = purple[900];
14 |
15 | export const overridings = {
16 | palette: {
17 | primary: {
18 | light: accentGreen,
19 | main: primaryGreen,
20 | dark: darkGreen,
21 | contrastText: '#fff'
22 | },
23 | secondary: {
24 | light: accentPurple,
25 | main: primaryPurple,
26 | dark: darkPurple,
27 | contrastText: '#fff'
28 | }
29 | },
30 | themeName: 'Custom Light Theme'
31 | };
32 |
33 | export default createMuiTheme(overridings);
34 |
--------------------------------------------------------------------------------
/.storybook/.themes/customTheme2.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import green from '@material-ui/core/colors/green';
3 | import purple from '@material-ui/core/colors/purple';
4 |
5 | const primaryGreen = green[500];
6 | const accentGreen = green.A200;
7 | const darkGreen = green[900];
8 | const primaryPurple = purple[500];
9 | const accentPurple = purple.A200;
10 | const darkPurple = purple[900];
11 |
12 | export const overridings = {
13 | palette: {
14 | primary: {
15 | light: accentPurple,
16 | main: primaryPurple,
17 | dark: darkPurple,
18 | contrastText: '#fff'
19 | },
20 | type: 'dark',
21 | secondary: {
22 | light: accentGreen,
23 | main: primaryGreen,
24 | dark: darkGreen,
25 | contrastText: '#fff'
26 | }
27 | },
28 | themeName: 'Custom Dark Theme'
29 | };
30 |
31 | export default createMuiTheme(overridings);
32 |
--------------------------------------------------------------------------------
/.storybook/.themes/customTheme3.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import green from '@material-ui/core/colors/green';
3 | import purple from '@material-ui/core/colors/purple';
4 | import blue from '@material-ui/core/colors/blue';
5 |
6 | const darkGreen = green[900];
7 | const accentPurple = purple.A200;
8 | const darkPurple = purple[900];
9 |
10 | export const overridings = {
11 | palette: {
12 | primary: {
13 | light: accentPurple,
14 | main: blue[200],
15 | dark: darkPurple,
16 | },
17 | secondary: {
18 | main: darkGreen,
19 | },
20 | type: 'dark'
21 | },
22 | themeName: 'Pale Blue Theme'
23 | };
24 |
25 | export default createMuiTheme(overridings);
26 |
--------------------------------------------------------------------------------
/.storybook/.themes/customTheme4.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import red from '@material-ui/core/colors/red';
3 | import yellow from '@material-ui/core/colors/yellow';
4 |
5 |
6 | export const overridings = {
7 | palette: {
8 | primary: {
9 | main: yellow[500],
10 | contrastText: '#000'
11 | },
12 | secondary: {
13 | main: red[500],
14 | contrastText: '#fff'
15 | },
16 | type: 'dark'
17 | },
18 | themeName: 'Yellow and Red Theme'
19 | };
20 |
21 | export default createMuiTheme(overridings);
22 |
--------------------------------------------------------------------------------
/.storybook/.themes/customTheme5.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import blue from '@material-ui/core/colors/blue';
3 | import yellow from '@material-ui/core/colors/yellow';
4 |
5 |
6 | export const overridings = {
7 | palette: {
8 | primary: {
9 | main: yellow[500],
10 | contrastText: '#000'
11 | },
12 | secondary: {
13 | main: blue[500],
14 | contrastText: '#fff'
15 | },
16 | type: 'dark'
17 | },
18 | themeName: 'Yellow and Blue Theme'
19 | };
20 |
21 | export default createMuiTheme(overridings);
22 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '../src/register';
2 | import '@storybook/addon-actions/register';
3 | import '@storybook/addon-links/register';
4 | import '@storybook/addon-backgrounds/register';
5 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */
2 |
3 | import { configure } from '@storybook/react';
4 |
5 | function loadStories() {
6 | require('./stories');
7 | }
8 |
9 | configure(loadStories, module);
10 |
--------------------------------------------------------------------------------
/.storybook/stories.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { storiesOf } from '@storybook/react';
4 |
5 | import Button from '@material-ui/core/Button';
6 |
7 | import { muiTheme } from '../src';
8 |
9 | import { overridings as theme1 } from './.themes/customTheme1';
10 | import { overridings as theme2 } from './.themes/customTheme2';
11 | import themeF3, { overridings as theme3 } from './.themes/customTheme3';
12 | import { overridings as theme4 } from './.themes/customTheme4';
13 | import { overridings as theme5 } from './.themes/customTheme5';
14 |
15 | const buttonStyle = {
16 | margin: 16
17 | };
18 |
19 | storiesOf('Material Custom theme', module)
20 | .addParameters({
21 | backgrounds: [
22 | { name: 'init', value: '#FFFFFF' },
23 | { name: 'twitter', value: '#00aced' },
24 | { name: 'facebook', value: '#3b5998' }
25 | ]
26 | })
27 | .addDecorator(muiTheme([theme1, theme2, theme3, theme4, theme5]))
28 | .add('Raised buttons', () => (
29 |
30 |
31 | Raised primary
32 |
33 |
34 | Raised secondary
35 |
36 |
37 | Raised default
38 |
39 |
40 | ))
41 | .add('Outlined buttons', () => (
42 |
43 |
44 | Outlined primary
45 |
46 |
47 | Outlined secondary
48 |
49 |
50 | Outlined default
51 |
52 |
53 | ))
54 | .add('Flat buttons', () => (
55 |
56 |
57 | Flat primary
58 |
59 |
60 | Flat secondary
61 |
62 |
63 | Flat default
64 |
65 |
66 | ));
67 |
68 | storiesOf('Clone Custom theme', module)
69 | // .addDecorator(muiTheme([theme4, theme5]))
70 | .add(' Raised buttons', () => (
71 |
72 |
73 | Raised primary
74 |
75 |
76 | Raised secondary
77 |
78 |
79 | Raised default
80 |
81 |
82 | ));
83 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at welcome@sm-artlight.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Oleg Proskurin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.codacy.com/gh/react-theming/storybook-addon-material-ui?utm_source=github.com&utm_medium=referral&utm_content=react-theming/storybook-addon-material-ui&utm_campaign=Badge_Grade)
2 | [](https://badge.fury.io/js/storybook-addon-material-ui)
3 | [](https://sm-react.github.io/storybook-boilerplate/?theme-ind=0&theme-sidebar=false&theme-full=false&knob-Title=Welcome%20to%20React-Theming&knob-Subtitle=Storybook%20Boilerplate%20Project&knob-Label1=Hello%20Button&knob-Label2=Hello%20Button&selectedKind=Material-UI&selectedStory=Components&full=0&down=1&left=1&panelRight=0&downPanel=sm%2Fstorybook-addon-material-ui%2Fmaterial-panel)
4 |
5 | # Storybook Addon Material-UI
6 |
7 |
8 | [ ](https://storybooks.js.org/docs/react-storybook/addons/addon-gallery/)
9 | [ ](https://material-ui.com/styles/advanced/#theming)
10 |
11 | Provides development environment which helps creating [Material-UI Components](http://www.material-ui.com/). This is addon for [React Storybook](https://github.com/storybooks/react-storybook) which wraps your components into MuiThemeProvider. This accelerates and simplifies the [development](#getting-started-bookmark_tabs) process for Material-UI based applications.
12 |
13 | You can use this [project's demo page](https://sm-react.github.io/storybook-boilerplate/?theme-ind=0&theme-sidebar=false&theme-full=false&knob-Title=Welcome%20to%20React-Theming&knob-Subtitle=Storybook%20Boilerplate%20Project&knob-Label1=Hello%20Button&knob-Label2=Hello%20Button&selectedKind=Material-UI&selectedStory=Components&full=0&down=1&left=1&panelRight=0&downPanel=sm%2Fstorybook-addon-material-ui%2Fmaterial-panel) to discover `Material-UI Theme Settings` for any component and create your `own new themes` right online. But to take [full advantage](#features-dizzy) of this project [run it locally](#quick-start) in your work environment.
14 |
15 | [](https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/master/docs/WatchMe.gif)
16 |
17 |
18 | ## Features
19 |
20 | [](https://sm-react.github.io/storybook-boilerplate/?theme-ind=0&theme-sidebar=false&theme-full=false&knob-Title=Welcome%20to%20React-Theming&knob-Subtitle=Storybook%20Boilerplate%20Project&knob-Label1=Hello%20Button&knob-Label2=Hello%20Button&selectedKind=Material-UI&selectedStory=Components&full=0&down=1&left=1&panelRight=0&downPanel=sm%2Fstorybook-addon-material-ui%2Fmaterial-panel)
21 |
22 | - Wrapped in the theme provider. Just start to develop with base light theme.
23 | - Injected TapEvent Plugin. Test on mobile devices.
24 | - Switching themes. See how it looks in one click.
25 | - Creating your custom theme. By code or in visual editor.
26 | - Dynamic visual themes editing. Discover the all avalibale theme properties.
27 | - Google [material color](https://material.google.com/style/color.html#color-color-palette) palette [picker](https://github.com/sm-react/react-material-color-picker)
28 | - Save made changes and download in JSON file
29 | - Part of [React Theming](https://github.com/react-theming/react-theming). Create themable React Components.
30 | - Works with Storybook 3.0
31 |
32 | ## Quick Start
33 |
34 | In order to quick start with the latest `storybook-addon-material-ui` you can check out [create-material-ui-app](https://github.com/react-theming/create-material-ui-app)
35 |
36 | It contains the working setup with:
37 |
38 | - create-react-app
39 | - Storybook
40 | - Material-UI
41 | - storybook-addon-material-ui
42 |
43 | ---
44 |
45 | ## Getting Started
46 |
47 | First, install the addon
48 |
49 | ```shell
50 | npm i storybook-addon-material-ui --save-dev
51 | ```
52 |
53 | ### Storybook 6.1
54 |
55 | Add `storybook-addon-material-ui` to the storybook addons:
56 |
57 | ```js
58 | //.storybook/main.js
59 |
60 | module.exports = {
61 | stories: ['../stories/**/*.stories.(js|mdx)'],
62 | addons: [
63 | 'storybook-addon-material-ui'
64 | ],
65 | };
66 | ```
67 |
68 | Add the decorator to storybook preview:
69 |
70 | ```js
71 | //.storybook/preview.js
72 |
73 | import { muiTheme } from 'storybook-addon-material-ui'
74 |
75 | export const decorators = [
76 | muiTheme()
77 | ];
78 |
79 | ```
80 |
81 | > Note : You can switch between the loaded themes. Out of the box, you have two base themes, but you can simply add your custom themes like this:
82 | ```js
83 | //.storybook/preview.js
84 |
85 | import { muiTheme } from 'storybook-addon-material-ui'
86 |
87 | // Create your own theme like this.
88 | // Note: you can specify theme name in `themeName` field. Otherwise it will be displayed by the number.
89 | // you can specify only required fields overriding the `Light Base Theme`
90 | const newTheme = {
91 | themeName: 'Grey Theme',
92 | palette: {
93 | primary1Color: '#00bcd4',
94 | alternateTextColor: '#4a4a4a',
95 | canvasColor: '#616161',
96 | textColor: '#bdbdbd',
97 | secondaryTextColor: 'rgba(255, 255, 255, 0.54)',
98 | disabledColor: '#757575',
99 | accent1Color: '#607d8b',
100 | },
101 | };
102 |
103 |
104 | export const decorators = [
105 | muiTheme([newTheme])
106 | ];
107 |
108 | ```
109 | or even import from elsewhere
110 | ```js
111 | //.storybook/preview.js
112 |
113 | import { muiTheme } from 'storybook-addon-material-ui'
114 |
115 | import theme1 from './src/theme/theme1'
116 | import theme2 from './src/theme/theme2'
117 |
118 | export const decorators = [
119 | muiTheme([theme1, theme2])
120 | ];
121 |
122 | ```
123 |
124 | ### Storybook 5 (and older versions)
125 | Now, write your stories with Material-UI Addon. By default your stories will be provided with [`Light Base Theme`](https://github.com/callemall/material-ui/blob/master/src/styles/baseThemes/lightBaseTheme.js) and [`Dark Base Theme`](https://github.com/callemall/material-ui/blob/master/src/styles/baseThemes/darkBaseTheme.js)
126 |
127 | ```js
128 | import React from 'react';
129 | import { storiesOf, addDecorator } from '@storybook/react';
130 | import {muiTheme} from 'storybook-addon-material-ui';
131 |
132 | // Import some examples from react-theming https://github.com/react-theming/react-theme-provider/blob/master/example/
133 | import CardExampleControlled from '../CardExampleControlled.jsx';
134 | import RaisedButtonExampleSimple from '../RaisedButtonExampleSimple.jsx';
135 | import DatePickerExampleSimple from '../DatePickerExampleSimple.jsx';
136 |
137 | storiesOf('Material-UI', module)
138 | // Add the `muiTheme` decorator to provide material-ui support to your stories.
139 | // If you do not specify any arguments it starts with two default themes
140 | // You can also configure `muiTheme` as a global decorator.
141 | .addDecorator(muiTheme())
142 | .add('Card Example Controlled', () => (
143 |
144 | ))
145 | .add('Raised Button Example Simple', () => (
146 |
147 | ))
148 | .add('Date Picker Example Simple', () => (
149 |
150 | ));
151 | ```
152 | > Note : You can switch between the loaded themes. Out of the box, you have two base themes, but you can simply add your custom themes like this:
153 |
154 | ```js
155 | import React from 'react';
156 | import { storiesOf, addDecorator } from '@storybook/react';
157 |
158 | import {muiTheme} from 'storybook-addon-material-ui';
159 |
160 | import CardExampleControlled from '../CardExampleControlled.jsx';
161 | import RaisedButtonExampleSimple from '../RaisedButtonExampleSimple.jsx';
162 | import DatePickerExampleSimple from '../DatePickerExampleSimple.jsx';
163 |
164 | // Create your own theme like this.
165 | // Note: you can specify theme name in `themeName` field. Otherwise it will be displayed by the number.
166 | // you can specify only required fields overriding the `Light Base Theme`
167 | const newTheme = {
168 | themeName: 'Grey Theme',
169 | palette: {
170 | primary1Color: '#00bcd4',
171 | alternateTextColor: '#4a4a4a',
172 | canvasColor: '#616161',
173 | textColor: '#bdbdbd',
174 | secondaryTextColor: 'rgba(255, 255, 255, 0.54)',
175 | disabledColor: '#757575',
176 | accent1Color: '#607d8b',
177 | },
178 | };
179 |
180 |
181 |
182 | storiesOf('Material-UI', module)
183 | .addDecorator(muiTheme([newTheme]))
184 | .add('Card Example Controlled', () => (
185 |
186 | ))
187 | .add('Raised Button Example Simple', () => (
188 |
189 | ))
190 | .add('Date Picker Example Simple', () => (
191 |
192 | ));
193 |
194 |
195 | ```
196 |
197 | ## Feedback
198 |
199 | **You can left your opinion about this project via anonymous [survey](https://app.qpointsurvey.com/s.aspx?c=**F2VOSpTXOlnHHqMaZKSSV5a1ylaCDoRfhut3oNCox34~**).**
200 |
201 |
202 | ## Query string parameters
203 |
204 | As you select themes and other options it stores in adress bar line. So this state is retained when you refresh the page and you can use direct links to the desired states.
205 |
206 | ```
207 | http://localhost:9001/?theme-ind=0&theme-sidebar=true&theme-full=true
208 | ```
209 |
210 | ## CONTRIBUTING
211 |
212 | [](./.eslintrc)
213 |
214 | ### Developers:
215 |
216 | Our team welcome all contributing, testing, bug fixing. If you would like
217 | to help contribute to the project feel free to make an issue, PR or get in touch with me.
218 |
219 | ### Designers:
220 |
221 | We would really welcome the involvement of designers in this project. We are very interested in your opinion about working with this tool, the possibility of joint work of the designer and developer as well as its appearance and capabilities
222 |
223 | #### Credits
224 |
225 |
228 |
--------------------------------------------------------------------------------
/docs/WatchMe.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/WatchMe.gif
--------------------------------------------------------------------------------
/docs/logos/Storybook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/logos/Storybook.png
--------------------------------------------------------------------------------
/docs/logos/material-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/logos/material-ui.png
--------------------------------------------------------------------------------
/docs/screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen1.png
--------------------------------------------------------------------------------
/docs/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen2.png
--------------------------------------------------------------------------------
/docs/screen3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen3.png
--------------------------------------------------------------------------------
/docs/screen4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen4.png
--------------------------------------------------------------------------------
/docs/screen5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen5.png
--------------------------------------------------------------------------------
/docs/screen6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/docs/screen6.png
--------------------------------------------------------------------------------
/docs/screenshorts.md:
--------------------------------------------------------------------------------
1 | ### default `Light base theme`
2 | >quick start for component development
3 | 
4 | ### default `Dark base theme`
5 | >Check a different appearance
6 | 
7 | ### Visual color adjusting
8 | >Results instantly on the screen
9 | 
10 | ### User created theme
11 | 
12 | ### Full theme settings
13 | 
14 | ### After overriding
15 | >you will have only chanded setting in your theme
16 | 
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "storybook-addon-material-ui",
3 | "version": "0.9.0-alpha.24",
4 | "description": "Storybook Addon for Material UI Library",
5 | "main": "dist/index.js",
6 | "types": "storybook-addon-material-ui.d.ts",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/react-theming/storybook-addon-material-ui.git"
10 | },
11 | "keywords": [
12 | "storybook-addons",
13 | "style",
14 | "debug",
15 | "storybook",
16 | "react",
17 | "material",
18 | "ui",
19 | "material-ui",
20 | "addon",
21 | "decorator",
22 | "theme",
23 | "editor",
24 | "customization",
25 | "dark theme",
26 | "light theme",
27 | "storybook-addon"
28 | ],
29 | "storybook": {
30 | "displayName": "Material-UI",
31 | "supportedFrameworks": [
32 | "React"
33 | ],
34 | "icon": "https://github.com/react-theming/storybook-addon-material-ui/blob/b0ac1c444bd33212d693af182ac6fed1b069c3db/docs/logos/material-ui.png"
35 | },
36 | "license": "MIT",
37 | "bugs": {
38 | "url": "https://github.com/react-theming/storybook-addon-material-ui/issues"
39 | },
40 | "homepage": "https://github.com/react-theming/storybook-addon-material-ui",
41 | "dependencies": {
42 | "@emotion/core": "^10.0.4",
43 | "@emotion/styled": "^10.0.4",
44 | "global": "^4.3.2",
45 | "js-beautify": "^1.8.9",
46 | "react-inspector": "^2.3.1",
47 | "@usulpro/color-picker": "^1.1.3"
48 | },
49 | "scripts": {
50 | "start": "start-storybook -p 9001",
51 | "build-storybook": "build-storybook -s public",
52 | "deploy": "node .scripts/deployer",
53 | "prepare": "node .scripts/npm-prepare.js",
54 | "postpublish": "node .scripts/npm-postpublish.js"
55 | },
56 | "devDependencies": {
57 | "@babel/cli": "^7.2.3",
58 | "@babel/core": "^7.2.2",
59 | "@babel/plugin-proposal-class-properties": "^7.2.3",
60 | "@babel/preset-env": "^7.2.3",
61 | "@babel/preset-react": "^7.0.0",
62 | "@material-ui/core": "^3.9.3",
63 | "@material-ui/icons": "^3.0.2",
64 | "@storybook/addon-actions": "^5.0.6",
65 | "@storybook/addon-backgrounds": "^5.0.6",
66 | "@storybook/addon-links": "^5.0.6",
67 | "@storybook/addons": "^5.0.6",
68 | "@storybook/react": "^5.0.6",
69 | "babel-eslint": "^8.2.6",
70 | "babel-jest": "^23.4.2",
71 | "babel-loader": "^8.0.2",
72 | "chalk": "^2.4.1",
73 | "emotion-theming": "^10.0.10",
74 | "eslint": "^5.3.0",
75 | "eslint-config-airbnb": "^17.0.0",
76 | "eslint-config-prettier": "^2.9.0",
77 | "eslint-plugin-import": "^2.14.0",
78 | "eslint-plugin-jest": "^21.21.0",
79 | "eslint-plugin-json": "^1.2.1",
80 | "eslint-plugin-jsx-a11y": "^6.1.1",
81 | "eslint-plugin-prettier": "^2.6.2",
82 | "eslint-plugin-react": "^7.10.0",
83 | "gh-pages": "^1.2.0",
84 | "jest": "^23.5.0",
85 | "prettier": "^1.14.2",
86 | "prop-types": "^15.6.2",
87 | "react": "16.7.0-alpha.2",
88 | "react-dom": "16.7.0-alpha.2",
89 | "react-scripts": "1.1.5",
90 | "shelljs": "^0.8.2"
91 | },
92 | "peerDependencies": {
93 | "@material-ui/core": "^1.0.0 || ^3.0.0 || ^4.0.0",
94 | "@storybook/addons": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
95 | "@storybook/react": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
96 | "prop-types": "^15.5.8",
97 | "react": "^16.0.0 || ^17.0.0",
98 | "react-dom": "^16.0.0 || ^17.0.0"
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/7afdfba6b0f0bc6695450a4b881b7359d376594e/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/register.js:
--------------------------------------------------------------------------------
1 | require('./dist/register.js');
2 |
--------------------------------------------------------------------------------
/src/.themes/index.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 |
3 |
4 | export const lightTheme = createMuiTheme({
5 | palette: {
6 | primary: {
7 | main: 'rgb(98, 126, 157)'
8 | }
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/src/UI/AddonPanel.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { cx, css } from '@emotion/core';
4 | import styled from '@emotion/styled';
5 | import { ObjectInspector } from 'react-inspector';
6 |
7 | import { Toggle, Link, Button, Dropdown, Paper } from '../Utils/ui_package';
8 | import withChannel from '../adk/WithChannel';
9 | import { EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK } from '../config';
10 | import FullTheme from './FullTheme';
11 | import Overridings from './Overridings';
12 | import Palette from './Palette';
13 |
14 | const genNameList = themesAppliedList =>
15 | themesAppliedList.map((val, ind) => val.themeName || `Theme ${ind + 1}`);
16 |
17 | const FlexBlock = styled('div')(props => ({
18 | minWidth: 160,
19 | padding: 16,
20 | display: 'flex',
21 | flexDirection: props.direction || 'column',
22 | justifyContent: 'space-between',
23 | flexGrow: props.main ? 1 : 0
24 | }));
25 |
26 | const ModeSection = styled('div')(props => ({
27 | display: 'flex',
28 | flexDirection: 'column',
29 | alignItems: props.left ? 'center' : 'stretch',
30 | // height: 1,
31 | flexGrow: props.left ? 0 : 1,
32 | padding: props.left ? 2 : 0,
33 | marginRight: props.left ? 0 : 8,
34 | border: '1px solid rgba(0, 0, 0, 0.15)',
35 | borderRight: props.left ? 'none' : null,
36 | borderLeft: props.left ? null : 'none',
37 | backgroundColor: props.left ? 'rgba(0, 0, 0, 0.04)' : 'rgba(0, 0, 0, 0.01)',
38 | overflow: 'auto'
39 | }));
40 |
41 | const RadioButton = styled('button')(props => ({
42 | minWidth: 8,
43 | minHeight: 8,
44 | padding: 4,
45 | backgroundColor: props.active
46 | ? 'rgba(255, 255, 255, 0.99)'
47 | : 'rgba(255, 255, 255, 0.9)',
48 | border: props.active
49 | ? '1px solid rgba(0, 0, 0, 0.5)'
50 | : '1px solid rgba(0, 0, 0, 0.2)',
51 | borderRadius: 2,
52 | outline: 'none',
53 | margin: 4,
54 | // fontFamily:
55 | // '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif', // eslint-disable-line
56 | cursor: 'pointer',
57 | fontSize: 9,
58 | fontWeight: 500,
59 | textDecoration: 'none',
60 | color: props.active ? 'rgba(0, 0, 0, 1)' : 'rgba(0, 0, 0, 0.8)',
61 | '&:hover': {
62 | backgroundColor: 'white',
63 | border: '1px solid rgba(0, 0, 0, 0.5)'
64 | },
65 | '&[disabled]': {
66 | border: '1px solid rgba(0, 0, 0, 0.1)',
67 | color: 'rgba(0, 0, 0, 0.4)',
68 | cursor: 'default'
69 | }
70 | }));
71 |
72 | const CMTButton = styled('div')`
73 | cursor: pointer;
74 | border: 1px solid #c5c5c5;
75 | background-color: #f7f7f7;
76 | border-radius: 2px;
77 | &:hover {
78 | background-color: rgba(0, 0, 0, 0.1)
79 | }
80 | `;
81 |
82 | const MODS_LIST = [
83 | {
84 | title: 'Palette',
85 | id: 'palette',
86 | label: 'P'
87 | },
88 | {
89 | title: 'Overridings',
90 | id: 'overridings',
91 | label: 'O'
92 | },
93 | {
94 | title: 'Spacing',
95 | id: 'spacing',
96 | label: 'S',
97 | disabled: true
98 | },
99 | {
100 | title: 'Typography',
101 | id: 'typography',
102 | label: 'T',
103 | disabled: true
104 | },
105 | {
106 | title: 'Full',
107 | id: 'full',
108 | label: 'F'
109 | }
110 | ];
111 |
112 | class AddonPanel extends React.Component {
113 | state = {
114 | value: this.props.defautThemeInd,
115 | isThemeEditing: false,
116 | isThemeValid: true,
117 | theme: this.props.themeJSON,
118 | currentMode: MODS_LIST[0].id
119 | };
120 |
121 | setMode = currentMode => () => this.setState({ currentMode });
122 |
123 | handleChange = value => {
124 | this.setState({ value }, this.props.onThemeSelect(value));
125 | };
126 |
127 | handleThemeChange = ev => this.setState({ theme: ev.target.value });
128 |
129 | onChangePalette = palette => {
130 | const { themeInd, themes } = this.props.data;
131 | themes[themeInd].palette = palette;
132 | this.props.sendData({ themes });
133 | };
134 |
135 | render() {
136 | const { data } = this.props;
137 | const { currentMode } = this.state;
138 | if (!data) return 'Waiting for theme';
139 |
140 | const { themes } = data;
141 | let theme;
142 | try {
143 | theme = themes[data.themeInd];
144 | } catch (err) {
145 | return 'Error...';
146 | }
147 | const themeStr = JSON.stringify(theme);
148 |
149 | const styleArea = {
150 | width: '100%',
151 | // height: '100%',
152 | outlineColor: this.props.isThemeInvalid ? '#cc5858' : '#26acd8',
153 | flexGrow: 1
154 | };
155 | const buttonStyle = {
156 | height: 34,
157 | width: 34,
158 | fontSize: 10,
159 | fontFamily:
160 | '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
161 | marginBottom: 4
162 | };
163 |
164 | return (
165 |
175 |
184 |
185 | this.props.sendData({ themeInd })}
190 | />
191 |
192 |
203 |
204 |
209 | Clone Theme
210 |
211 |
216 |
221 |
222 |
223 |
224 |
225 |
226 | {MODS_LIST.map(item => (
227 |
234 | {item.label}
235 |
236 | ))}
237 |
238 |
239 | {currentMode === 'palette' && (
240 |
245 | )}
246 | {currentMode === 'overridings' && }
247 | {currentMode === 'full' && }
248 |
249 |
250 |
251 |
310 |
311 | );
312 | }
313 | }
314 |
315 | export default withChannel({ EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK })(
316 | AddonPanel
317 | );
318 |
--------------------------------------------------------------------------------
/src/UI/FullTheme.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { cx, css } from '@emotion/core';
4 | import styled from '@emotion/styled';
5 | import { ObjectInspector } from 'react-inspector';
6 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
7 |
8 | const sortObjectKeys = (a, b) => {
9 | if (a === 'themeName') return -2;
10 | if (b === 'themeName') return 2;
11 | if (a === 'palette') return -1;
12 | if (b === 'palette') return 1;
13 | return a.charCodeAt(0) - b.charCodeAt(0);
14 | };
15 |
16 | const Holder = styled('div')`
17 | height: 1px;
18 | flex-grow: 1;
19 | display: flex;
20 | flex-direction: column;
21 | label: PaletteHolder;
22 | padding: 8px;
23 | `;
24 |
25 | export default ({ theme }) => (
26 |
27 |
33 |
34 | );
35 |
--------------------------------------------------------------------------------
/src/UI/MuiDecorator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
4 |
5 | import withChannel from '../adk/WithChannel';
6 | import { EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK } from '../config';
7 |
8 | const currentTheme = data => {
9 | try {
10 | const theme = data.themes[data.themeInd];
11 | return createMuiTheme(theme);
12 | } catch (err) {
13 | return createMuiTheme({});
14 | }
15 | };
16 |
17 | const MuiDecorator = ({ data, story }) => (
18 |
19 | {story}
20 |
21 | );
22 |
23 | export default withChannel({ EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK })(
24 | MuiDecorator
25 | );
26 |
--------------------------------------------------------------------------------
/src/UI/Overridings.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { cx, css } from '@emotion/core';
4 | import styled from '@emotion/styled';
5 | import { ObjectInspector } from 'react-inspector';
6 |
7 | const sortObjectKeys = (a, b) => {
8 | if (a === 'themeName') return -2;
9 | if (b === 'themeName') return 2;
10 | if (a === 'palette') return -1;
11 | if (b === 'palette') return 1;
12 | return a.charCodeAt(0) - b.charCodeAt(0);
13 | };
14 |
15 | const Holder = styled('div')`
16 | height: 1px;
17 | flex-grow: 1;
18 | display: flex;
19 | flex-direction: column;
20 | label: PaletteHolder;
21 | padding: 8px;
22 | `;
23 |
24 | export default ({ theme }) => (
25 |
26 |
32 |
33 | );
34 |
--------------------------------------------------------------------------------
/src/UI/Palette.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { cx, css } from '@emotion/core';
4 | import styled from '@emotion/styled';
5 | import { ObjectInspector } from 'react-inspector';
6 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
7 | import MaterialColorPicker from '@usulpro/color-picker';
8 |
9 | const sortObjectKeys = (a, b) => {
10 | if (a === 'themeName') return -2;
11 | if (b === 'themeName') return 2;
12 | if (a === 'palette') return -1;
13 | if (b === 'palette') return 1;
14 | return a.charCodeAt(0) - b.charCodeAt(0);
15 | };
16 |
17 | const PaletteHolder = styled('div')`
18 | height: 1px;
19 | flex-grow: 1;
20 | display: flex;
21 | flex-direction: column;
22 | background-color: ${props =>
23 | props.dark ? 'hsl(0, 0%, 44%)' : 'hsl(0, 0%, 90%)'};
24 | color: ${props => (props.dark ? 'hsl(0, 0%, 90%)' : 'hsl(0, 0%, 44%)')};
25 | label: PaletteHolder;
26 | padding: 8px;
27 | position: relative;
28 | `;
29 |
30 | const PickerOverlap = styled('div')`
31 | position: absolute;
32 | background-color: hsl(0, 0%, 0%, 0.8);
33 | left: 0px;
34 | right: 0px;
35 | top: 0px;
36 | bottom: 0px;
37 | display: flex;
38 | justify-content: center;
39 | align-items: center;
40 | `;
41 |
42 | const PickerHolder = styled('div')`
43 | width: 70%;
44 | max-width: 500px;
45 | min-width: 250px;
46 | background-color: hsl(0, 0%, 50%);
47 | `;
48 |
49 | const ColorInput = styled('div')`
50 | margin-left: 2px;
51 | margin-top: 8px;
52 | color: hsl(0, 0%, 30%);
53 | & input {
54 | margin-right: 4px;
55 | }
56 | `;
57 |
58 | export default class Palette extends React.Component {
59 | static propTypes = {
60 | theme: PropTypes.shape()
61 | };
62 |
63 |
64 | state = {
65 | isPickerOpen: false,
66 | editColor: '',
67 | palette: this.props.theme.palette,
68 | path: []
69 | };
70 |
71 | prevColor = '';
72 |
73 | onChange = () => {
74 | this.props.onChangePalette(this.state.palette);
75 | };
76 |
77 | setPath = (path, isPickerOpen) => () => {
78 | const { palette } = this.state;
79 | this.setState(
80 | {
81 | path,
82 | editColor: createMuiTheme({ palette }).palette[path[0]][path[1]],
83 | isPickerOpen
84 | },
85 | () => {
86 | this.prevColor = this.state.editColor;
87 | }
88 | );
89 | };
90 |
91 | updPalette = (ev, cb) => {
92 | const { path, palette } = this.state;
93 | const editColor = ev.target.value || this.prevColor;
94 | const newPalette = {
95 | ...palette,
96 | [path[0]]: {
97 | ...palette[path[0]],
98 | [path[1]]: editColor
99 | }
100 | };
101 | this.setState({ editColor, palette: newPalette }, cb);
102 | };
103 |
104 | onSubmit = ev => {
105 | this.updPalette(ev, () => {
106 | this.onChange();
107 | this.setState({ isPickerOpen: false });
108 | this.prevColor = this.state.editColor;
109 | });
110 | };
111 |
112 | onReset = ev => {
113 | this.updPalette(ev, () => {
114 | this.onChange();
115 | this.setState({ isPickerOpen: false });
116 | });
117 | };
118 |
119 | onHover = ev => {
120 | this.updPalette(ev, () => {
121 | this.onChange();
122 | });
123 | };
124 |
125 | renderColorInput = () => (
126 |
127 |
132 | ok
133 |
134 | );
135 |
136 | renderColorSet = (colorSet, name, isDark) => {
137 | const { main, light, dark, contrastText } = colorSet;
138 | const Plate = styled('div')`
139 | display: flex;
140 | justify-content: space-between;
141 | height: 20px;
142 | margin: 2px;
143 | margin-bottom: ${props => (props.up ? '0px' : '2px')};
144 | margin-top: ${props => (!props.up ? '0px' : '2px')};
145 | `;
146 | const ColorBox = styled('div')`
147 | background-color: ${props => props.color || 'rgba(0, 0, 0, 0.1)'};
148 | width: 1px;
149 | flex-grow: 1;
150 | border: 1px solid ${isDark ? 'hsl(0, 0%, 80%)' : 'hsl(0, 0%, 44%)'};
151 | border: ${props => (props.color ? '' : 'none')};
152 | cursor: ${props => (props.color ? 'pointer' : 'text')};
153 | `;
154 | const ColorName = styled('div')`
155 | background-color: rgba(0, 0, 0, 0.1);
156 | width: 80px;
157 | padding-left: 4px;
158 | `;
159 | return (
160 | <>
161 |
162 | {name}
163 |
167 |
168 |
169 |
173 |
174 |
175 |
176 |
177 | {`light: ${light}`}
178 |
179 |
180 | {`main: ${main}`}
181 |
182 |
183 | {`dark: ${dark}`}
184 |
185 |
186 | {`contrastText: ${contrastText}`}
187 |
188 |
189 | >
190 | );
191 | };
192 |
193 | render() {
194 | const { palette } = createMuiTheme({ palette: this.state.palette });
195 | const colorSet = name =>
196 | this.renderColorSet(
197 | palette[name],
198 | name,
199 | this.state.palette.type === 'dark'
200 | );
201 |
202 | return (
203 |
204 | {colorSet('primary')}
205 | {colorSet('secondary')}
206 | {colorSet('error')}
207 | {this.renderColorInput()}
208 | {this.state.isPickerOpen && (
209 |
210 |
211 |
218 |
219 |
220 | )}
221 |
222 | );
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/src/Utils/index.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | export function copyToClipboard(text) {
4 | console.log(text);
5 | const copyText = text;
6 | return () => {
7 | console.info(copyText);
8 | const textElem = document.createElement('textarea');
9 | document.body.appendChild(textElem);
10 | textElem.value = text;
11 | textElem.select();
12 |
13 | let successful;
14 | try {
15 | successful = document.execCommand('copy');
16 | } catch (err) {
17 | console.warn('cant copy to clipboard');
18 | }
19 | textElem.remove();
20 | return successful;
21 | };
22 | }
23 |
24 | export function copyToClipboardThis(text) {
25 | const textElem = document.createElement('textarea');
26 | document.body.appendChild(textElem);
27 | textElem.value = text;
28 | textElem.select();
29 |
30 | let successful;
31 | try {
32 | successful = document.execCommand('copy');
33 | } catch (err) {
34 | console.warn('cant copy to clipboard');
35 | }
36 | textElem.remove();
37 | return successful;
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/Utils/svg_package.js:
--------------------------------------------------------------------------------
1 | (function webpackUniversalModuleDefinition(root, factory) {
2 | if (typeof exports === 'object' && typeof module === 'object') { module.exports = factory(); } else if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { exports.svg_package = factory(); } else { root.svg_package = factory(); }
3 | }(this, function () {
4 | return /** ****/ (function (modules) { // webpackBootstrap
5 | /** ****/ // The module cache
6 | /** ****/ const installedModules = {};
7 |
8 | /** ****/ // The require function
9 | /** ****/ function __webpack_require__(moduleId) {
10 | /** ****/ // Check if module is in cache
11 | /** ****/ if (installedModules[moduleId])
12 | /** ****/ { return installedModules[moduleId].exports; }
13 |
14 | /** ****/ // Create a new module (and put it into the cache)
15 | /** ****/ const module = installedModules[moduleId] = {
16 | /** ****/ i: moduleId,
17 | /** ****/ l: false,
18 | /** ****/ exports: {},
19 | /** ****/ };
20 |
21 | /** ****/ // Execute the module function
22 | /** ****/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
23 |
24 | /** ****/ // Flag the module as loaded
25 | /** ****/ module.l = true;
26 |
27 | /** ****/ // Return the exports of the module
28 | /** ****/ return module.exports;
29 | /** ****/ }
30 |
31 |
32 | /** ****/ // expose the modules object (__webpack_modules__)
33 | /** ****/ __webpack_require__.m = modules;
34 |
35 | /** ****/ // expose the module cache
36 | /** ****/ __webpack_require__.c = installedModules;
37 |
38 | /** ****/ // identity function for calling harmony imports with the correct context
39 | /** ****/ __webpack_require__.i = function (value) { return value; };
40 |
41 | /** ****/ // define getter function for harmony exports
42 | /** ****/ __webpack_require__.d = function (exports, name, getter) {
43 | /** ****/ if (!__webpack_require__.o(exports, name)) {
44 | /** ****/ Object.defineProperty(exports, name, {
45 | /** ****/ configurable: false,
46 | /** ****/ enumerable: true,
47 | /** ****/ get: getter,
48 | /** ****/ });
49 | /** ****/ }
50 | /** ****/ };
51 |
52 | /** ****/ // getDefaultExport function for compatibility with non-harmony modules
53 | /** ****/ __webpack_require__.n = function (module) {
54 | /** ****/ const getter = module && module.__esModule ?
55 | /** ****/ function getDefault() { return module.default; } :
56 | /** ****/ function getModuleExports() { return module; };
57 | /** ****/ __webpack_require__.d(getter, 'a', getter);
58 | /** ****/ return getter;
59 | /** ****/ };
60 |
61 | /** ****/ // Object.prototype.hasOwnProperty.call
62 | /** ****/ __webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
63 |
64 | /** ****/ // __webpack_public_path__
65 | /** ****/ __webpack_require__.p = '';
66 |
67 | /** ****/ // Load entry module and return exports
68 | /** ****/ return __webpack_require__(__webpack_require__.s = 35);
69 | /** ****/ }([
70 | /* 0 */
71 | /** */ (function (module, exports) {
72 | module.exports = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAB3RJTUUH4QEaBzIA+ze+OAAAAaBJREFUeJztl82RhiAMQHEbgBK+DqAT6ABLsAPsBEqwE+wkJbAHZ5yIQvwWZ9YD78SBn2eABIeUEnsTP/8tkNOFKLoQRRei6EIUXYgkVQGAEIIxRinVsopSyhgTQgCA+opFIQCY51kI8dSXbwgh5nmuaF0LAUBjSOoopUpOF0IA8HhgzgghLp1yoXNsOOfOuRjj1iHG6JzjnLc7XcYpF3LO4THW2svvAABrbbuTc64mlG2W1vqsgml3Om/cQch7v3flnJNXFADa9857j+c8JMZlWfb2NE3k0RZCTNPUKIQXZeyYGPFx3k9xnRhjo5BSCk84JPTXMQwDFr05Ix71N/Bar6tlByEp5d5e1/XO+JvdKuBFc6HP57O387NW4Ga3CnhRxljx2pdSe3bt24tMdu3zxIjzijGmLjSOY6PNOdsRpcMYUyod7TaMLB0b2SnbXjC4uD71TpJS0sU1PVQQSEqlqfhAy+L0LJexqQltPPXuwWyvq6+fsDhU3nutdWPApJRaa+89mUoOtewNvLuWvYEuRNGFKLoQRRei6EIUrxP6BcmQ7xzbjmd9AAAAAElFTkSuQmCC';
73 | /** */ }),
74 | /* 1 */
75 | /** */ (function (module, exports) {
76 | module.exports = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACBklEQVRoQ+1X7TEEQRB9FwEhEAEyIAIyQASIABkQASJABGSACAiBCKhXtaN253pmenau72rp+XVV19Pb773+mhkmfmYTjx8OYNUKugKuQCMDnkKNBDZfdwWaKWx08K8UWAewD+AAwAaA7Uby4uuvAD4APAB4BPCp8a9RgIGfADgFwN/LOAz+CsB1CUgJAAN+MmBbSwJV2cuByAFg8O9LZD0FimpspkCkAFgz/9WlCPOdLPOwplhfTNW1CE1SiRSACwDnWp0r7e66IFNFSvKY/4eR30sAjGtwJACWqcPgj5SAqQ67XjhiKkkA+IEb5UdqzJg2bL+q9tjVHttqP52OAdz2PyoBiJHXBJmzFVOg4DxOZc4H1snvkQC8GLXNnV7BaklhYTOecFjM9JMF8K31XmlXmjkpd3E8Az+S08kDoExblexqzBeRQm9xev/JIrZqo9mVQJBQmkeqNsqLcf/VpIjGhj2cQWjOfdQyxTmyilWCIM4yA40EcpAO+j0A9SpBdujk2aiY6T/s+xxM/WWOq4P07pgr3iBhaZ22SiVNCgWb7ApSGi7WSpSAkPndsQ+a4JwgKKu0p5cCGPt/eC/Mrc+xw5ICfXsCYWGFR/2ihx3ZDo96LpSqrbUGwFg2Te85AFN6Fc5dAQVJpiaugCm9CueugIIkUxNXwJRehXNXQEGSqcnkFfgBKMNcMdUsPWUAAAAASUVORK5CYII=';
77 | /** */ }),
78 | /* 2 */
79 | /** */ (function (module, exports) {
80 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0yMCAySDRjLTEuMSAwLTEuOTkuOS0xLjk5IDJMMiAyMmw0LTRoMTRjMS4xIDAgMi0uOSAyLTJWNGMwLTEuMS0uOS0yLTItMnptLTcgOWgtMlY1aDJ2NnptMCA0aC0ydi0yaDJ2MnoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
81 | /** */ }),
82 | /* 3 */
83 | /** */ (function (module, exports) {
84 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xMiA2djNsNC00LTQtNHYzYy00LjQyIDAtOCAzLjU4LTggOCAwIDEuNTcuNDYgMy4wMyAxLjI0IDQuMjZMNi43IDE0LjhjLS40NS0uODMtLjctMS43OS0uNy0yLjggMC0zLjMxIDIuNjktNiA2LTZ6bTYuNzYgMS43NEwxNy4zIDkuMmMuNDQuODQuNyAxLjc5LjcgMi44IDAgMy4zMS0yLjY5IDYtNiA2di0zbC00IDQgNCA0di0zYzQuNDIgMCA4LTMuNTggOC04IDAtMS41Ny0uNDYtMy4wMy0xLjI0LTQuMjZ6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
85 | /** */ }),
86 | /* 4 */
87 | /** */ (function (module, exports) {
88 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xNyAzSDdjLTEuMSAwLTEuOTkuOS0xLjk5IDJMNSAyMWw3LTMgNyAzVjVjMC0xLjEtLjktMi0yLTJ6bTAgMTVsLTUtMi4xOEw3IDE4VjVoMTB2MTN6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
89 | /** */ }),
90 | /* 5 */
91 | /** */ (function (module, exports) {
92 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogICAgPHBhdGggZD0iTTIyLjcgMTlsLTkuMS05LjFjLjktMi4zLjQtNS0xLjUtNi45LTItMi01LTIuNC03LjQtMS4zTDkgNiA2IDkgMS42IDQuN0MuNCA3LjEuOSAxMC4xIDIuOSAxMi4xYzEuOSAxLjkgNC42IDIuNCA2LjkgMS41bDkuMSA5LjFjLjQuNCAxIC40IDEuNCAwbDIuMy0yLjNjLjUtLjQuNS0xLjEuMS0xLjR6Ii8+Cjwvc3ZnPg==';
93 | /** */ }),
94 | /* 6 */
95 | /** */ (function (module, exports) {
96 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xOSAzSDVjLTEuMTEgMC0yIC45LTIgMnYxNGMwIDEuMS44OSAyIDIgMmgxNGMxLjExIDAgMi0uOSAyLTJWNWMwLTEuMS0uODktMi0yLTJ6bS05IDE0bC01LTUgMS40MS0xLjQxTDEwIDE0LjE3bDcuNTktNy41OUwxOSA4bC05IDl6Ii8+Cjwvc3ZnPg==';
97 | /** */ }),
98 | /* 7 */
99 | /** */ (function (module, exports) {
100 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xOSA1djE0SDVWNWgxNG0wLTJINWMtMS4xIDAtMiAuOS0yIDJ2MTRjMCAxLjEuOSAyIDIgMmgxNGMxLjEgMCAyLS45IDItMlY1YzAtMS4xLS45LTItMi0yeiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz4=';
101 | /** */ }),
102 | /* 8 */
103 | /** */ (function (module, exports) {
104 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xOSA2LjQxTDE3LjU5IDUgMTIgMTAuNTkgNi40MSA1IDUgNi40MSAxMC41OSAxMiA1IDE3LjU5IDYuNDEgMTkgMTIgMTMuNDEgMTcuNTkgMTkgMTkgMTcuNTkgMTMuNDEgMTJ6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
105 | /** */ }),
106 | /* 9 */
107 | /** */ (function (module, exports) {
108 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPgogICAgPHBhdGggZD0iTTkuNCAxNi42TDQuOCAxMmw0LjYtNC42TDggNmwtNiA2IDYgNiAxLjQtMS40em01LjIgMGw0LjYtNC42LTQuNi00LjZMMTYgNmw2IDYtNiA2LTEuNC0xLjR6Ii8+Cjwvc3ZnPg==';
109 | /** */ }),
110 | /* 10 */
111 | /** */ (function (module, exports) {
112 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xNiAxSDRjLTEuMSAwLTIgLjktMiAydjE0aDJWM2gxMlYxem0zIDRIOGMtMS4xIDAtMiAuOS0yIDJ2MTRjMCAxLjEuOSAyIDIgMmgxMWMxLjEgMCAyLS45IDItMlY3YzAtMS4xLS45LTItMi0yem0wIDE2SDhWN2gxMXYxNHoiLz4KPC9zdmc+';
113 | /** */ }),
114 | /* 11 */
115 | /** */ (function (module, exports) {
116 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxjaXJjbGUgY3g9IjYiIGN5PSIxOCIgZmlsbD0ibm9uZSIgcj0iMiIvPgogICAgPGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgZmlsbD0ibm9uZSIgcj0iLjUiLz4KICAgIDxjaXJjbGUgY3g9IjYiIGN5PSI2IiBmaWxsPSJub25lIiByPSIyIi8+CiAgICA8cGF0aCBkPSJNOS42NCA3LjY0Yy4yMy0uNS4zNi0xLjA1LjM2LTEuNjQgMC0yLjIxLTEuNzktNC00LTRTMiAzLjc5IDIgNnMxLjc5IDQgNCA0Yy41OSAwIDEuMTQtLjEzIDEuNjQtLjM2TDEwIDEybC0yLjM2IDIuMzZDNy4xNCAxNC4xMyA2LjU5IDE0IDYgMTRjLTIuMjEgMC00IDEuNzktNCA0czEuNzkgNCA0IDQgNC0xLjc5IDQtNGMwLS41OS0uMTMtMS4xNC0uMzYtMS42NEwxMiAxNGw3IDdoM3YtMUw5LjY0IDcuNjR6TTYgOGMtMS4xIDAtMi0uODktMi0ycy45LTIgMi0yIDIgLjg5IDIgMi0uOSAyLTIgMnptMCAxMmMtMS4xIDAtMi0uODktMi0ycy45LTIgMi0yIDIgLjg5IDIgMi0uOSAyLTIgMnptNi03LjVjLS4yOCAwLS41LS4yMi0uNS0uNXMuMjItLjUuNS0uNS41LjIyLjUuNS0uMjIuNS0uNS41ek0xOSAzbC02IDYgMiAyIDctN1YzeiIvPgo8L3N2Zz4=';
117 | /** */ }),
118 | /* 12 */
119 | /** */ (function (module, exports) {
120 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xOSAyaC00LjE4QzE0LjQuODQgMTMuMyAwIDEyIDBjLTEuMyAwLTIuNC44NC0yLjgyIDJINWMtMS4xIDAtMiAuOS0yIDJ2MTZjMCAxLjEuOSAyIDIgMmgxNGMxLjEgMCAyLS45IDItMlY0YzAtMS4xLS45LTItMi0yem0tNyAwYy41NSAwIDEgLjQ1IDEgMXMtLjQ1IDEtMSAxLTEtLjQ1LTEtMSAuNDUtMSAxLTF6bTcgMThINVY0aDJ2M2gxMFY0aDJ2MTZ6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
121 | /** */ }),
122 | /* 13 */
123 | /** */ (function (module, exports) {
124 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik02IDE5YzAgMS4xLjkgMiAyIDJoOGMxLjEgMCAyLS45IDItMlY3SDZ2MTJ6TTE5IDRoLTMuNWwtMS0xaC01bC0xIDFINXYyaDE0VjR6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
125 | /** */ }),
126 | /* 14 */
127 | /** */ (function (module, exports) {
128 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPgogICAgPHBhdGggZD0iTTYgMTljMCAxLjEuOSAyIDIgMmg4YzEuMSAwIDItLjkgMi0yVjdINnYxMnptMi40Ni03LjEybDEuNDEtMS40MUwxMiAxMi41OWwyLjEyLTIuMTIgMS40MSAxLjQxTDEzLjQxIDE0bDIuMTIgMi4xMi0xLjQxIDEuNDFMMTIgMTUuNDFsLTIuMTIgMi4xMi0xLjQxLTEuNDFMMTAuNTkgMTRsLTIuMTMtMi4xMnpNMTUuNSA0bC0xLTFoLTVsLTEgMUg1djJoMTRWNHoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
129 | /** */ }),
130 | /* 15 */
131 | /** */ (function (module, exports) {
132 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik00IDE4bDguNS02TDQgNnYxMnptOS0xMnYxMmw4LjUtNkwxMyA2eiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz4=';
133 | /** */ }),
134 | /* 16 */
135 | /** */ (function (module, exports) {
136 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xMSAxOFY2bC04LjUgNiA4LjUgNnptLjUtNmw4LjUgNlY2bC04LjUgNnoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
137 | /** */ }),
138 | /* 17 */
139 | /** */ (function (module, exports) {
140 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xOSA5aC00VjNIOXY2SDVsNyA3IDctN3pNNSAxOHYyaDE0di0ySDV6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
141 | /** */ }),
142 | /* 18 */
143 | /** */ (function (module, exports) {
144 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMSAxOGgydi0yaC0ydjJ6bTEtMTZDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTAgMThjLTQuNDEgMC04LTMuNTktOC04czMuNTktOCA4LTggOCAzLjU5IDggOC0zLjU5IDgtOCA4em0wLTE0Yy0yLjIxIDAtNCAxLjc5LTQgNGgyYzAtMS4xLjktMiAyLTJzMiAuOSAyIDJjMCAyLTMgMS43NS0zIDVoMmMwLTIuMjUgMy0yLjUgMy01IDAtMi4yMS0xLjc5LTQtNC00eiIvPgo8L3N2Zz4=';
145 | /** */ }),
146 | /* 19 */
147 | /** */ (function (module, exports) {
148 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xNC41OSA4TDEyIDEwLjU5IDkuNDEgOCA4IDkuNDEgMTAuNTkgMTIgOCAxNC41OSA5LjQxIDE2IDEyIDEzLjQxIDE0LjU5IDE2IDE2IDE0LjU5IDEzLjQxIDEyIDE2IDkuNDEgMTQuNTkgOHpNMTIgMkM2LjQ3IDIgMiA2LjQ3IDIgMTJzNC40NyAxMCAxMCAxMCAxMC00LjQ3IDEwLTEwUzE3LjUzIDIgMTIgMnptMCAxOGMtNC40MSAwLTgtMy41OS04LThzMy41OS04IDgtOCA4IDMuNTkgOCA4LTMuNTkgOC04IDh6Ii8+Cjwvc3ZnPg==';
149 | /** */ }),
150 | /* 20 */
151 | /** */ (function (module, exports) {
152 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMyAzYy00Ljk3IDAtOSA0LjAzLTkgOUgxbDMuODkgMy44OS4wNy4xNEw5IDEySDZjMC0zLjg3IDMuMTMtNyA3LTdzNyAzLjEzIDcgNy0zLjEzIDctNyA3Yy0xLjkzIDAtMy42OC0uNzktNC45NC0yLjA2bC0xLjQyIDEuNDJDOC4yNyAxOS45OSAxMC41MSAyMSAxMyAyMWM0Ljk3IDAgOS00LjAzIDktOXMtNC4wMy05LTktOXptLTEgNXY1bDQuMjggMi41NC43Mi0xLjIxLTMuNS0yLjA4VjhIMTJ6Ii8+Cjwvc3ZnPg==';
153 | /** */ }),
154 | /* 21 */
155 | /** */ (function (module, exports) {
156 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik00IDZIMnYxNGMwIDEuMS45IDIgMiAyaDE0di0ySDRWNnptMTYtNEg4Yy0xLjEgMC0yIC45LTIgMnYxMmMwIDEuMS45IDIgMiAyaDEyYzEuMSAwIDItLjkgMi0yVjRjMC0xLjEtLjktMi0yLTJ6bS0xIDloLTR2NGgtMnYtNEg5VjloNFY1aDJ2NGg0djJ6Ii8+Cjwvc3ZnPg==';
157 | /** */ }),
158 | /* 22 */
159 | /** */ (function (module, exports) {
160 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0zIDE4aDE4di0ySDN2MnptMC01aDE4di0ySDN2MnptMC03djJoMThWNkgzeiIvPgo8L3N2Zz4=';
161 | /** */ }),
162 | /* 23 */
163 | /** */ (function (module, exports) {
164 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMiAyQzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyem0wIDE4Yy00LjQyIDAtOC0zLjU4LTgtOCAwLTEuODUuNjMtMy41NSAxLjY5LTQuOUwxNi45IDE4LjMxQzE1LjU1IDE5LjM3IDEzLjg1IDIwIDEyIDIwem02LjMxLTMuMUw3LjEgNS42OUM4LjQ1IDQuNjMgMTAuMTUgNCAxMiA0YzQuNDIgMCA4IDMuNTggOCA4IDAgMS44NS0uNjMgMy41NS0xLjY5IDQuOXoiLz4KPC9zdmc+';
165 | /** */ }),
166 | /* 24 */
167 | /** */ (function (module, exports) {
168 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xOSAxOUg1VjVoN1YzSDVjLTEuMTEgMC0yIC45LTIgMnYxNGMwIDEuMS44OSAyIDIgMmgxNGMxLjEgMCAyLS45IDItMnYtN2gtMnY3ek0xNCAzdjJoMy41OWwtOS44MyA5LjgzIDEuNDEgMS40MUwxOSA2LjQxVjEwaDJWM2gtN3oiLz4KPC9zdmc+';
169 | /** */ }),
170 | /* 25 */
171 | /** */ (function (module, exports) {
172 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMS41IDlDMTAuMTIgOSA5IDEwLjEyIDkgMTEuNXMxLjEyIDIuNSAyLjUgMi41IDIuNS0xLjEyIDIuNS0yLjVTMTIuODggOSAxMS41IDl6TTIwIDRINGMtMS4xIDAtMiAuOS0yIDJ2MTJjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yem0tMy4yMSAxNC4yMWwtMi45MS0yLjkxYy0uNjkuNDQtMS41MS43LTIuMzkuN0M5LjAxIDE2IDcgMTMuOTkgNyAxMS41UzkuMDEgNyAxMS41IDcgMTYgOS4wMSAxNiAxMS41YzAgLjg4LS4yNiAxLjY5LS43IDIuMzlsMi45MSAyLjktMS40MiAxLjQyeiIvPgo8L3N2Zz4=';
173 | /** */ }),
174 | /* 26 */
175 | /** */ (function (module, exports) {
176 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xNCAxMEgydjJoMTJ2LTJ6bTAtNEgydjJoMTJWNnptNCA4di00aC0ydjRoLTR2Mmg0djRoMnYtNGg0di0yaC00ek0yIDE2aDh2LTJIMnYyeiIvPgo8L3N2Zz4=';
177 | /** */ }),
178 | /* 27 */
179 | /** */ (function (module, exports) {
180 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xMiA3Yy0yLjc2IDAtNSAyLjI0LTUgNXMyLjI0IDUgNSA1IDUtMi4yNCA1LTUtMi4yNC01LTUtNXptMC01QzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyem0wIDE4Yy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
181 | /** */ }),
182 | /* 28 */
183 | /** */ (function (module, exports) {
184 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xMiAyQzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyem0wIDE4Yy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
185 | /** */ }),
186 | /* 29 */
187 | /** */ (function (module, exports) {
188 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xOC40IDEwLjZDMTYuNTUgOC45OSAxNC4xNSA4IDExLjUgOGMtNC42NSAwLTguNTggMy4wMy05Ljk2IDcuMjJMMy45IDE2YzEuMDUtMy4xOSA0LjA1LTUuNSA3LjYtNS41IDEuOTUgMCAzLjczLjcyIDUuMTIgMS44OEwxMyAxNmg5VjdsLTMuNiAzLjZ6Ii8+Cjwvc3ZnPg==';
189 | /** */ }),
190 | /* 30 */
191 | /** */ (function (module, exports) {
192 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xNCAySDZjLTEuMSAwLTEuOTkuOS0xLjk5IDJMNCAyMGMwIDEuMS44OSAyIDEuOTkgMkgxOGMxLjEgMCAyLS45IDItMlY4bC02LTZ6bS0yIDE2Yy0yLjA1IDAtMy44MS0xLjI0LTQuNTgtM2gxLjcxYy42My45IDEuNjggMS41IDIuODcgMS41IDEuOTMgMCAzLjUtMS41NyAzLjUtMy41UzEzLjkzIDkuNSAxMiA5LjVjLTEuMzUgMC0yLjUyLjc4LTMuMSAxLjlsMS42IDEuNmgtNFY5bDEuMyAxLjNDOC42OSA4LjkyIDEwLjIzIDggMTIgOGMyLjc2IDAgNSAyLjI0IDUgNXMtMi4yNCA1LTUgNXoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+';
193 | /** */ }),
194 | /* 31 */
195 | /** */ (function (module, exports) {
196 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xOS40MyAxMi45OGMuMDQtLjMyLjA3LS42NC4wNy0uOThzLS4wMy0uNjYtLjA3LS45OGwyLjExLTEuNjVjLjE5LS4xNS4yNC0uNDIuMTItLjY0bC0yLTMuNDZjLS4xMi0uMjItLjM5LS4zLS42MS0uMjJsLTIuNDkgMWMtLjUyLS40LTEuMDgtLjczLTEuNjktLjk4bC0uMzgtMi42NUMxNC40NiAyLjE4IDE0LjI1IDIgMTQgMmgtNGMtLjI1IDAtLjQ2LjE4LS40OS40MmwtLjM4IDIuNjVjLS42MS4yNS0xLjE3LjU5LTEuNjkuOThsLTIuNDktMWMtLjIzLS4wOS0uNDkgMC0uNjEuMjJsLTIgMy40NmMtLjEzLjIyLS4wNy40OS4xMi42NGwyLjExIDEuNjVjLS4wNC4zMi0uMDcuNjUtLjA3Ljk4cy4wMy42Ni4wNy45OGwtMi4xMSAxLjY1Yy0uMTkuMTUtLjI0LjQyLS4xMi42NGwyIDMuNDZjLjEyLjIyLjM5LjMuNjEuMjJsMi40OS0xYy41Mi40IDEuMDguNzMgMS42OS45OGwuMzggMi42NWMuMDMuMjQuMjQuNDIuNDkuNDJoNGMuMjUgMCAuNDYtLjE4LjQ5LS40MmwuMzgtMi42NWMuNjEtLjI1IDEuMTctLjU5IDEuNjktLjk4bDIuNDkgMWMuMjMuMDkuNDkgMCAuNjEtLjIybDItMy40NmMuMTItLjIyLjA3LS40OS0uMTItLjY0bC0yLjExLTEuNjV6TTEyIDE1LjVjLTEuOTMgMC0zLjUtMS41Ny0zLjUtMy41czEuNTctMy41IDMuNS0zLjUgMy41IDEuNTcgMy41IDMuNS0xLjU3IDMuNS0zLjUgMy41eiIvPgo8L3N2Zz4=';
197 | /** */ }),
198 | /* 32 */
199 | /** */ (function (module, exports) {
200 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik02IDE4bDguNS02TDYgNnYxMnpNMTYgNnYxMmgyVjZoLTJ6Ii8+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+Cjwvc3ZnPg==';
201 | /** */ }),
202 | /* 33 */
203 | /** */ (function (module, exports) {
204 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik02IDZoMnYxMkg2em0zLjUgNmw4LjUgNlY2eiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz4=';
205 | /** */ }),
206 | /* 34 */
207 | /** */ (function (module, exports) {
208 | module.exports = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMi41IDhjLTIuNjUgMC01LjA1Ljk5LTYuOSAyLjZMMiA3djloOWwtMy42Mi0zLjYyYzEuMzktMS4xNiAzLjE2LTEuODggNS4xMi0xLjg4IDMuNTQgMCA2LjU1IDIuMzEgNy42IDUuNWwyLjM3LS43OEMyMS4wOCAxMS4wMyAxNy4xNSA4IDEyLjUgOHoiLz4KPC9zdmc+';
209 | /** */ }),
210 | /* 35 */
211 | /** */ (function (module, exports, __webpack_require__) {
212 | Object.defineProperty(exports, '__esModule', {
213 | value: true,
214 | });
215 | exports.credits = undefined;
216 | exports.checkBox = checkBox;
217 | exports.toggle = toggle;
218 |
219 | const _toggle_on = __webpack_require__(1);
220 |
221 | const _toggle_on2 = _interopRequireDefault(_toggle_on);
222 |
223 | const _toggle_off = __webpack_require__(0);
224 |
225 | const _toggle_off2 = _interopRequireDefault(_toggle_off);
226 |
227 | const _ic_announcement_black_18px = __webpack_require__(2);
228 |
229 | const _ic_announcement_black_18px2 = _interopRequireDefault(_ic_announcement_black_18px);
230 |
231 | const _ic_autorenew_black_18px = __webpack_require__(3);
232 |
233 | const _ic_autorenew_black_18px2 = _interopRequireDefault(_ic_autorenew_black_18px);
234 |
235 | const _ic_bookmark_border_black_18px = __webpack_require__(4);
236 |
237 | const _ic_bookmark_border_black_18px2 = _interopRequireDefault(_ic_bookmark_border_black_18px);
238 |
239 | const _ic_build_black_18px = __webpack_require__(5);
240 |
241 | const _ic_build_black_18px2 = _interopRequireDefault(_ic_build_black_18px);
242 |
243 | const _ic_check_box_black_24px = __webpack_require__(6);
244 |
245 | const _ic_check_box_black_24px2 = _interopRequireDefault(_ic_check_box_black_24px);
246 |
247 | const _ic_check_box_outline_blank_black_24px = __webpack_require__(7);
248 |
249 | const _ic_check_box_outline_blank_black_24px2 = _interopRequireDefault(_ic_check_box_outline_blank_black_24px);
250 |
251 | const _ic_clear_black_18px = __webpack_require__(8);
252 |
253 | const _ic_clear_black_18px2 = _interopRequireDefault(_ic_clear_black_18px);
254 |
255 | const _ic_code_black_18px = __webpack_require__(9);
256 |
257 | const _ic_code_black_18px2 = _interopRequireDefault(_ic_code_black_18px);
258 |
259 | const _ic_content_copy_black_18px = __webpack_require__(10);
260 |
261 | const _ic_content_copy_black_18px2 = _interopRequireDefault(_ic_content_copy_black_18px);
262 |
263 | const _ic_content_cut_black_18px = __webpack_require__(11);
264 |
265 | const _ic_content_cut_black_18px2 = _interopRequireDefault(_ic_content_cut_black_18px);
266 |
267 | const _ic_content_paste_black_18px = __webpack_require__(12);
268 |
269 | const _ic_content_paste_black_18px2 = _interopRequireDefault(_ic_content_paste_black_18px);
270 |
271 | const _ic_delete_black_18px = __webpack_require__(13);
272 |
273 | const _ic_delete_black_18px2 = _interopRequireDefault(_ic_delete_black_18px);
274 |
275 | const _ic_delete_forever_black_18px = __webpack_require__(14);
276 |
277 | const _ic_delete_forever_black_18px2 = _interopRequireDefault(_ic_delete_forever_black_18px);
278 |
279 | const _ic_fast_forward_black_18px = __webpack_require__(15);
280 |
281 | const _ic_fast_forward_black_18px2 = _interopRequireDefault(_ic_fast_forward_black_18px);
282 |
283 | const _ic_fast_rewind_black_18px = __webpack_require__(16);
284 |
285 | const _ic_fast_rewind_black_18px2 = _interopRequireDefault(_ic_fast_rewind_black_18px);
286 |
287 | const _ic_get_app_black_18px = __webpack_require__(17);
288 |
289 | const _ic_get_app_black_18px2 = _interopRequireDefault(_ic_get_app_black_18px);
290 |
291 | const _ic_help_outline_black_18px = __webpack_require__(18);
292 |
293 | const _ic_help_outline_black_18px2 = _interopRequireDefault(_ic_help_outline_black_18px);
294 |
295 | const _ic_highlight_off_black_18px = __webpack_require__(19);
296 |
297 | const _ic_highlight_off_black_18px2 = _interopRequireDefault(_ic_highlight_off_black_18px);
298 |
299 | const _ic_history_black_18px = __webpack_require__(20);
300 |
301 | const _ic_history_black_18px2 = _interopRequireDefault(_ic_history_black_18px);
302 |
303 | const _ic_library_add_black_18px = __webpack_require__(21);
304 |
305 | const _ic_library_add_black_18px2 = _interopRequireDefault(_ic_library_add_black_18px);
306 |
307 | const _ic_menu_black_18px = __webpack_require__(22);
308 |
309 | const _ic_menu_black_18px2 = _interopRequireDefault(_ic_menu_black_18px);
310 |
311 | const _ic_not_interested_black_18px = __webpack_require__(23);
312 |
313 | const _ic_not_interested_black_18px2 = _interopRequireDefault(_ic_not_interested_black_18px);
314 |
315 | const _ic_open_in_new_black_18px = __webpack_require__(24);
316 |
317 | const _ic_open_in_new_black_18px2 = _interopRequireDefault(_ic_open_in_new_black_18px);
318 |
319 | const _ic_playlist_add_black_18px = __webpack_require__(26);
320 |
321 | const _ic_playlist_add_black_18px2 = _interopRequireDefault(_ic_playlist_add_black_18px);
322 |
323 | const _ic_radio_button_checked_black_24px = __webpack_require__(27);
324 |
325 | const _ic_radio_button_checked_black_24px2 = _interopRequireDefault(_ic_radio_button_checked_black_24px);
326 |
327 | const _ic_radio_button_unchecked_black_24px = __webpack_require__(28);
328 |
329 | const _ic_radio_button_unchecked_black_24px2 = _interopRequireDefault(_ic_radio_button_unchecked_black_24px);
330 |
331 | const _ic_redo_black_18px = __webpack_require__(29);
332 |
333 | const _ic_redo_black_18px2 = _interopRequireDefault(_ic_redo_black_18px);
334 |
335 | const _ic_restore_page_black_18px = __webpack_require__(30);
336 |
337 | const _ic_restore_page_black_18px2 = _interopRequireDefault(_ic_restore_page_black_18px);
338 |
339 | const _ic_settings_black_18px = __webpack_require__(31);
340 |
341 | const _ic_settings_black_18px2 = _interopRequireDefault(_ic_settings_black_18px);
342 |
343 | const _ic_skip_next_black_18px = __webpack_require__(32);
344 |
345 | const _ic_skip_next_black_18px2 = _interopRequireDefault(_ic_skip_next_black_18px);
346 |
347 | const _ic_skip_previous_black_18px = __webpack_require__(33);
348 |
349 | const _ic_skip_previous_black_18px2 = _interopRequireDefault(_ic_skip_previous_black_18px);
350 |
351 | const _ic_undo_black_18px = __webpack_require__(34);
352 |
353 | const _ic_undo_black_18px2 = _interopRequireDefault(_ic_undo_black_18px);
354 |
355 | const _ic_pageview_black_24px = __webpack_require__(25);
356 |
357 | const _ic_pageview_black_24px2 = _interopRequireDefault(_ic_pageview_black_24px);
358 |
359 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
360 |
361 | const images = {
362 | announcement: _ic_announcement_black_18px2.default,
363 | autorenew: _ic_autorenew_black_18px2.default,
364 | bookmark_border: _ic_bookmark_border_black_18px2.default,
365 | build: _ic_build_black_18px2.default,
366 | check_box: _ic_check_box_black_24px2.default,
367 | check_box_outline_blank: _ic_check_box_outline_blank_black_24px2.default,
368 | clear: _ic_clear_black_18px2.default,
369 | code: _ic_code_black_18px2.default,
370 | content_copy: _ic_content_copy_black_18px2.default,
371 | content_cut: _ic_content_cut_black_18px2.default,
372 | content_paste: _ic_content_paste_black_18px2.default,
373 | delete_: _ic_delete_black_18px2.default,
374 | delete_forever: _ic_delete_forever_black_18px2.default,
375 | fast_forward: _ic_fast_forward_black_18px2.default,
376 | fast_rewind: _ic_fast_rewind_black_18px2.default,
377 | get_app: _ic_get_app_black_18px2.default,
378 | help_outline: _ic_help_outline_black_18px2.default,
379 | highlight_off: _ic_highlight_off_black_18px2.default,
380 | history: _ic_history_black_18px2.default,
381 | library_add: _ic_library_add_black_18px2.default,
382 | menu: _ic_menu_black_18px2.default,
383 | not_interested: _ic_not_interested_black_18px2.default,
384 | open_in_new: _ic_open_in_new_black_18px2.default,
385 | playlist_add: _ic_playlist_add_black_18px2.default,
386 | radio_button_checked: _ic_radio_button_checked_black_24px2.default,
387 | radio_button_unchecked: _ic_radio_button_unchecked_black_24px2.default,
388 | redo: _ic_redo_black_18px2.default,
389 | restore_page: _ic_restore_page_black_18px2.default,
390 | settings: _ic_settings_black_18px2.default,
391 | skip_next: _ic_skip_next_black_18px2.default,
392 | skip_previous: _ic_skip_previous_black_18px2.default,
393 | undo: _ic_undo_black_18px2.default,
394 | toggle_on: _toggle_on2.default,
395 | toggle_off: _toggle_off2.default,
396 | pageview: _ic_pageview_black_24px2.default,
397 | };
398 |
399 | exports.default = images;
400 | function checkBox(isOn) {
401 | if (isOn) return checked_box;
402 | return unchecked_box;
403 | }
404 |
405 | function toggle(isOn) {
406 | if (isOn) return _toggle_on2.default;
407 | return _toggle_off2.default;
408 | }
409 |
410 | const credits = exports.credits = '\nthis package uses:\n- Google Material Design svg icons (https://material.io/icons/)\n- Icons8 free png icon (https://icons8.com/)\n';
411 | /** */ }),
412 | /** ****/ ]));
413 | }));
414 |
--------------------------------------------------------------------------------
/src/Utils/uiTheme.js:
--------------------------------------------------------------------------------
1 | const uiThemeLight = {
2 | palette: {
3 | borderColor: '#e0e0e0',
4 | textColor: 'rgba(0, 0, 0, 0.87)',
5 | secondaryTextColor: 'rgba(0, 0, 0, 0.54)',
6 | inputTextColor: 'rgb(46, 84, 128)',
7 | canvas: '#ffffff',
8 | },
9 | };
10 |
11 | const currentTheme = {
12 | theme: uiThemeLight,
13 | };
14 |
15 | export default function getCurrentTheme() {
16 | return currentTheme.theme;
17 | }
18 |
--------------------------------------------------------------------------------
/src/Utils/ui_package.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | // import images from './svg_package';
4 |
5 | const images = {};
6 |
7 | const iconStyle = {
8 | width: 18,
9 | opacity: 0.6,
10 | marginRight: 8
11 | };
12 |
13 | const buttonStyle = {
14 | backgroundColor: 'rgba(0, 0, 0, 0)',
15 | border: 'none',
16 | outline: 'none',
17 | padding: 0,
18 | margin: 4,
19 | display: 'flex',
20 | alignItems: 'center',
21 | fontFamily:
22 | '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif', // eslint-disable-line
23 | cursor: 'pointer',
24 | fontSize: 12,
25 | textDecoration: 'none',
26 | color: 'black'
27 | };
28 |
29 | const selectStyle = {
30 | ...buttonStyle,
31 | border: '#d9d9d9 1px solid',
32 | borderRadius: 2,
33 | backgroundColor: '#e8e8e8',
34 | padding: 2,
35 | boxShadow: '0px 0px 2px 0px rgba(0, 0, 0, 0.5)',
36 | fontSize: 14,
37 | width: '100%'
38 | };
39 |
40 | const optionsStyle = {
41 | backgroundColor: '#fcfcfc',
42 | height: 50
43 | // border: '#2e63ac 4px solid',
44 | };
45 |
46 | export function Button({ icon, label, title, onClick, compact, disabled }) {
47 | // const iconStyleAply = iconStyle;
48 | const iconOverride = !label || compact ? { margin: 0 } : {};
49 | // if (!label || compact) iconStyleAply.margin = 0;
50 |
51 | return (
52 |
57 |
62 | {(!compact && label) || ''}
63 |
64 | );
65 | }
66 |
67 | Button.propTypes = {
68 | icon: PropTypes.string,
69 | label: PropTypes.string,
70 | title: PropTypes.string,
71 | onClick: PropTypes.func
72 | };
73 |
74 | export function Link({ icon, label, title, href }) {
75 | return (
76 |
83 |
84 | {label}
85 |
86 | );
87 | }
88 |
89 | Link.propTypes = {
90 | icon: PropTypes.string,
91 | label: PropTypes.string,
92 | title: PropTypes.string,
93 | href: PropTypes.string
94 | };
95 |
96 | Button.propTypes = {
97 | icon: PropTypes.string,
98 | label: PropTypes.string,
99 | title: PropTypes.string
100 | };
101 |
102 | export function CheckBox({ checked, label, title, onToggle }) {
103 | const toggle = () => onToggle(!checked);
104 | const selectTitle = is => (is ? title[1] : title[0]);
105 | const titleString = typeof title === 'string' ? title : selectTitle(checked);
106 |
107 | return (
108 |
109 |
114 | {label}
115 |
116 | );
117 | }
118 |
119 | CheckBox.propTypes = {
120 | checked: PropTypes.bool,
121 | label: PropTypes.string,
122 | title: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
123 | onToggle: PropTypes.func
124 | };
125 |
126 | export function Toggle({ checked, label, title, onToggle }) {
127 | const toggle = () => onToggle(!checked);
128 | const selectTitle = is => (is ? title[1] : title[0]);
129 | const titleString = typeof title === 'string' ? title : selectTitle(checked);
130 |
131 | return (
132 |
137 |
147 | {label}
148 |
149 | );
150 | }
151 |
152 | Toggle.propTypes = {
153 | checked: PropTypes.bool,
154 | label: PropTypes.string,
155 | title: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
156 | onToggle: PropTypes.func
157 | };
158 |
159 | export function Dropdown({ selected, list, title, onSelect }) {
160 | const options = list.map((val, ind) => (
161 |
162 | {val}
163 |
164 | ));
165 | const select = event => onSelect(parseInt(event.target.value, 10));
166 |
167 | return (
168 |
174 | {options}
175 |
176 | );
177 | }
178 |
179 | Dropdown.propTypes = {
180 | selected: PropTypes.number,
181 | title: PropTypes.string,
182 | list: PropTypes.arrayOf(PropTypes.string),
183 | onSelect: PropTypes.func
184 | };
185 |
186 | const paperStyle = {
187 | boxShadow: 'rgba(0, 0, 0, 0.2) 0px 1px 6px',
188 | // padding: '8px 8px 8px 16px',
189 | borderRadius: 2,
190 | boxSizing: 'border-box',
191 | fontFamily:
192 | '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif', // eslint-disable-line
193 | fontSize: 12,
194 | marginBottom: 10
195 | };
196 |
197 | export function Paper({ children, style }) {
198 | return {children}
;
199 | }
200 |
201 | Paper.propTypes = {
202 | children: PropTypes.node,
203 | style: PropTypes.shape()
204 | };
205 |
206 | const tagStyle = {
207 | backgroundColor: 'rgb(224, 224, 224)',
208 | border: 'black',
209 | borderRadius: 11,
210 | display: 'flex',
211 | alignItems: 'center',
212 | fontSize: 11,
213 | cursor: 'pointer'
214 | };
215 |
216 | const avaStyle = {
217 | width: 22,
218 | height: 22,
219 | borderRadius: 11,
220 | backgroundColor: 'rgb(188, 188, 188)',
221 | color: '#efefef',
222 | fontSize: 14,
223 | fontWeight: 600,
224 | textTransform: 'uppercase',
225 | display: 'inline-flex',
226 | alignItems: 'center',
227 | justifyContent: 'center'
228 | };
229 |
230 | export function Tag({ label, onClick }) {
231 | return (
232 |
233 |
234 | {label[0] || '!'}
235 |
236 |
{label}
237 |
238 | );
239 | }
240 |
241 | Paper.propTypes = {
242 | label: PropTypes.string,
243 | onClick: PropTypes.func
244 | };
245 |
--------------------------------------------------------------------------------
/src/adk/ChannelHOC.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | // class WithChannel extends React.Component {
5 | // state = {
6 | // data: { lala: 123 }
7 | // };
8 |
9 | // render() {
10 | // const { component: Component, extProps } = this.props;
11 | // const { data } = this.state;
12 | // const dname = Component.displayName;
13 | // console.log('TCL: WithChannel -> render -> dname', dname);
14 | // return ;
15 | // }
16 | // }
17 |
18 | function getDisplayName(WrappedComponent) {
19 | return WrappedComponent.displayName || WrappedComponent.name || 'Component';
20 | }
21 |
22 | function withChannel(WrappedComponent) {
23 | class WithChannel extends React.Component {
24 | state = {
25 | data: 123
26 | };
27 |
28 | render() {
29 | return ;
30 | }
31 | }
32 | WithChannel.displayName = `WithSubscription(${getDisplayName(
33 | WrappedComponent
34 | )})`;
35 | return WithChannel;
36 | }
37 |
38 | // const withChannel = params => Component => props => (
39 | //
40 | // );
41 |
42 | export default withChannel;
43 |
--------------------------------------------------------------------------------
/src/adk/ChannelStore.js:
--------------------------------------------------------------------------------
1 | import addons from '@storybook/addons';
2 |
3 | export default class ChannelStore {
4 | constructor({
5 | EVENT_ID_INIT,
6 | EVENT_ID_DATA,
7 | EVENT_ID_BACK,
8 | name = 'store',
9 | initData = {},
10 | isPanel = false,
11 | }) {
12 | this.store = initData;
13 | this.name = name;
14 | this.subscriber = () => {};
15 | this.onConnectedFn = () => {};
16 | this.channel = addons.getChannel();
17 |
18 | this.connect = () => {
19 | this.channel.on(EVENT_ID_INIT, this.onInitChannel);
20 | this.channel.on(isPanel ? EVENT_ID_DATA : EVENT_ID_BACK, this.onDataChannel);
21 | this.onConnectedFn();
22 | };
23 | this.emit = data => this.channel.emit(isPanel ? EVENT_ID_BACK : EVENT_ID_DATA, data);
24 | this.init = data => this.channel.emit(EVENT_ID_INIT, data);
25 | this.removeInit = () =>
26 | this.channel.removeListener(EVENT_ID_INIT, this.onInitChannel);
27 | this.removeData = () =>
28 | this.channel.removeListener(EVENT_ID_DATA, this.onDataChannel);
29 | }
30 |
31 | onInitChannel = initData => {
32 | this.store = initData;
33 | this.subscriber(this.store);
34 | };
35 |
36 | onDataChannel = updData => {
37 | this.store = {
38 | ...this.store,
39 | ...updData
40 | };
41 | this.subscriber(this.store);
42 | };
43 |
44 | onData = subscriberFn => {
45 | this.subscriber = subscriberFn;
46 | };
47 |
48 | onConnected = onConnectedFn => {
49 | this.onConnectedFn = onConnectedFn;
50 | };
51 |
52 | send = data => {
53 | this.store = {
54 | ...this.store,
55 | ...data
56 | };
57 | this.emit(this.store);
58 | this.subscriber(this.store);
59 | };
60 |
61 | sendInit = data => {
62 | this.init(data);
63 | };
64 |
65 | disconnect = () => {
66 | this.removeInit();
67 | this.removeData();
68 | };
69 | }
70 |
--------------------------------------------------------------------------------
/src/adk/WithChannel.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import ChannelStore from './ChannelStore';
4 |
5 | const getDisplayName = WrappedComponent =>
6 | WrappedComponent.displayName || WrappedComponent.name || 'Component';
7 |
8 | const withChannel = ({
9 | EVENT_ID_INIT,
10 | EVENT_ID_DATA,
11 | EVENT_ID_BACK,
12 | initData,
13 | panel
14 | }) => WrappedComponent =>
15 | class extends React.Component {
16 | static displayName = `WithChannel(${getDisplayName(WrappedComponent)})`;
17 |
18 | state = {
19 | data: initData || this.props.initData
20 | };
21 |
22 | store = new ChannelStore({
23 | EVENT_ID_INIT,
24 | EVENT_ID_DATA,
25 | EVENT_ID_BACK,
26 | name: this.props.pointName,
27 | initData: initData || this.props.initData,
28 | isPanel: panel || this.props.panel
29 | });
30 |
31 | componentDidMount() {
32 | this.store.onData(this.onData);
33 | if (this.state.data) {
34 | this.store.onConnected(() => this.store.send(this.state.data));
35 | }
36 | this.store.connect();
37 | }
38 |
39 | componentWillUnmount() {
40 | this.store.disconnect();
41 | }
42 |
43 | onData = data => this.setState({ data });
44 |
45 | render() {
46 | const { pointName, initData, active, ...props } = this.props;
47 | if (active === false) return null;
48 | return (
49 |
55 | );
56 | }
57 | };
58 |
59 | export default withChannel;
60 |
--------------------------------------------------------------------------------
/src/adk/decorator.js:
--------------------------------------------------------------------------------
1 | import ChannelStore from './ChannelStore';
2 |
3 | let decoratorStore;
4 |
5 | export const createStore = (...args) => {
6 | decoratorStore = new ChannelStore(...args);
7 | return decoratorStore;
8 | };
9 |
10 | export const getStore = () => decoratorStore;
11 |
--------------------------------------------------------------------------------
/src/adk/panel.js:
--------------------------------------------------------------------------------
1 | import ChannelStore from './ChannelStore';
2 |
3 | let panelStore;
4 |
5 | export const createStore = (EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK) => {
6 | panelStore = new ChannelStore(EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK);
7 | return panelStore;
8 | };
9 |
10 | export const getStore = () => panelStore;
11 |
--------------------------------------------------------------------------------
/src/components/AddonPanel.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Toggle, Link, Button, Dropdown, Paper } from '../Utils/ui_package';
4 |
5 | const propTypes = {
6 | themesNameList: PropTypes.arrayOf(PropTypes.string).isRequired,
7 | defautThemeInd: PropTypes.number.isRequired,
8 | onThemeSelect: PropTypes.func.isRequired,
9 | onToggleSideBar: PropTypes.func.isRequired,
10 | isSideBarOpen: PropTypes.bool.isRequired,
11 | isThemeInvalid: PropTypes.bool.isRequired,
12 | themeJSON: PropTypes.string.isRequired,
13 | onChangeTheme: PropTypes.func.isRequired,
14 | onThemeEditing: PropTypes.func.isRequired,
15 | onCloneTheme: PropTypes.func.isRequired,
16 | onDnLoadTheme: PropTypes.func.isRequired,
17 | onCleanTheme: PropTypes.func.isRequired,
18 | issuesLink: PropTypes.string,
19 | };
20 |
21 | const defaultProps = {
22 | themesNameList: ['BaseLight', 'BaseDark'],
23 | defautThemeInd: 0,
24 | onThemeSelect: () => {},
25 | onToggleSideBar: () => {},
26 | isSideBarOpen: false,
27 | onCloneTheme: () => {},
28 | onDnLoadTheme: () => {},
29 | onCleanTheme: () => {},
30 | issuesLink: 'https://github.com/sm-react/storybook-addon-material-ui/issues/new',
31 | };
32 |
33 | const contextTypes = {
34 | muiTheme: PropTypes.object,
35 | };
36 |
37 | export default class AddonPanel extends React.Component {
38 | constructor(props) {
39 | super(props);
40 |
41 | this.state = {
42 | value: props.defautThemeInd,
43 | isThemeEditing: false,
44 | isThemeValid: true,
45 | theme: props.themeJSON,
46 | };
47 |
48 | this.handleChange = this.handleChange.bind(this);
49 | }
50 |
51 | handleChange(value) {
52 | this.setState({ value }, this.props.onThemeSelect(value));
53 | }
54 |
55 | handleThemeChange = ev => this.setState({ theme: ev.target.value });
56 |
57 | render() {
58 | const styleArea = {
59 | width: '100%',
60 | // height: '100%',
61 | outlineColor: this.props.isThemeInvalid ? '#cc5858' : '#26acd8',
62 | flexGrow: 1,
63 | };
64 | const buttonStyle = {
65 | height: 34,
66 | width: 34,
67 | fontSize: 10,
68 | fontFamily:
69 | '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
70 | marginBottom: 4,
71 | };
72 | return (
73 |
82 |
91 |
92 |
98 |
99 |
110 |
116 |
122 |
128 |
129 |
130 |
140 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
163 |
170 | this.props.onChangeTheme(this.state.theme)}>Apply
171 |
172 |
173 |
174 |
183 |
190 |
196 |
204 | Vote for the most useful features
205 |
206 |
207 |
212 | {'> HERE <'}
213 |
214 |
215 |
216 |
217 |
223 |
229 |
230 |
231 |
232 | );
233 | }
234 | }
235 |
236 | AddonPanel.propTypes = propTypes;
237 | AddonPanel.defaultProps = defaultProps;
238 | AddonPanel.contextTypes = contextTypes;
239 |
--------------------------------------------------------------------------------
/src/components/ThemePropBlock.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Paper from '@material-ui/core/Paper';
4 | import SclToggle from '../material-desktop/SclToggle';
5 | import SclAvatar from '../material-desktop/SclAvatar';
6 |
7 | import { CSS_CLASS } from '../';
8 | import ThemePropItem from './ThemePropItem';
9 |
10 |
11 | const propTypes = {
12 | settingsObj: PropTypes.object.isRequired,
13 | settingsName: PropTypes.string.isRequired,
14 | open: PropTypes.func.isRequired,
15 | onThemeTableOverride: PropTypes.func.isRequired,
16 | onSelect: PropTypes.func.isRequired,
17 | };
18 |
19 | const contextTypes = {
20 | muiTheme: PropTypes.object.isRequired,
21 | };
22 |
23 | export default class ThemePropBlock extends React.Component {
24 | constructor(props, ...args) {
25 | super(props, ...args);
26 | this.state = {
27 | toolCollapsedList: {},
28 | };
29 | this.needComponentUpdate = false;
30 | this.valueHandler = this.valueHandler.bind(this);
31 | this.onToolCollapse = this.onToolCollapse.bind(this);
32 | this.onSelect = this.onSelect.bind(this);
33 | this.renderProp = this.renderProp.bind(this);
34 | this.renderColl = this.renderColl.bind(this);
35 | }
36 |
37 | shouldComponentUpdate() {
38 | const f = this.needComponentUpdate;
39 | this.needComponentUpdate = false;
40 | return f;
41 | }
42 |
43 | onToolCollapse(val) {
44 | return (isCol) => {
45 | const { toolCollapsedList } = this.state;
46 | toolCollapsedList[val] = isCol;
47 | this.needComponentUpdate = true;
48 | this.setState({ toolCollapsedList });
49 | };
50 | }
51 |
52 | onSelect(sel) {
53 | const select = {
54 | selectedTable: this.props.settingsName,
55 | selectedProp: '',
56 | selectedVal: '',
57 | };
58 | const fullSelect = Object.assign(select, sel);
59 | this.props.onSelect(fullSelect);
60 | }
61 |
62 | valueHandler(propName) {
63 | return (event) => {
64 | this.needComponentUpdate = true;
65 | this.props.onThemeTableOverride(propName, event.target.value);
66 | };
67 | }
68 |
69 | renderProp(val, ind, isOpen, isHeader) {
70 | return (
71 |
72 | {isOpen ? : null}
83 |
84 |
85 | );
86 | }
87 |
88 | renderColl() {
89 | const settingsObj = this.props.settingsObj;
90 | const keyList = Object.keys(settingsObj);
91 | const rowList = keyList.map((val, ind) => (this.renderProp(val, ind, this.props.open())));
92 | return (
93 |
94 | {this.renderProp(`${this.props.settingsName}-header`, 0, this.props.open(), true)}
95 | {rowList}
96 |
);
97 | }
98 |
99 | render() {
100 | const { settingsName, open } = this.props;
101 | const onSelect = this.onSelect;
102 | const openThis = (f) => {
103 | if (typeof (f) === 'undefined') return open();
104 | this.needComponentUpdate = true;
105 | open(f);
106 | return null;
107 | };
108 | return (
109 |
118 |
119 |
120 |
121 | {this.renderColl()}
122 |
123 |
124 | );
125 | }
126 | }
127 |
128 | ThemePropBlock.propTypes = propTypes;
129 | ThemePropBlock.contextTypes = contextTypes;
130 |
131 | function BlockHeader(props, context) {
132 | const toggleHeadStyle = {
133 | color: context.muiTheme.palette.primary1Color,
134 | fontSize: context.muiTheme.flatButton.fontSize,
135 | };
136 | const toggleOpen = () => {
137 | props.openThis(!props.openThis());
138 | };
139 | return (
140 |
147 |
151 | {/*
152 |
153 | {props.settingsName[0]}
154 | {props.settingsName}
155 | */}
156 |
157 |
158 |
165 |
166 |
167 |
168 | );
169 | }
170 |
171 | BlockHeader.contextTypes = contextTypes;
172 | BlockHeader.propTypes = {
173 | openThis: PropTypes.func.isRequired,
174 | onSelect: PropTypes.func.isRequired,
175 | settingsName: PropTypes.string.isRequired,
176 | };
177 |
--------------------------------------------------------------------------------
/src/components/ThemePropItem.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Tab from '@material-ui/core/Tab';
4 | import Tabs from '@material-ui/core/Tabs';
5 | import Slider from '@material-ui/core/Slide';
6 | import MaterialColorPicker from '@usulpro/color-picker';
7 |
8 | import { CSS_CLASS } from '../';
9 |
10 | const propTypes = {
11 | val: PropTypes.string.isRequired,
12 | ind: PropTypes.number.isRequired,
13 | settingsObj: PropTypes.object.isRequired,
14 | valueHandler: PropTypes.func.isRequired,
15 | isCollapsed: PropTypes.bool.isRequired,
16 | onCollapsed: PropTypes.func.isRequired,
17 | onSelect: PropTypes.func.isRequired,
18 | isOpen: PropTypes.bool.isRequired,
19 | isHeader: PropTypes.bool.isRequired,
20 | };
21 |
22 | const defaultProps = {
23 | val: 'val',
24 | ind: 7,
25 | settingsObj: {},
26 | valueHandler: () => {},
27 | isCollapsed: true,
28 | isOpen: true,
29 | isHeader: true,
30 | };
31 |
32 | const contextTypes = {
33 | muiTheme: PropTypes.object.isRequired,
34 | };
35 |
36 | export default class ThemePropItem extends React.Component {
37 | constructor(props, ...args) {
38 | super(props, ...args);
39 |
40 | this.onToolTogle = this.onToolTogle.bind(this);
41 | this.renderProp = this.renderProp.bind(this);
42 | }
43 |
44 | shouldComponentUpdate(nextProps) {
45 | return true;
46 | // future: shouldComponentUpdate
47 | // const val = this.props.val;
48 | // const shouldCollapsed = (nextProps.isCollapsed !== this.props.isCollapsed);
49 | // const shouldOpen = (nextProps.isOpen !== this.props.isOpen);
50 | // const shouldsettingsObj = (nextProps.settingsObj[val] !== this.props.settingsObj[val]);
51 | // const shouldUpdate = (shouldCollapsed || shouldOpen || shouldsettingsObj);
52 | // if (shouldUpdate) {
53 | // console.log(
54 | // `shouldUpdate: ${val} ${shouldCollapsed} ${shouldOpen} ${shouldsettingsObj}`
55 | // );
56 | // }
57 | // return shouldUpdate;
58 | }
59 |
60 | onToolTogle() {
61 | this.props.onCollapsed(!this.props.isCollapsed);
62 | }
63 |
64 | renderProp(isNotHeader) {
65 | const { palette } = this.context.muiTheme;
66 | const { ind, val, valueHandler, isCollapsed, isOpen, onSelect } = this.props;
67 | const settingsObj = this.props.settingsObj || { isNotHeader };
68 | const onToolTogle = this.onToolTogle;
69 | const styleHR = { borderBottom: `solid ${palette.borderColor} 1px` };
70 | return (
71 |
86 | );
87 | }
88 |
89 | render() {
90 | return (
91 |
92 | {this.renderProp(!this.props.isHeader)}
93 |
94 |
95 | );
96 | }
97 | }
98 |
99 | ThemePropItem.propTypes = propTypes;
100 | ThemePropItem.defaultProps = defaultProps;
101 | ThemePropItem.contextTypes = contextTypes;
102 |
103 | function PropItem(props, context) {
104 | const { palette } = context.muiTheme;
105 | const { settingsObj, val, ind, valueHandler, /* isOpen,*/ isNotHeader } = props;
106 | const color = typeof (settingsObj[val]) === 'string' ? settingsObj[val] : '';
107 | const onSelect = () => {
108 | const select = {
109 | selectedProp: val,
110 | selectedVal: `'${settingsObj[val]}'`,
111 | };
112 | props.onSelect(select);
113 | };
114 | return (
115 |
157 | );
158 | }
159 |
160 | PropItem.propTypes = {
161 | settingsObj: PropTypes.shape().isRequired,
162 | val: PropTypes.string.isRequired,
163 | ind: PropTypes.number.isRequired,
164 | onToolTogle: PropTypes.func.isRequired,
165 | onSelect: PropTypes.func.isRequired,
166 | valueHandler: PropTypes.func.isRequired,
167 | // isOpen: PropTypes.bool.isRequired,
168 | isNotHeader: PropTypes.bool.isRequired,
169 | };
170 | PropItem.contextTypes = contextTypes;
171 |
172 | function PropHeader(props, context) {
173 | const { ind, val, isNotHeader } = props;
174 | return (
175 |
187 |
188 | {isNotHeader ? ind + 1 : '#'}
189 |
190 |
199 |
{isNotHeader ? val : 'Prop Name'}
200 |
201 |
202 | );
203 | }
204 | PropHeader.propTypes = {
205 | val: PropTypes.string.isRequired,
206 | ind: PropTypes.number.isRequired,
207 | isNotHeader: PropTypes.bool.isRequired,
208 | };
209 | PropHeader.contextTypes = contextTypes;
210 |
211 | function PropInput(props, context) {
212 | const { palette } = context.muiTheme;
213 | const { valueHandler, settingsObj, isNotHeader } = props;
214 | const isInt = (settingsObj === parseInt(settingsObj, 10));
215 | const strStyle = {
216 | width: isInt ? 40 : 'auto',
217 | textAlign: isInt ? 'right' : 'left',
218 | };
219 | return (isNotHeader ?
220 | :
234 |
242 | Prop Value
243 |
244 | );
245 | }
246 | PropInput.propTypes = {
247 | settingsObj: PropTypes.oneOfType([
248 | PropTypes.string,
249 | PropTypes.number,
250 | ]).isRequired,
251 | valueHandler: PropTypes.func.isRequired,
252 | isNotHeader: PropTypes.bool.isRequired,
253 | };
254 | PropInput.contextTypes = contextTypes;
255 |
256 | function PropTool(props, context) {
257 | const { palette } = context.muiTheme;
258 | const { isNotHeader } = props;
259 | const blockStyle = {
260 | width: 16,
261 | height: 16,
262 | marginLeft: 4,
263 | border: `solid 1px ${palette.borderColor}`,
264 | backgroundColor: isNotHeader ? props.color : 'rgba(0, 0, 0, 0)',
265 | cursor: isNotHeader ? 'pointer' : '',
266 | };
267 | const toolProps = {
268 | style: blockStyle,
269 | title: isNotHeader ? props.color : 'view',
270 | onClick: isNotHeader ? props.onTool : null,
271 | };
272 | return
;
273 | }
274 | PropTool.propTypes = {
275 | isNotHeader: PropTypes.bool.isRequired,
276 | color: PropTypes.string.isRequired,
277 | onTool: PropTypes.func.isRequired,
278 | };
279 | PropTool.contextTypes = contextTypes;
280 |
281 |
282 | function PropToolPicker(props, context) {
283 | const { settingsObj, valueHandler, onToolTogle } = props;
284 | const initColor = `${settingsObj}`;
285 | const style = {
286 | height: props.isCollapsed ? 0 : 200,
287 | transition: 'height 300ms ease 0ms',
288 | overflow: 'hidden',
289 | };
290 | const onSubmit = (event) => {
291 | valueHandler(event);
292 | onToolTogle();
293 | };
294 | // fixme: check onReset
295 | return (
296 |
307 | );
308 | }
309 | PropToolPicker.propTypes = {
310 | settingsObj: PropTypes.oneOfType([
311 | PropTypes.string,
312 | PropTypes.number,
313 | ]).isRequired,
314 | isCollapsed: PropTypes.bool.isRequired,
315 | valueHandler: PropTypes.func.isRequired,
316 | onToolTogle: PropTypes.func.isRequired,
317 | };
318 | PropToolPicker.contextTypes = contextTypes;
319 |
320 | // future: we will use when all components be ready
321 | function PropToolPickerFull(props, context) {
322 | const { settingsObj, valueHandler, onToolTogle } = props;
323 | const initColor = `${settingsObj}`;
324 | const style = {
325 | height: props.isCollapsed ? 0 : 200,
326 | transition: 'height 300ms ease 0ms',
327 | overflow: 'hidden',
328 | };
329 | const tabStyle = { height: 16, marginTop: -12, fontSize: 12 };
330 | const onSubmit = (event) => {
331 | valueHandler(event);
332 | onToolTogle();
333 | };
334 | return (
335 |
336 |
339 |
343 |
344 |
350 |
351 |
352 |
353 |
354 |
Tab Two
355 |
356 | This is another example tab.
357 |
358 | {/*
*/}
359 |
360 |
361 |
367 |
368 |
Tab Three
369 |
370 | This is a third example tab.
371 |
372 |
373 |
374 |
375 |
376 |
Tab Two
377 |
378 | This is another example tab.
379 |
380 |
381 |
382 |
383 |
384 |
385 |
Tab Two
386 |
387 | This is another example tab.
388 |
389 |
390 |
391 |
392 |
393 |
394 | );
395 | }
396 | PropToolPickerFull.propTypes = {
397 | settingsObj: PropTypes.shape().isRequired,
398 | isCollapsed: PropTypes.bool.isRequired,
399 | valueHandler: PropTypes.func.isRequired,
400 | onToolTogle: PropTypes.func.isRequired,
401 | };
402 | PropToolPickerFull.contextTypes = contextTypes;
403 |
--------------------------------------------------------------------------------
/src/components/ThemeSideBar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Paper from '@material-ui/core/Paper';
4 | import IconCopy from '@material-ui/icons/ContentCopy';
5 | import IconSwch from '@material-ui/icons/SwitchCamera';
6 |
7 | import SclToggle from '../material-desktop/SclToggle';
8 | import SvgButton from '../material-desktop/SvgButton';
9 |
10 |
11 | import { CSS_CLASS } from '../';
12 | import ThemePropBlock from './ThemePropBlock';
13 | import { copyToClipboardThis } from '../Utils';
14 |
15 | const BAR_WIDTH = 400;
16 |
17 | const propTypes = {
18 | open: PropTypes.bool.isRequired,
19 | themeName: PropTypes.string.isRequired,
20 | theme: PropTypes.object.isRequired,
21 | muiTheme: PropTypes.object.isRequired,
22 | fullTheme: PropTypes.func.isRequired,
23 | shouldComponentUpdate: PropTypes.bool.isRequired,
24 | shouldShowData: PropTypes.bool.isRequired,
25 | };
26 |
27 | export default class ThemeSideBar extends React.Component {
28 | constructor(props) {
29 | super(props);
30 | this.state = {
31 | selectedTable: '',
32 | selectedProp: '',
33 | selectedVal: '',
34 | isSelectedStyleObj: true,
35 | };
36 |
37 | this.clipString = this.clipString.bind(this);
38 | this.onSelect = this.onSelect.bind(this);
39 | this.onSwitchStyleObj = this.onSwitchStyleObj.bind(this);
40 | this.onCopy = this.onCopy.bind(this);
41 | }
42 |
43 | shouldComponentUpdate(nextProps, nextState) {
44 | // fixme shouldComponentUpdate - remove
45 | return nextProps.shouldComponentUpdate;
46 | }
47 |
48 | onSelect(sel) {
49 | this.setState(sel);
50 | }
51 |
52 | onSwitchStyleObj() {
53 | const isObj = this.state.isSelectedStyleObj;
54 | this.setState({ isSelectedStyleObj: !isObj });
55 | }
56 |
57 | onCopy() {
58 | const text = this.clipString();
59 | copyToClipboardThis(text);
60 | }
61 |
62 | clipString() {
63 | const table = this.state.selectedTable;
64 | const prop = this.state.selectedProp;
65 | const val = this.state.selectedVal;
66 | const isObj = this.state.isSelectedStyleObj;
67 |
68 | const strTbl = table;
69 | const strVal = isObj ? `${prop}: ${val},` : `${table}.${prop} = ${val};`;
70 | return prop ? strVal : strTbl;
71 | }
72 |
73 | renderContent() {
74 | const { palette } = this.context.muiTheme;
75 | const styleHR = { borderBottom: `solid ${palette.borderColor} 1px` };
76 | const blockStyle = {
77 | width: 21,
78 | height: 21,
79 | marginLeft: 4,
80 | border: `solid 1px ${palette.borderColor}`,
81 | backgroundColor: 'rgba(0, 0, 0, 0)',
82 | cursor: 'pointer',
83 | };
84 | return (
85 |
95 |
96 |
97 |
105 | {`${this.props.themeName} properties`}
106 |
107 |
108 |
117 |
122 | Theme Settings
123 |
124 |
this.props.fullTheme(!this.props.fullTheme())}
130 | />
131 | Full Settings
136 |
137 |
143 |
157 |
173 |
}
175 | tooltip="Copy to clipboard"
176 | width={48}
177 | onTouchTap={this.onCopy}
178 | />
179 |
180 |
}
182 | tooltip="switch style"
183 | width={48}
184 | onTouchTap={this.onSwitchStyleObj}
185 | />
186 |
187 |
188 |
189 |
190 | {this.props.shouldShowData ?
191 | themesList(
192 | this.props.fullTheme() ? this.props.muiTheme : this.props.theme,
193 | this.props, this.onSelect,
194 | )
195 | : null}
196 |
197 | );
198 | }
199 |
200 | render() {
201 | // const barWidth = this.props.open ? BAR_WIDTH : 0; // fixme BAR_WIDTH
202 |
203 | return (
204 |
208 | {this.props.open ? this.renderContent() : null}
209 |
210 | );
211 | }
212 |
213 | }
214 |
215 | ThemeSideBar.propTypes = propTypes;
216 |
217 | ThemeSideBar.contextTypes = {
218 | muiTheme: PropTypes.object.isRequired,
219 | };
220 |
221 | function forTable(tableTame, objListFunc) {
222 | return (val) => {
223 | const objList = objListFunc();
224 | const obj = objList[tableTame];
225 | if (val == undefined) {
226 | return obj;
227 | }
228 | objList[tableTame] = val;
229 | objListFunc(objList);
230 | return val;
231 | };
232 | }
233 |
234 | function themesList(themeObj, _props, onSelect) {
235 | const onThemeTableOverride = (tableName) => {
236 | return (propName, value) => {
237 | const overTheme = {};
238 | if (tableName === 'miscellaneous') {
239 | overTheme[propName] = value;
240 | _props.onThemeOverride(overTheme);
241 | return;
242 | }
243 | overTheme[tableName] = {};
244 | overTheme[tableName][propName] = value;
245 | _props.onThemeOverride(overTheme);
246 | };
247 | };
248 |
249 | const themePropTable = (tableName, table) => (
250 |
259 | );
260 |
261 |
262 | const keyList = Object.keys(themeObj);
263 |
264 | const strList = {};
265 | keyList.forEach((val) => {
266 | if (typeof (themeObj[val]) === 'string') {
267 | strList[val] = themeObj[val];
268 | }
269 | });
270 |
271 | const strListNode = themePropTable('miscellaneous', strList);
272 | const paletteList = themeObj.palette ? themePropTable('palette', themeObj.palette)
273 | : {'No palette here'}
;
274 |
275 | const tablesListObj = keyList.map((val) => {
276 | if (typeof (themeObj[val]) === 'object' && val !== 'palette') {
277 | return (themePropTable(val, themeObj[val])
278 | );
279 | }
280 | return null;
281 | });
282 |
283 | const scrollStyle = {
284 | height: '100%',
285 | overflowY: 'scroll',
286 | };
287 | return (
288 |
297 |
301 |
308 |
309 | {paletteList}
310 | {tablesListObj}
311 | {strListNode}
312 |
313 |
314 |
315 |
316 |
317 | );
318 | }
319 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | export const ADDON_ID = 'sm/storybook-addon-material-ui';
2 | export const PANEL_ID = `${ADDON_ID}/material-panel`;
3 | export const EVENT_ID_INIT = `${ADDON_ID}/material-event/init`;
4 | export const EVENT_ID_DATA = `${ADDON_ID}/material-event/data`;
5 | export const EVENT_ID_BACK = `${ADDON_ID}/material-event/back`;
6 | export const CSS_CLASS = 'sb-addon-material-ui';
7 |
--------------------------------------------------------------------------------
/src/containers/MuiTheme.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
5 | import createPalette from '@material-ui/core/styles/createPalette';
6 | import purple from '@material-ui/core/colors/purple';
7 | import green from '@material-ui/core/colors/green';
8 | import red from '@material-ui/core/colors/red';
9 |
10 | import { EVENT_ID_DATA, EVENT_ID_BACK } from '../config';
11 | import { lightTheme } from '../.themes';
12 | // future: [x] remove ThemeToolbar
13 | // import ThemeSideBar from '../components/ThemeSideBar';
14 | // const stringify = require('json-stringify-safe');
15 |
16 | const propTypes = {
17 | themesAppliedListInit: PropTypes.arrayOf(PropTypes.object).isRequired,
18 | story: PropTypes.shape().isRequired,
19 | onChangeState: PropTypes.func.isRequired,
20 | onThemeOverride: PropTypes.func.isRequired,
21 | themesInitList: PropTypes.array.isRequired,
22 | // themeListRender: PropTypes.func.isRequired,
23 | initState: PropTypes.shape().isRequired,
24 | // channel: PropTypes.object.isRequired
25 | store: PropTypes.shape().isRequired
26 | };
27 |
28 | export default class MuiTheme extends React.Component {
29 | constructor(props, context) {
30 | super(props, context);
31 |
32 | this.state = props.initState;
33 | this.state.themesAppliedList = props.themesAppliedListInit;
34 | this.state.currentTheme = {};
35 | // this.state.muiTheme = createMuiTheme(props.themesAppliedListInit[props.initState.themeInd]); // Not working yet
36 | this.state.muiTheme = createMuiTheme();
37 | this.state.isMount = false;
38 | this.isChannelData = false;
39 | this.UpdateList = {};
40 |
41 | this.changeTheme = this.changeTheme.bind(this);
42 | this.onChannel = this.onChannel.bind(this);
43 | this.openSideBar = this.openSideBar.bind(this);
44 | this.onThemeOverride = this.onThemeOverride.bind(this);
45 | this.subState = this.subState.bind(this);
46 | this.wouldComponentUpdate = this.wouldComponentUpdate.bind(this);
47 | this.needComponentUpdate = this.needComponentUpdate.bind(this);
48 |
49 | // this.dataChannelSend = this.dataChannelSend.bind(this);
50 | }
51 |
52 | componentDidMount() {
53 | // this.props.channel.on(EVENT_ID_BACK, this.onChannel);
54 | // if (!this.state.isMount) {
55 | // setTimeout(() => {
56 | // this.needComponentUpdate('ThemeSideBar');
57 | // this.setState({ isMount: true });
58 | // }, 1);
59 | // }
60 | this.props.store.onData(this.onChannel);
61 | this.props.store.connect();
62 | }
63 |
64 | shouldComponentUpdate() {
65 | return true; // fixme: shouldComponentUpdate
66 | }
67 |
68 | componentDidUpdate() {
69 | this.props.onChangeState(this.state);
70 | // this.dataChannelSend(this.state);
71 | this.isChannelData = false;
72 | }
73 |
74 | componentWillUnmount() {
75 | // this.props.channel.removeListener(EVENT_ID_BACK, this.onChannel);
76 | this.store.disconnect();
77 | }
78 |
79 | onChannel = theme => {
80 | this.setState({ currentTheme: theme });
81 | };
82 |
83 | onThemeOverride() {
84 | const propsThemeOverFunc = this.props.onThemeOverride(this.state.themeInd);
85 | return overTheme => {
86 | const themesAppliedList = propsThemeOverFunc(overTheme);
87 | this.needComponentUpdate('ThemeSideBar');
88 | this.setState({ themesAppliedList });
89 | };
90 | }
91 |
92 | changeTheme(ind) {
93 | this.needComponentUpdate('ThemeSideBar');
94 | this.setState({
95 | // muiTheme: createMuiTheme(this.state.themesAppliedList[ind]),
96 | muiTheme: createMuiTheme(),
97 | themeInd: ind
98 | });
99 | }
100 |
101 | openSideBar(f) {
102 | this.needComponentUpdate('ThemeSideBar');
103 | this.setState({
104 | isSideBarOpen: f
105 | });
106 | }
107 |
108 | subState(componentName, prop) {
109 | return val => {
110 | if (val == undefined) {
111 | return this.state[prop];
112 | }
113 | const subState = {};
114 | subState[prop] = val;
115 | this.setState(subState);
116 | this.needComponentUpdate(componentName);
117 | return val;
118 | };
119 | }
120 |
121 | wouldComponentUpdate(componentName) {
122 | if (this.UpdateList[componentName] == undefined) {
123 | this.UpdateList[componentName] = false;
124 | }
125 | const upd = this.UpdateList[componentName];
126 | this.UpdateList[componentName] = false;
127 | return upd;
128 | }
129 |
130 | needComponentUpdate(componentName) {
131 | this.UpdateList[componentName] = true;
132 | }
133 |
134 | render() {
135 | const theme = createMuiTheme(this.state.currentTheme);
136 |
137 | return (
138 |
139 | {this.props.story}
140 |
141 | );
142 | }
143 | }
144 |
145 | MuiTheme.propTypes = propTypes;
146 |
--------------------------------------------------------------------------------
/src/containers/PanelContainer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
5 | import * as beauti from 'js-beautify';
6 |
7 | import AddonPanel from '../components/AddonPanel';
8 | import withChannel from '../adk/WithChannel';
9 | import {
10 | EVENT_ID_INIT,
11 | EVENT_ID_DATA,
12 | EVENT_ID_BACK,
13 | } from '../config';
14 |
15 | const { document, window } = global;
16 | const logger = console;
17 |
18 | const lightBaseTheme = createMuiTheme();
19 |
20 | const PROGRESS_STATUS = {
21 | 'button-clone': 'soon', // todo: [] button_clone
22 | 'button-download': 'done', // todo: [x] button_download
23 | 'button-clean': 'soon', // todo: [] button_clean
24 | 'textarea-edit': 'done', // todo: [x] textarea-edit
25 | 'textarea-update': 'done' // todo: [x] textarea-update
26 | };
27 |
28 | const progressInfo = () => {
29 | const keys = Object.keys(PROGRESS_STATUS);
30 | logger.group('PROGRESS_STATUS:');
31 | keys.forEach(val => {
32 | if (PROGRESS_STATUS[val] === 'done') {
33 | logger.info(`${val}: ${PROGRESS_STATUS[val]}`);
34 | return;
35 | }
36 | logger.warn(`${val}: ${PROGRESS_STATUS[val]}`);
37 | });
38 | logger.groupEnd('PROGRESS_STATUS:');
39 | };
40 |
41 | const genNameList = themesAppliedList =>
42 | themesAppliedList.map((val, ind) => val.themeName || `Theme ${ind + 1}`);
43 |
44 | class PanelContainer extends React.Component {
45 | static propTypes = {
46 | store: PropTypes.shape().isRequired,
47 | api: PropTypes.shape().isRequired
48 | };
49 |
50 | constructor(props, ...args) {
51 | super(props, ...args);
52 |
53 | this.state = {
54 | isReady: false,
55 | isThemeInvalid: false,
56 | isThemeEditing: false,
57 | themeString: '',
58 | themeInd: 0,
59 | };
60 | this.isChannelData = false;
61 |
62 | // future: get from state with own theme ind
63 | this.muiTheme = lightBaseTheme;
64 | }
65 |
66 | componentDidMount() {
67 | // this.props.channel.on(EVENT_ID_INIT, this.onInitChannel);
68 | // this.props.channel.on(EVENT_ID_DATA, this.onDataChannel);
69 | this.props.store.connect();
70 | this.props.store.onData(this.onInitChannel);
71 | }
72 |
73 | componentDidUpdate() {
74 | // if (!this.isChannelData) this.props.channel.emit(EVENT_ID_DATA, nextState);
75 | this.querySet(this.state);
76 | this.dataChannelSend(this.state);
77 | this.isChannelData = false;
78 | }
79 |
80 | componentWillUnmount() {
81 | this.props.store.disconnect();
82 | // this.props.channel.removeListener(EVENT_ID_INIT, this.onInitChannel);
83 | // this.props.channel.removeListener(EVENT_ID_DATA, this.onDataChannel);
84 | }
85 |
86 | onInitChannel = initData => {
87 | // const _themesNameList = genNameList(initData.themesAppliedList);
88 | const themesNameList = genNameList(initData);
89 | const queryData = this.queryFetch();
90 | this.setState({
91 | themesAppliedList: initData,
92 | ...queryData,
93 | themesNameList,
94 | isReady: true
95 | });
96 | console.log('TCL: PanelContainer -> initData', initData);
97 | };
98 |
99 | onDataChannel = stateData => {
100 | // const stateData = JSON.parse(strData);
101 | const themesNameList = genNameList(stateData.themesAppliedList);
102 | this.isChannelData = true; // note: this state received by channel, don't need to send back
103 | this.setState({ ...stateData, themesNameList });
104 | };
105 |
106 | onThemeSelect = ind => {
107 | this.setState({
108 | themeInd: ind
109 | });
110 | };
111 |
112 | onChangeTheme = str => {
113 | // const str = event.target.value;
114 | try {
115 | const newTheme = JSON.parse(str);
116 | const themesAppliedList = this.state.themesAppliedList;
117 | themesAppliedList[this.state.themeInd] = newTheme;
118 | this.setState({
119 | themesAppliedList,
120 | isThemeInvalid: false,
121 | themeString: str
122 | });
123 | } catch (e) {
124 | this.setState({
125 | isThemeInvalid: true,
126 | themeString: str
127 | });
128 | }
129 | };
130 |
131 | onThemeEditing = isFocus => () => {
132 | const themeString = this.getCurrentTheme(1);
133 | this.setState({
134 | isThemeEditing: isFocus,
135 | themeString
136 | });
137 | };
138 |
139 | onToggleSideBar = f => {
140 | this.setState({
141 | isSideBarOpen: f
142 | });
143 | };
144 |
145 | onDnLoadTheme = () => {
146 | const uri = `data:application/json;charset=utf-8;base64,
147 | ${window.btoa(this.getCurrentTheme(4))}`;
148 | const fileName =
149 | this.state.themesAppliedList[this.state.themeInd].themeFile ||
150 | 'theme.json';
151 | const downloadTheme = document.createElement('a');
152 | downloadTheme.href = uri;
153 | downloadTheme.download = fileName;
154 |
155 | document.body.appendChild(downloadTheme);
156 | downloadTheme.click();
157 | document.body.removeChild(downloadTheme);
158 | };
159 |
160 | onCloneTheme = () => {
161 | progressInfo(this);
162 | return null;
163 |
164 | // const themesAppliedList = this.state.themesAppliedList;
165 | // const newTheme = Object.assign({}, themesAppliedList[this.state.themeInd]); // fixme: deeper
166 | // newTheme.themeName = `${themesAppliedList[this.state.themeInd].themeName} clone`;
167 | // newTheme.themeFile = `${themesAppliedList[this.state.themeInd].themeFile}.clone`;
168 | // const newAppliedList = themesAppliedList.slice(0, this.state.themeInd + 1)
169 | // .concat(newTheme, themesAppliedList.slice(this.state.themeInd + 1));
170 | // const themesNameList = genNameList(newAppliedList);
171 | // logger.log(themesNameList);
172 | // this.setState({ themesAppliedList: newAppliedList, themesNameList });
173 | };
174 |
175 | onCleanTheme = () => {
176 | progressInfo(this);
177 | return null;
178 | // const themesAppliedList = this.state.themesAppliedList;
179 | // const newTheme = {};
180 | // newTheme.themeName = themesAppliedList[this.state.themeInd].themeName;
181 | // newTheme.themeFile = themesAppliedList[this.state.themeInd].themeFile;
182 | // themesAppliedList[this.state.themeInd] = newTheme;
183 | // const themesNameList = genNameList(themesAppliedList);
184 | // this.setState({ themesAppliedList, themesNameList });
185 | };
186 |
187 | getCurrentTheme = (indent = 2) =>
188 | beauti.js_beautify(
189 | JSON.stringify(this.state.themesAppliedList[this.state.themeInd]),
190 | {
191 | indent_size: indent,
192 | indent_char: ' ',
193 | eol: '\n',
194 | end_with_newline: true
195 | }
196 | );
197 |
198 | dataChannelSend = data => {
199 | if (this.isChannelData) return false;
200 | // this.props.channel.emit(EVENT_ID_BACK, data);
201 | try {
202 | const theme = this.state.themesRenderedList[this.state.themeInd];
203 | this.props.store.send(theme);
204 | return true;
205 | } catch (err) {
206 | return false;
207 | }
208 | };
209 |
210 | queryFetch = () => {
211 | const themeInd = this.props.api.getQueryParam('theme-ind');
212 | const isSideBarOpen = this.props.api.getQueryParam('theme-sidebar');
213 | const isFullTheme = this.props.api.getQueryParam('theme-full');
214 | const data = JSON.parse(
215 | JSON.stringify({ themeInd, isSideBarOpen, isFullTheme })
216 | );
217 | const keys = Object.keys(data);
218 | keys.forEach(val => {
219 | data[val] = JSON.parse(data[val]);
220 | });
221 | return data;
222 | };
223 |
224 | querySet = state => {
225 | if (state.isReady) {
226 | const { themeInd, isSideBarOpen, isFullTheme } = state;
227 | const queryParams = {
228 | 'theme-ind': themeInd,
229 | 'theme-sidebar': isSideBarOpen,
230 | 'theme-full': isFullTheme
231 | };
232 | this.props.api.setQueryParams(queryParams);
233 | }
234 | };
235 |
236 | render() {
237 | return this.state.isReady ? (
238 |
239 |
257 |
258 | ) : (
259 |
267 | waiting for muiTheme decorator...
268 |
269 | );
270 | }
271 | }
272 |
273 | export default withChannel({EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK})(PanelContainer)
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { muiTheme } from './muiTheme';
2 |
--------------------------------------------------------------------------------
/src/material-desktop/SclAvatar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import Chip from '@material-ui/core/Chip';
5 | import Avatar from '@material-ui/core/Avatar';
6 |
7 | const defaultProps = {
8 | scale: 0.8,
9 | text: 'dummy text',
10 | };
11 |
12 | const propTypes = {
13 | scale: PropTypes.number,
14 | text: PropTypes.string,
15 | };
16 |
17 | export default function SclAvatar(props) {
18 | const style = {
19 | transform: `scale(${props.scale})`,
20 | transformOrigin: 'left',
21 | // left: -95 * (1 - props.scale) / 2,
22 | // position: 'absolute',
23 | };
24 | const chipProps = Object.assign({}, props);
25 | delete chipProps.text;
26 | return (
27 |
28 |
29 |
30 |
31 | {{props.text[0].toUpperCase()} }
32 | {props.text}
33 |
34 |
35 |
36 |
37 | );
38 | }
39 | SclAvatar.defaultProps = defaultProps;
40 | SclAvatar.propTypes = propTypes;
41 |
--------------------------------------------------------------------------------
/src/material-desktop/SclToggle.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Toggle from '@material-ui/core/Switch';
4 |
5 | const defaultProps = {
6 | scale: 0.7,
7 | };
8 |
9 | const propTypes = {
10 | scale: PropTypes.number,
11 | };
12 |
13 | export default function SclToggle(props) {
14 | const style = {
15 | transform: `scale(${props.scale})`,
16 | };
17 | return (
18 |
19 |
20 |
21 | );
22 | }
23 | SclToggle.defaultProps = defaultProps;
24 | SclToggle.propTypes = propTypes;
25 |
--------------------------------------------------------------------------------
/src/material-desktop/SvgButton.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import IconButton from '@material-ui/core/IconButton';
4 |
5 | const propTypes = {
6 | iconScale: PropTypes.number.isRequired,
7 | icon: PropTypes.element.isRequired,
8 | tooltip: PropTypes.string,
9 | width: PropTypes.number,
10 | onTouchTap: PropTypes.func,
11 | };
12 |
13 | const defaultProps = {
14 | iconScale: 0.8,
15 | tooltipPosition: 'top-center',
16 | width: 32,
17 | tooltip: '',
18 | onTouchTap: () => {},
19 | };
20 |
21 | // const contextTypes = {
22 | // muiTheme: PropTypes.object.isRequired,
23 | // };
24 |
25 |
26 | export default class SvgButton extends React.Component {
27 | constructor(props, context) {
28 | super(props, context);
29 |
30 | this.scaleProp = {
31 | style: {
32 | transform: `scale(${props.iconScale})`,
33 | width: 24,
34 | margin: '0 auto',
35 | },
36 | };
37 | this.butnProp = {
38 | style: {
39 | marginLeft: (24 - props.width) / 2,
40 | width: props.width,
41 | display: 'flex',
42 | justifyContent: 'center',
43 | overflow: 'hidden',
44 | },
45 | title: props.tooltip,
46 | onClick: props.onClick,
47 | };
48 | }
49 |
50 | render() {
51 | const icon = React.cloneElement(this.props.icon, {
52 | // color: this.context.muiTheme.palette.secondaryTextColor,
53 | });
54 | return (
55 |
60 |
61 |
62 |
66 |
67 |
68 | {icon}
69 |
70 |
71 |
72 |
73 |
74 |
75 | );
76 | }
77 | }
78 |
79 |
80 | SvgButton.propTypes = propTypes;
81 | SvgButton.defaultProps = defaultProps;
82 | // SvgButton.contextTypes = contextTypes;
83 |
--------------------------------------------------------------------------------
/src/material-desktop/SvgIcon.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const propTypes = {
5 | scale: PropTypes.number.isRequired,
6 | };
7 |
8 | const defaultProps = {
9 | scale: 0.8,
10 | };
11 |
12 | const contextTypes = {
13 | muiTheme: PropTypes.object.isRequired,
14 | };
15 |
16 |
17 | export default class SvgIcon extends React.Component {
18 | constructor(props, context) {
19 | super(props, context);
20 |
21 | require.ensure([], (require) => {
22 | const Icon = require('@material-ui/core/SvgIcon');
23 | this.ActionHome = Icon.default;
24 | });
25 |
26 | this.scaleProp = {
27 | style: { transform: `scale(${props.scale})` },
28 | };
29 | }
30 |
31 | render() {
32 | return (
33 |
40 | );
41 | }
42 | }
43 |
44 |
45 | SvgIcon.propTypes = propTypes;
46 | SvgIcon.defaultProps = defaultProps;
47 | SvgIcon.contextTypes = contextTypes;
48 |
--------------------------------------------------------------------------------
/src/muiTheme.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createMuiTheme } from '@material-ui/core/styles';
3 |
4 | import { EVENT_ID_INIT, EVENT_ID_DATA, EVENT_ID_BACK } from './config';
5 | import MuiDecorator from './UI/MuiDecorator';
6 | import { createStore } from './adk/decorator';
7 |
8 | const lightBaseTheme = createMuiTheme({
9 | typography: {
10 | useNextVariants: true
11 | }
12 | });
13 | const darkBaseTheme = createMuiTheme({
14 | palette: {
15 | type: 'dark'
16 | },
17 | typography: {
18 | useNextVariants: true
19 | }
20 | });
21 |
22 | lightBaseTheme.themeName = 'Light Theme';
23 | darkBaseTheme.themeName = 'Dark Theme';
24 |
25 | export function muiTheme(themes) {
26 | const store = createStore(
27 | EVENT_ID_INIT,
28 | EVENT_ID_DATA,
29 | EVENT_ID_BACK,
30 | 'iframe'
31 | );
32 |
33 | let themesInitList = [lightBaseTheme, darkBaseTheme];
34 | if (themes) {
35 | if (Array.isArray(themes)) {
36 | themesInitList = themes;
37 | themesInitList.forEach((val, ind) => {
38 | if (typeof val === 'string') {
39 | /* note: unsupported names goes as lightBaseTheme
40 | if (val === lightBaseTheme.themeName) {
41 | themesInitList[ind] = lightBaseTheme;
42 | }
43 | */
44 | if (val === darkBaseTheme.themeName) {
45 | themesInitList[ind] = darkBaseTheme;
46 | } else {
47 | themesInitList[ind] = lightBaseTheme;
48 | }
49 | }
50 | });
51 | } else {
52 | themesInitList = [themes];
53 | }
54 | }
55 |
56 | store.onConnected(() =>
57 | store.sendInit({ themes: themesInitList, themeInd: 0 })
58 | );
59 |
60 | return story => {
61 | const storyItem = story();
62 | return (
63 |
67 | );
68 | };
69 | }
70 |
--------------------------------------------------------------------------------
/src/preset.js:
--------------------------------------------------------------------------------
1 | export function managerEntries(entry = []) {
2 | return [...entry, require.resolve("./register")]; //👈 addon implementation
3 | }
4 |
--------------------------------------------------------------------------------
/src/register.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import addons from '@storybook/addons';
3 | import AddonPanel from './UI/AddonPanel';
4 | import { ADDON_ID, PANEL_ID } from './config';
5 |
6 | addons.register(ADDON_ID, api => {
7 | addons.addPanel(PANEL_ID, {
8 | title: 'Material-UI',
9 | render: ({ active, key } = {}) => (
10 |
11 | )
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/storybook-addon-material-ui.d.ts:
--------------------------------------------------------------------------------
1 | import {DecoratorFunction} from "@storybook/addons";
2 | import {Theme} from "@material-ui/core";
3 |
4 | export declare function muiTheme(arg?: Array): DecoratorFunction;
5 |
--------------------------------------------------------------------------------