diff --git a/generators/app/index.js b/generators/app/index.js index 5887595..c19d087 100644 --- a/generators/app/index.js +++ b/generators/app/index.js @@ -108,6 +108,9 @@ module.exports = class extends Generator { answers.humans = hasOption('humans'); answers.changelog = hasOption('changelog'); + // Store 'svg' for icons, maybe we'll add a FontAwesome option later. + answers.icon = 'svg'; + // Make sure we have a "/" at the end of the paths if (answers.src.slice(-1) !== '/') { answers.src += '/'; @@ -217,6 +220,10 @@ module.exports = class extends Generator { fromSrcToTop: this.props.fromSrcToTop } ); + const that = this; + curl.request({url: 'https://raw.githubusercontent.com/twbs/bootstrap/v4-dev/scss/_variables.scss'}, function (err, data) { + that.fs.write(that.destinationPath(`${that.props.src}config/bootstrap-variables.scss`), data); + }); } this.fs.write(this.destinationPath(`${this.props.src}config/styleguide.scss`), "@charset 'utf-8';\n\n@import 'variables';\n"); diff --git a/generators/app/templates/_package.json b/generators/app/templates/_package.json index ea0bce0..6ddecf2 100644 --- a/generators/app/templates/_package.json +++ b/generators/app/templates/_package.json @@ -37,9 +37,14 @@ "<%= assets %>config/bootstrap-variables.scss" ], "plugins": [ - "stylelint-order" + "stylelint-order", + "stylelint-a11y", + "stylelint-declaration-block-no-ignored-properties", + "stylelint-high-performance-animation", + "stylelint-scss", + "stylelint-declaration-strict-value" ], - "extends": "stylelint-config-standard", + "extends": "stylelint-config-recommended-scss", "rules": { "at-rule-no-vendor-prefix": true, "media-feature-name-no-vendor-prefix": true, @@ -47,6 +52,15 @@ "selector-no-vendor-prefix": true, "value-no-vendor-prefix": true, "selector-pseudo-element-colon-notation": "single", + "plugin/no-low-performance-animation-properties": true, + "plugin/declaration-block-no-ignored-properties": true, + "scale-unlimited/declaration-strict-value": [ + ["/color/", "fill", "stroke", "font-size"], { + "ignoreKeywords": { + "": ["currentColor", "transparent", "inherit"], + "font-size": ["currentColor", "inherit"] + } + }], "order/order": [ "custom-properties", "dollar-variables", @@ -57,7 +71,7 @@ "order/properties-order": [ "content", "display", - "flex", + "/flex/", "position", "top", "right", @@ -78,7 +92,12 @@ "color", "transform", "transition" - ] + ], + "a11y/media-prefers-reduced-motion": [true, { "severity": "warning" }], + "a11y/no-outline-none": [true, { "severity": "warning" }], + "a11y/font-size-is-readable": [true, { "severity": "warning" }], + "a11y/no-obsolete-element": [true, { "severity": "warning" }], + "a11y/no-text-align-justify": [true, { "severity": "warning" }] } } } diff --git a/generators/app/templates/_packages.json b/generators/app/templates/_packages.json index 101d014..9552a70 100644 --- a/generators/app/templates/_packages.json +++ b/generators/app/templates/_packages.json @@ -1,6 +1,6 @@ { "base": [ - "bootstrap@^4.0.0", - "toolbox-utils@latest" + "bootstrap", + "toolbox-utils" ] } diff --git a/generators/app/templates/config/_bootstrap.scss b/generators/app/templates/config/_bootstrap.scss index b44625c..5817f97 100755 --- a/generators/app/templates/config/_bootstrap.scss +++ b/generators/app/templates/config/_bootstrap.scss @@ -1,5 +1,5 @@ /*! - * Bootstrap v4.0.0 (https://getbootstrap.com) + * Bootstrap v4.1.1 (https://getbootstrap.com/) * Copyright 2011-2018 The Bootstrap Authors * Copyright 2011-2018 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) diff --git a/generators/generate/index.js b/generators/generate/index.js index da15482..d0b0e91 100644 --- a/generators/generate/index.js +++ b/generators/generate/index.js @@ -3,6 +3,8 @@ const Generator = require('yeoman-generator'); const chalk = require('chalk'); const pathExists = require('path-exists'); const fs = require('fs'); +const yaml = require('node-yaml'); +const slug = require('slug'); const checkUpdate = require('../check-update'); @@ -73,7 +75,8 @@ module.exports = class extends Generator { async writing() { if (this.props.type !== 'doc') { - const componentPath = `${this.promptValues.src}components/${this.props.type}/${this.props.slug}/`; + const componentPath = `${this.promptValues.src}components/${this.props.type}/${this.props.slug}`; + const filePath = `${componentPath}/${this.props.slug}`; // Kill process if the component is already created if (pathExists.sync(this.destinationPath(componentPath))) { @@ -82,21 +85,30 @@ module.exports = class extends Generator { } // Generate Twig file - this.fs.write( - this.destinationPath(`${componentPath}/${this.props.slug}.twig`), + await this.fs.write( + this.destinationPath(`${filePath}.twig`), `\n` ); // Generate YAML file - this.fs.write( - this.destinationPath(`${componentPath}/${this.props.slug}.yml`), - `title: ${this.props.name}\nname: ${this.props.slug}` - ); + const config = { + name: this.props.slug, + title: this.props.name, + notes: `Describe the ${this.props.slug} component here.\n`, + wrapper: '', + background: '', + }; + + if (!fs.existsSync(componentPath)) { + await fs.mkdirSync(componentPath); + } + await yaml.write(this.destinationPath(`${filePath}.yml`), config); + this.log(chalk.green(` create`) + ` ${filePath}.yml`); if (this.props.type !== 'pages') { // Generate SCSS file this.fs.write( - this.destinationPath(`${componentPath}/${this.props.slug}.scss`), + this.destinationPath(`${filePath}.scss`), '@charset \'utf-8\';\n' ); diff --git a/generators/variant/index.js b/generators/variant/index.js index a222c63..8e5cdd1 100644 --- a/generators/variant/index.js +++ b/generators/variant/index.js @@ -5,6 +5,7 @@ const pathExists = require('path-exists'); const fs = require('fs'); const autocomplete = require('inquirer-autocomplete-prompt'); const yaml = require('node-yaml'); +const slug = require('slug'); const checkUpdate = require('../check-update'); @@ -82,25 +83,29 @@ module.exports = class extends Generator { } async writing() { - const variant = this.props.variant.toLowerCase(); - const variantObject = { - name: variant, + const slugName = slug(this.props.variant, {lower: true}); + const variant = { + name: slugName, title: this.props.variant, + notes: `Describe the ${slugName} variant here.\n`, + background: '', + wrapper: '', }; - const componentPath = `${this.promptValues.src}components/${this.props.component.category}/${this.props.component.component}/`; + const variantPath = `${this.promptValues.src}components/${this.props.component.category}/${this.props.component.component}/${this.props.component.component}`; // Generate Twig file this.fs.write( - this.destinationPath(`${componentPath}/${this.props.component.component}-${variant}.twig`), - `\n` + this.destinationPath(`${variantPath}-${variant.name}.twig`), + `\n` ); // Generate Config in YAML file - const config = yaml.readSync(this.destinationPath(`${componentPath}/${this.props.component.component}.yml`)); + const configPath = this.destinationPath(`${variantPath}.yml`); + const config = yaml.readSync(configPath); - config.variants = config.variants ? [...config.variants, variantObject] : [variantObject]; - yaml.write(this.destinationPath(`${componentPath}/${this.props.component.component}.yml`), config); + config.variants = config.variants ? [...config.variants, variant] : [variant]; + yaml.write(this.destinationPath(configPath), config); } };