diff --git a/.gitignore b/.gitignore index 9e91bc6a33..b6d52bd9b9 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ plnkr.html public/docs/*/latest/guide/cheatsheet.json protractor-results.txt link-checker-results.txt +*a2docs.css diff --git a/gulpfile.js b/gulpfile.js index b2e93be14e..6c5a3a4490 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,7 +22,7 @@ var globby = require("globby"); // - because childProcess.kill does not work properly on windows var treeKill = require("tree-kill"); var blc = require("broken-link-checker"); - +var less = require('gulp-less'); var tslint = require('gulp-tslint'); // TODO: @@ -41,6 +41,7 @@ var EXAMPLES_PROTRACTOR_PATH = path.join(EXAMPLES_PATH, '_protractor'); var NOT_API_DOCS_GLOB = path.join(PUBLIC_PATH, './{docs/*/latest/!(api),!(docs)}/**/*.*'); var RESOURCES_PATH = path.join(PUBLIC_PATH, 'resources'); var LIVE_EXAMPLES_PATH = path.join(RESOURCES_PATH, 'live-examples'); +var STYLES_SOURCE_PATH = path.join(TOOLS_PATH, 'styles-builder/less'); var docShredder = require(path.resolve(TOOLS_PATH, 'doc-shredder/doc-shredder')); var exampleZipper = require(path.resolve(TOOLS_PATH, '_example-zipper/exampleZipper')); @@ -87,6 +88,7 @@ var _excludeMatchers = _excludePatterns.map(function(excludePattern){ var _exampleBoilerplateFiles = [ '.editorconfig', + 'a2docs.css', 'karma.conf.js', 'karma-test-shim.js', 'package.json', @@ -98,7 +100,7 @@ var _exampleBoilerplateFiles = [ 'wallaby.js' ]; -var _exampleDartWebBoilerPlateFiles = ['styles.css']; +var _exampleDartWebBoilerPlateFiles = ['a2docs.css', 'styles.css']; var _exampleProtractorBoilerplateFiles = [ 'tsconfig.json' @@ -106,6 +108,8 @@ var _exampleProtractorBoilerplateFiles = [ var _exampleConfigFilename = 'example-config.json'; +var _styleLessName = 'a2docs.less'; + // Gulp flags: // // --lang=[all | ts | js | dart | 'ts|js' | 'ts|js|dart' | ...] @@ -118,7 +122,7 @@ var _exampleConfigFilename = 'example-config.json'; var lang, langs, buildDartApiDocs = false; function configLangs(langOption) { const fullSiteBuildTasks = ['build-compile', 'check-serve', 'check-deploy']; - const buildAllDocs = argv['_'] && + const buildAllDocs = argv['_'] && fullSiteBuildTasks.some((task) => argv['_'].indexOf(task) >= 0); const langDefault = buildAllDocs ? 'all' : 'ts|js'; lang = (langOption || langDefault).toLowerCase(); @@ -190,7 +194,7 @@ function runE2e() { return spawnInfo.promise; }) .then(function() { - copyExampleBoilerplate(); + buildStyles(copyExampleBoilerplate, _.noop); gutil.log('runE2e: update webdriver'); spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PROTRACTOR_PATH}); return spawnInfo.promise; @@ -414,7 +418,7 @@ gulp.task('help', taskListing.withFilters(function(taskName) { })); // requires admin access because it adds symlinks -gulp.task('add-example-boilerplate', function() { +gulp.task('add-example-boilerplate', function(done) { var realPath = path.join(EXAMPLES_PATH, '/node_modules'); var nodeModulesPaths = excludeDartPaths(getNodeModulesPaths(EXAMPLES_PATH)); @@ -430,16 +434,26 @@ gulp.task('add-example-boilerplate', function() { fsUtils.addSymlink(realPath, linkPath); }); - return copyExampleBoilerplate(); + return buildStyles(copyExampleBoilerplate, done); }); // copies boilerplate files to locations // where an example app is found -gulp.task('_copy-example-boilerplate', function () { - if (!argv.fast) copyExampleBoilerplate(); +gulp.task('_copy-example-boilerplate', function (done) { + if (!argv.fast) buildStyles(copyExampleBoilerplate, done); }); +//Builds Angular 2 Docs CSS file from Bootstrap npm LESS source +//and copies the result to the _examples folder to be included as +//part of the example boilerplate. +function buildStyles(cb, done){ + gulp.src(path.join(STYLES_SOURCE_PATH, _styleLessName)) + .pipe(less()) + .pipe(gulp.dest(EXAMPLES_PATH)).on('end', function(){ + cb().then(function() { done(); }); + }); +} // copies boilerplate files to locations // where an example app is found @@ -1251,7 +1265,7 @@ function buildApiDocsForDart() { dab.createApiDataAndJadeFiles(apiEntries); }).catch((err) => { - console.log(err); + console.error(err); }); } catch(err) { diff --git a/package.json b/package.json index e6d82ff58e..d5283e3f43 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "devDependencies": { "archiver": "^1.0.0", "assert-plus": "^1.0.0", + "bootstrap": "3.3.6", "broken-link-checker": "0.7.1", "browser-sync": "^2.9.3", "canonical-path": "0.0.2", @@ -43,6 +44,7 @@ "gulp": "^3.5.6", "gulp-env": "0.4.0", "gulp-sass": "^2.3.2", + "gulp-less": "^3.1.0", "gulp-task-listing": "^1.0.1", "gulp-tslint": "^5.0.0", "gulp-util": "^3.0.6", diff --git a/tools/styles-builder/less/a2docs.less b/tools/styles-builder/less/a2docs.less new file mode 100644 index 0000000000..9462e2d54f --- /dev/null +++ b/tools/styles-builder/less/a2docs.less @@ -0,0 +1,29 @@ +//Import angular 2 docs colors and mixins +@import './colors/docs-material-palette.colors.less'; +@import './mixins/docs.mixins.less'; +//Import Bootstrap scaffolding and variables +@import '../../../node_modules/bootstrap/less/scaffolding.less'; +@import '../../../node_modules/bootstrap/less/variables.less'; +//Override Bootstrap variables with custom values for angular 2 docs +@import './overrides/bootstrap.overrides.less'; +//Import Bootstrap layout systems +@import '../../../node_modules/bootstrap/less/mixins.less'; +@import '../../../node_modules/bootstrap/less/grid.less'; +@import '../../../node_modules/bootstrap/less/utilities.less'; +@import '../../../node_modules/bootstrap/less/responsive-utilities.less'; +//Import only Bootstrap elements to support angular 2 docs styles +@import '../../../node_modules/bootstrap/less/type.less'; +@import '../../../node_modules/bootstrap/less/forms.less'; +@import '../../../node_modules/bootstrap/less/buttons.less'; +@import '../../../node_modules/bootstrap/less/button-groups.less'; +@import '../../../node_modules/bootstrap/less/input-groups.less'; +@import '../../../node_modules/bootstrap/less/tables.less'; +@import '../../../node_modules/bootstrap/less/glyphicons.less'; +@import '../../../node_modules/bootstrap/less/alerts.less'; +@import '../../../node_modules/bootstrap/less/close.less'; +//Import opacity overrides +@import './overrides/docs.opacity.overrides.less'; +//Import styles overrides and angular 2 doc styles layouts +@import './overrides/docs.overrides.less'; +//Import accessibility tweaks +@import './overrides/docs.a11y.overrides.less'; diff --git a/tools/styles-builder/less/colors/docs-material-palette.colors.less b/tools/styles-builder/less/colors/docs-material-palette.colors.less new file mode 100644 index 0000000000..a9ee4cd821 --- /dev/null +++ b/tools/styles-builder/less/colors/docs-material-palette.colors.less @@ -0,0 +1,10 @@ +//Style guide colors +@material-header: #455A64; +@material-header-darker: #37474F; +@material-header-dark: #263238; +@material-200: #EEEEEE; +@material-700: #616161; +@material-800: #424242; +@material-900: #212121; +@black: #000000; +@white: #FFFFFF; diff --git a/tools/styles-builder/less/mixins/docs.mixins.less b/tools/styles-builder/less/mixins/docs.mixins.less new file mode 100644 index 0000000000..142c36fe67 --- /dev/null +++ b/tools/styles-builder/less/mixins/docs.mixins.less @@ -0,0 +1,44 @@ +.opacity(){ + opacity: 0.87; +} + +.top-header-text(){ + font-size: 50px; + font-weight: bold; +} + +.header-text(){ + font-size: 30px; + font-weight: bold; +} + +.sub-header-text(){ + font-size: 20px; + font-weight: 400; + line-height: 40px; +} + +.paragraph-text(){ + font-size: 16px; + font-weight: 400; + line-height: 28px; +} + +.label-text(){ + font-size: 16px; + font-weight: 400; + line-height: 28px; +} + +.button-text(){ + font-size: 16px; + font-weight: bold; + line-height: 28px; +} + +.input-text(){ + font-size: 16px; + font-weight: 400; + line-height: 28px; + margin-top: 15px; +} diff --git a/tools/styles-builder/less/overrides/bootstrap.overrides.less b/tools/styles-builder/less/overrides/bootstrap.overrides.less new file mode 100644 index 0000000000..24149caf11 --- /dev/null +++ b/tools/styles-builder/less/overrides/bootstrap.overrides.less @@ -0,0 +1,21 @@ +//Main Bootstrap color overrides +@gray-base: @black; +@gray-darker: @black; +@gray-dark: @material-900; +@gray: @material-800; +@gray-light: @material-700; +@gray-lighter: @material-200; + +//Font override +@font-family-sans-serif: "Roboto", Helvetica, Sans-Serif; + +//Glyphicons font path +@icon-font-path: "./node_modules/bootstrap/fonts/"; + +//Class overrides +@input-color: @gray-dark; +@text-color: @gray-dark; +@btn-primary-color: @gray-lighter; +@btn-primary-bg: @material-header-dark; +@btn-default-color: @white; +@btn-default-bg: @material-header-darker; diff --git a/tools/styles-builder/less/overrides/docs.a11y.overrides.less b/tools/styles-builder/less/overrides/docs.a11y.overrides.less new file mode 100644 index 0000000000..4ee1a14360 --- /dev/null +++ b/tools/styles-builder/less/overrides/docs.a11y.overrides.less @@ -0,0 +1,55 @@ +//Accessibility tweaks +@danger-text: #632827; +@state-danger-text: @danger-text; + +input { + &::-webkit-input-placeholder { + color: @gray-light !important; + } + + &::-moz-placeholder { + color: @gray-light !important; + } +} + +label { + input, textarea, select { + font-weight: normal; + } +} + +button.btn.disabled, +button.btn[disabled] { + color: @white; + background-color: @black; +} + +.btn.btn-primary:not(.disabled):not([disabled]) { + &:hover, + &:focus{ + color: @black; + background-color: @gray-lighter; + } +} + +.btn.btn-default:not(.disabled):not([disabled]) { + &:hover, + &:focus{ + color: @black; + background-color: @gray-lighter; + } +} + +button.btn.disabled, button.btn[disabled] { + &:hover, + &:focus{ + color: @white; + background-color: @black; + } +} + +.close, +.close:hover, +.close:focus{ + opacity: 1; +} diff --git a/tools/styles-builder/less/overrides/docs.opacity.overrides.less b/tools/styles-builder/less/overrides/docs.opacity.overrides.less new file mode 100644 index 0000000000..215ec29378 --- /dev/null +++ b/tools/styles-builder/less/overrides/docs.opacity.overrides.less @@ -0,0 +1,35 @@ +//Opacity tweaks + +h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + .opacity(); +} + +label { + + input { + opacity: 1; + } + + .opacity(); +} + + +input { + .opacity(); +} + +.label-default { + .opacity(); +} + +legend { + .opacity(); +} + +button { + .opacity(); +} + +span, p, dl { + .opacity(); +} diff --git a/tools/styles-builder/less/overrides/docs.overrides.less b/tools/styles-builder/less/overrides/docs.overrides.less new file mode 100644 index 0000000000..f2803b3f86 --- /dev/null +++ b/tools/styles-builder/less/overrides/docs.overrides.less @@ -0,0 +1,75 @@ +//Design tweaks +h1 { + color: @material-header; + .top-header-text(); +} + +h2 { + color: @material-header; + .header-text(); +} + +h3, legend { + .sub-header-text(); +} + +label, .label-default { + .label-text(); +} + +input, textarea, select { + color: @gray-dark; + .input-text(); +} + +span, p, dl, .doc-text { + .paragraph-text(); +} + +button.btn { + .button-text(); +} + +.dl-horizontal dt { + text-align: left; +} + +.input-group-btn { + padding-top: 15px; + + button.btn { + padding-top: 2px; + padding-bottom: 3px; + } + +} + +.shadow-1 { + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37); +} + +.showcase { + margin-bottom: 20px; +} + +.showcase .showcase-header { + background: #E0E0E0; + padding: 32px; +} + +.showcase .showcase-content { + padding: 32px; +} + +.main-header { + margin-bottom: 40px; +} + +a *{ + color:inherit; + + &:hover { + color: inherit; + } + +}