├── .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 | 33 | 36 | 39 |
40 | )) 41 | .add('Outlined buttons', () => ( 42 |
43 | 46 | 49 | 52 |
53 | )) 54 | .add('Flat buttons', () => ( 55 |
56 | 59 | 62 | 65 |
66 | )); 67 | 68 | storiesOf('Clone Custom theme', module) 69 | // .addDecorator(muiTheme([theme4, theme5])) 70 | .add(' Raised buttons', () => ( 71 |
72 | 75 | 78 | 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 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/721efbed8ff544c2adbd996108e84165)](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 | [![npm version](https://badge.fury.io/js/storybook-addon-material-ui.svg)](https://badge.fury.io/js/storybook-addon-material-ui) 3 | [![Live demo](https://img.shields.io/badge/Live%20Demo-%20Storybook-brightgreen.svg)](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 | [![screen1](https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/master/docs/WatchMe.gif)](https://raw.githubusercontent.com/react-theming/storybook-addon-material-ui/master/docs/WatchMe.gif) 16 | 17 | 18 | ## Features 19 | 20 | [![Live demo](https://img.shields.io/badge/Live%20Demo-%20Storybook-brightgreen.svg)](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 | [![@airbnb](https://img.shields.io/badge/code%20style-Airbnb-brightgreen.svg)](./.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 |
Created with ❤︎ to Storybook and Material-UI by Oleg Proskurin [React Theming] 227 |
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 | ![screen1](screen1.png) 4 | ### default `Dark base theme` 5 | >Check a different appearance 6 | ![screen2](screen2.png) 7 | ### Visual color adjusting 8 | >Results instantly on the screen 9 | ![screen3](screen3.png) 10 | ### User created theme 11 | ![screen4](screen4.png) 12 | ### Full theme settings 13 | ![screen5](screen5.png) 14 | ### After overriding 15 | >you will have only chanded setting in your theme 16 | ![screen6](screen6.png) -------------------------------------------------------------------------------- /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 | 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 | 211 |
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 |
260 | 267 | 273 |

280 | 285 | {'> HERE <'} 286 | 287 |

288 |
289 |
296 | 302 | 308 |
309 |
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 | 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 | 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 | {images[icon]} 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 | 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 | 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 | 164 | )); 165 | const select = event => onSelect(parseInt(event.target.value, 10)); 166 | 167 | return ( 168 | 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 |
129 |
130 |
140 |
147 |
153 |
163 |