|
| 1 | +#!/usr/bin/env node |
| 2 | +"use strict"; |
| 3 | + |
| 4 | +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; |
| 5 | + |
| 6 | +const gulp = require("gulp"), |
| 7 | + cleanCSS = require("gulp-clean-css"), |
| 8 | + del = require("del"), |
| 9 | + fs = require("fs"), |
| 10 | + handlebars = require("handlebars"), |
| 11 | + jeditor = require("gulp-json-editor"), |
| 12 | + jsonSass = require("json-sass"), |
| 13 | + map = require("through2-map"), |
| 14 | + rename = require("gulp-rename"), |
| 15 | + sass = require("gulp-sass"), |
| 16 | + source = require("vinyl-source-stream"), |
| 17 | + vinylPaths = require("vinyl-paths"), |
| 18 | + zip = require("gulp-zip"); |
| 19 | + |
| 20 | +const dirRoot = process.cwd(); |
| 21 | +const routeConfig = `${dirRoot}/css-gridish.json`; |
| 22 | +const config = require(routeConfig); |
| 23 | +const intro = config.paths !== undefined && config.paths.intro !== undefined ? fs.readFileSync(`${dirRoot}/${config.paths.intro}`, "utf8") : ""; |
| 24 | +const route = config.paths !== undefined && config.paths.route !== undefined ? config.paths.route : "css-gridish"; |
| 25 | +const dirDest = `${dirRoot}/${route}`; |
| 26 | +const dirDestCss = `${dirDest}/\css`; |
| 27 | +const dirDestDesign = `${__dirname}/css-gridish-design.json`; |
| 28 | +const dirDestScss = `${dirDest}/s\css`; |
| 29 | +const dirDestSketch = `${dirDest}/sketch`; |
| 30 | +const prefix = config.prefix ? config.prefix : "gridish"; |
| 31 | + |
| 32 | +const artboard = require(`${__dirname}/src/sketch/artboard.json`); |
| 33 | + |
| 34 | +const parseUnit = function (value, width) { |
| 35 | + let parsed = value; |
| 36 | + if (value !== 0) { |
| 37 | + if (value.includes("vw")) { |
| 38 | + parsed = value.slice(0, -2) * width * 0.01; |
| 39 | + } else if (value.includes("rem")) { |
| 40 | + parsed = value.slice(0, -3) * config.rem; |
| 41 | + } else if (value.includes("px")) { |
| 42 | + parsed = value.slice(0, -2); |
| 43 | + } else if (value.includes("%")) { |
| 44 | + parsed = value.slice(0, -1) * width * 0.01; |
| 45 | + } |
| 46 | + } |
| 47 | + return parsed; |
| 48 | +}; |
| 49 | + |
| 50 | +handlebars.registerHelper("length", function (json) { |
| 51 | + return Object.keys(json).length; |
| 52 | +}); |
| 53 | + |
| 54 | +handlebars.registerHelper("math", function (lvalue, operator, rvalue, options) { |
| 55 | + lvalue = parseFloat(lvalue); |
| 56 | + rvalue = parseFloat(rvalue); |
| 57 | + |
| 58 | + return { |
| 59 | + "+": lvalue + rvalue, |
| 60 | + "-": lvalue - rvalue, |
| 61 | + "*": lvalue * rvalue, |
| 62 | + "/": lvalue / rvalue, |
| 63 | + "%": lvalue % rvalue |
| 64 | + }[operator]; |
| 65 | +}); |
| 66 | + |
| 67 | +gulp.task("clean", function () { |
| 68 | + return del([dirDestCss, dirDestScss, `${dirDest}/${prefix}-grid.sketch`]); |
| 69 | +}); |
| 70 | + |
| 71 | +gulp.task("css", ["scssRenameLegacy"], function () { |
| 72 | + return gulp.src(`${dirDestScss}/${prefix}-grid.s\css`).pipe(sass().on("error", sass.logError)).pipe(rename(`${prefix}-grid.\css`)).pipe(gulp.dest(dirDestCss)).pipe(cleanCSS({ |
| 73 | + level: 2 |
| 74 | + })).pipe(rename(`${prefix}-grid.min.\css`)).pipe(gulp.dest(dirDestCss)); |
| 75 | +}); |
| 76 | + |
| 77 | +gulp.task("css-legacy", ["css"], function () { |
| 78 | + return gulp.src(`${dirDestScss}/${prefix}-grid-legacy.s\css`).pipe(sass().on("error", sass.logError)).pipe(rename(`${prefix}-grid-legacy.\css`)).pipe(gulp.dest(dirDestCss)).pipe(cleanCSS({ |
| 79 | + level: 2 |
| 80 | + })).pipe(rename(`${prefix}-grid-legacy.min.\css`)).pipe(gulp.dest(dirDestCss)); |
| 81 | +}); |
| 82 | + |
| 83 | +gulp.task("docs", ["css-legacy"], function () { |
| 84 | + return gulp.src(`${__dirname}/src/docs/*.hbs`).pipe(map.obj(chunk => { |
| 85 | + var template = handlebars.compile(chunk.contents.toString()); |
| 86 | + chunk.contents = new Buffer(template({ |
| 87 | + config: _extends({}, config, { |
| 88 | + classBreakpoints: Object.keys(config.breakpoints).slice(0, -1), |
| 89 | + intro |
| 90 | + }) |
| 91 | + })); |
| 92 | + return chunk; |
| 93 | + })).pipe(rename(path => { |
| 94 | + // a template file of the form AAAA.BBB.hbs produces output file AAAA.BBB |
| 95 | + var dot = path.basename.lastIndexOf("."); |
| 96 | + path.extname = path.basename.substring(dot); |
| 97 | + path.basename = path.basename.substring(0, dot); |
| 98 | + })).pipe(gulp.dest(dirDest)); |
| 99 | +}); |
| 100 | + |
| 101 | +gulp.task("scss", ["valuesClean"], function () { |
| 102 | + return gulp.src(`${__dirname}/src/scss/**/*.s\css`).pipe(gulp.dest(dirDestScss)); |
| 103 | +}); |
| 104 | + |
| 105 | +gulp.task("scssRename", ["scss"], function () { |
| 106 | + return gulp.src(`${dirDestScss}/gridish-grid.s\css`).pipe(vinylPaths(del)).pipe(rename(`${prefix}-grid.s\css`)).pipe(gulp.dest(dirDestScss)); |
| 107 | +}); |
| 108 | + |
| 109 | +gulp.task("scssRenameLegacy", ["scssRename"], function () { |
| 110 | + return gulp.src(`${dirDestScss}/gridish-grid-legacy.s\css`).pipe(vinylPaths(del)).pipe(rename(`${prefix}-grid-legacy.s\css`)).pipe(gulp.dest(dirDestScss)); |
| 111 | +}); |
| 112 | + |
| 113 | +gulp.task("sketchClean", ["sketchZip"], function () { |
| 114 | + return del([dirDestSketch]); |
| 115 | +}); |
| 116 | + |
| 117 | +gulp.task("sketchFiles", ["docs"], function () { |
| 118 | + return gulp.src([`${__dirname}/src/sketch/files/**/*`, `!${__dirname}/src/sketch/files/pages/BC333699-815E-4E1B-9816-9836EDA5B291.json`]).pipe(gulp.dest(dirDestSketch)); |
| 119 | +}); |
| 120 | + |
| 121 | +gulp.task("sketchPage", ["sketchFiles"], function () { |
| 122 | + // Add breakpoint values to extra artboards |
| 123 | + const originalBreakpoints = config.breakpoints; |
| 124 | + let allBreakpoints = originalBreakpoints; |
| 125 | + for (let i = 0; i < Object.values(config.extraArtboards).length; i++) { |
| 126 | + const name = Object.keys(config.extraArtboards)[i]; |
| 127 | + const value = Object.values(config.extraArtboards)[i]; |
| 128 | + let found = false; |
| 129 | + for (let j = 0; j < Object.values(originalBreakpoints).length; j++) { |
| 130 | + // should catch at max |
| 131 | + if (Object.values(originalBreakpoints)[j + 1] !== undefined && Object.values(originalBreakpoints)[j + 1].breakpoint > value && !found) { |
| 132 | + allBreakpoints[name] = _extends({}, Object.values(originalBreakpoints)[j], { |
| 133 | + breakpoint: value |
| 134 | + }); |
| 135 | + found = true; |
| 136 | + } else if (Object.values(originalBreakpoints)[i + 1] === undefined) { |
| 137 | + allBreakpoints[name] = _extends({}, Object.values(originalBreakpoints)[i], { |
| 138 | + breakpoint: value |
| 139 | + }); |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + // Sort all breakpoints by size |
| 145 | + let sorted = Object.values(allBreakpoints); |
| 146 | + for (let i = 0; i < sorted.length; i++) { |
| 147 | + sorted[i] = _extends({}, sorted[i], { |
| 148 | + name: Object.keys(allBreakpoints)[i] |
| 149 | + }); |
| 150 | + } |
| 151 | + sorted = sorted.sort(function (a, b) { |
| 152 | + return a.breakpoint - b.breakpoint; |
| 153 | + }); |
| 154 | + |
| 155 | + // Make artboards for each breakpoint |
| 156 | + let layers = []; |
| 157 | + let x = 0; |
| 158 | + for (let i = 0; i < sorted.length; i++) { |
| 159 | + x = i > 0 ? x + (sorted[i - 1].breakpoint + 1) * config.rem : 0; |
| 160 | + const values = sorted[i]; |
| 161 | + const width = values.breakpoint * config.rem; |
| 162 | + const margin = parseUnit(values.margin, width); |
| 163 | + const gutter = parseUnit(values.gutter); |
| 164 | + const gridWidth = width - margin * 2; |
| 165 | + const gutterWidth = gutter; |
| 166 | + |
| 167 | + layers.push(_extends({}, artboard, { |
| 168 | + name: `${values.name}-${width}px-${values.columns}`, |
| 169 | + do_objectID: artboard.do_objectID.slice(0, -1) + i, |
| 170 | + frame: _extends({}, artboard.frame, { |
| 171 | + width, |
| 172 | + x |
| 173 | + }), |
| 174 | + grid: _extends({}, artboard.grid, { |
| 175 | + gridSize: config.rowHeight * config.rem |
| 176 | + }), |
| 177 | + layout: _extends({}, artboard.layout, { |
| 178 | + columnWidth: (gridWidth - gutterWidth * values.columns) / values.columns, |
| 179 | + gutterWidth, |
| 180 | + horizontalOffset: margin, |
| 181 | + numberOfColumns: values.columns, |
| 182 | + totalWidth: gridWidth |
| 183 | + }) |
| 184 | + })); |
| 185 | + } |
| 186 | + return gulp.src(`${__dirname}/src/sketch/files/pages/BC333699-815E-4E1B-9816-9836EDA5B291.json`).pipe(jeditor({ |
| 187 | + layers |
| 188 | + })).pipe(gulp.dest(`${dirDestSketch}/pages`)); |
| 189 | +}); |
| 190 | + |
| 191 | +gulp.task("sketchZip", ["sketchPage"], function () { |
| 192 | + return gulp.src(`${dirDestSketch}/**/*`).pipe(zip(`${prefix}-grid.zip`)).pipe(rename(`${prefix}-grid.sketch`)).pipe(vinylPaths(del)).pipe(gulp.dest(dirDest)); |
| 193 | +}); |
| 194 | + |
| 195 | +gulp.task("values", ["valuesPrep"], function () { |
| 196 | + return fs.createReadStream(dirDestDesign).pipe(jsonSass({ |
| 197 | + prefix: "$grid-values: " |
| 198 | + })).pipe(source(routeConfig)).pipe(rename("_values.scss")).pipe(gulp.dest(dirDestScss)); |
| 199 | +}); |
| 200 | + |
| 201 | +gulp.task("valuesClean", ["values"], function () { |
| 202 | + return fs.unlinkSync(dirDestDesign); |
| 203 | +}); |
| 204 | + |
| 205 | +gulp.task("valuesPrep", ["clean"], function () { |
| 206 | + return fs.writeFileSync(dirDestDesign, JSON.stringify(_extends({}, config, { |
| 207 | + paths: null |
| 208 | + }))); |
| 209 | +}); |
| 210 | + |
| 211 | +gulp.task("default", ["sketchClean"], function () { |
| 212 | + console.log(`CSS Gridish finished building your ${prefix} grid in ${dirDest}! 🏁`); |
| 213 | +}); |
| 214 | + |
| 215 | +gulp.start("default"); |
0 commit comments