uikit 3.8.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/{.eslintrc.js → .eslintrc.json} +5 -5
  2. package/CHANGELOG.md +21 -0
  3. package/build/{.eslintrc.js → .eslintrc.json} +5 -5
  4. package/build/build.js +59 -80
  5. package/build/icons.js +2 -11
  6. package/build/less.js +23 -38
  7. package/build/package.json +4 -0
  8. package/build/prefix.js +38 -94
  9. package/build/publishDev.js +11 -18
  10. package/build/release.js +34 -60
  11. package/build/scope.js +49 -84
  12. package/build/scss.js +14 -16
  13. package/build/util.js +107 -81
  14. package/dist/css/uikit-core-rtl.css +10 -10
  15. package/dist/css/uikit-core-rtl.min.css +1 -1
  16. package/dist/css/uikit-core.css +10 -10
  17. package/dist/css/uikit-core.min.css +1 -1
  18. package/dist/css/uikit-rtl.css +10 -10
  19. package/dist/css/uikit-rtl.min.css +1 -1
  20. package/dist/css/uikit.css +10 -10
  21. package/dist/css/uikit.min.css +1 -1
  22. package/dist/js/components/countdown.js +1 -1
  23. package/dist/js/components/countdown.min.js +1 -1
  24. package/dist/js/components/filter.js +1 -1
  25. package/dist/js/components/filter.min.js +1 -1
  26. package/dist/js/components/lightbox-panel.js +1 -1
  27. package/dist/js/components/lightbox-panel.min.js +1 -1
  28. package/dist/js/components/lightbox.js +1 -1
  29. package/dist/js/components/lightbox.min.js +1 -1
  30. package/dist/js/components/notification.js +1 -1
  31. package/dist/js/components/notification.min.js +1 -1
  32. package/dist/js/components/parallax.js +1 -1
  33. package/dist/js/components/parallax.min.js +1 -1
  34. package/dist/js/components/slider-parallax.js +1 -1
  35. package/dist/js/components/slider-parallax.min.js +1 -1
  36. package/dist/js/components/slider.js +1 -1
  37. package/dist/js/components/slider.min.js +1 -1
  38. package/dist/js/components/slideshow-parallax.js +1 -1
  39. package/dist/js/components/slideshow-parallax.min.js +1 -1
  40. package/dist/js/components/slideshow.js +1 -1
  41. package/dist/js/components/slideshow.min.js +1 -1
  42. package/dist/js/components/sortable.js +1 -1
  43. package/dist/js/components/sortable.min.js +1 -1
  44. package/dist/js/components/tooltip.js +1 -1
  45. package/dist/js/components/tooltip.min.js +1 -1
  46. package/dist/js/components/upload.js +1 -1
  47. package/dist/js/components/upload.min.js +1 -1
  48. package/dist/js/uikit-core.js +23 -14
  49. package/dist/js/uikit-core.min.js +2 -2
  50. package/dist/js/uikit-icons.js +1 -1
  51. package/dist/js/uikit-icons.min.js +1 -1
  52. package/dist/js/uikit.js +23 -14
  53. package/dist/js/uikit.min.js +2 -2
  54. package/package.json +15 -14
  55. package/src/js/util/event.js +7 -7
  56. package/src/js/util/viewport.js +13 -7
  57. package/src/less/components/base.less +7 -4
  58. package/src/less/components/card.less +7 -7
  59. package/src/less/components/form-range.less +1 -1
  60. package/src/less/components/notification.less +1 -1
  61. package/src/less/components/padding.less +1 -1
  62. package/src/less/components/spinner.less +2 -2
  63. package/src/less/components/table.less +3 -3
  64. package/src/less/components/transition.less +4 -4
  65. package/src/less/components/utility.less +4 -4
  66. package/src/scss/components/base.scss +7 -4
  67. package/src/scss/components/card.scss +7 -7
  68. package/src/scss/components/form-range.scss +1 -1
  69. package/src/scss/components/notification.scss +1 -1
  70. package/src/scss/components/padding.scss +1 -1
  71. package/src/scss/components/spinner.scss +2 -2
  72. package/src/scss/components/table.scss +3 -3
  73. package/src/scss/components/transition.scss +4 -4
  74. package/src/scss/components/utility.scss +4 -4
  75. package/src/scss/variables-theme.scss +16 -13
  76. package/src/scss/variables.scss +16 -13
  77. package/tests/scroll.html +65 -1
package/build/release.js CHANGED
@@ -1,22 +1,33 @@
1
- const fs = require('fs');
2
- const {promisify} = require('util');
3
- const archiver = require('archiver');
4
- const inquirer = require('inquirer');
5
- const pkg = require('../package.json');
6
- const dateFormat = require('dateformat');
7
- const args = require('minimist')(process.argv);
8
- const {glob, logFile, read, write} = require('./util');
9
- const {coerce, inc, prerelease, valid} = require('semver');
10
- const exec = promisify(require('child_process').exec);
11
-
12
- inquireVersion(args.v || args.version)
13
- .then(updateVersion)
14
- .then(compile)
15
- .then(createPackage)
16
- .catch(({message}) => {
17
- console.error(message);
18
- process.exitCode = 1;
19
- });
1
+ import archiver from 'archiver';
2
+ import inquirer from 'inquirer';
3
+ import dateFormat from 'dateformat/lib/dateformat.js';
4
+ import {createWriteStream} from 'fs';
5
+ import semver from 'semver';
6
+ import {args, getVersion, glob, logFile, replaceInFile, run} from './util.js';
7
+
8
+ const {coerce, inc, prerelease, valid} = semver;
9
+
10
+ const prevVersion = await getVersion();
11
+
12
+ console.log(prevVersion, inc(prevVersion, prerelease(prevVersion) ? 'prerelease' : 'patch'));
13
+
14
+ const version = await inquireVersion(args.v || args.version);
15
+
16
+ await Promise.all([
17
+ run(`npm version ${version} --git-tag-version false`),
18
+ replaceInFile('CHANGELOG.md', data =>
19
+ data.replace(/^##\s*WIP/m, `## ${versionFormat(version)} (${dateFormat(Date.now(), 'mmmm d, yyyy')})`)
20
+ ),
21
+ replaceInFile('.github/ISSUE_TEMPLATE/bug-report.md', data =>
22
+ data.replace(prevVersion, version)
23
+ )
24
+ ]);
25
+
26
+ await run('yarn compile');
27
+ await run('yarn compile-rtl');
28
+ await run('yarn build-scss');
29
+
30
+ await createPackage(version);
20
31
 
21
32
  async function inquireVersion(v) {
22
33
 
@@ -26,42 +37,20 @@ async function inquireVersion(v) {
26
37
 
27
38
  const prompt = inquirer.createPromptModule();
28
39
 
29
- const {version} = await prompt({
40
+ return (await prompt({
30
41
  name: 'version',
31
42
  message: 'Enter a version',
32
- default: () => inc(pkg.version, prerelease(pkg.version) ? 'prerelease' : 'patch'),
43
+ default: () => inc(prevVersion, prerelease(prevVersion) ? 'prerelease' : 'patch'),
33
44
  validate: val => !!val.length || 'Invalid version'
34
- });
35
-
36
- return version;
37
-
38
- }
39
-
40
- async function updateVersion(version) {
41
- await Promise.all([
42
- run(`npm version ${version} --git-tag-version false`),
43
- replaceInFile('CHANGELOG.md', data => data.replace(/^##\s*WIP/m, `## ${versionFormat(version)} (${dateFormat(Date.now(), 'mmmm d, yyyy')})`)),
44
- replaceInFile('.github/ISSUE_TEMPLATE/bug-report.md', data => data.replace(pkg.version, version))
45
- ]);
45
+ })).version;
46
46
 
47
- return version;
48
- }
49
-
50
- async function compile(version) {
51
- await sequential([
52
- () => run('yarn compile'),
53
- () => run('yarn compile-rtl'),
54
- () => run('yarn build-scss')
55
- ]);
56
-
57
- return version;
58
47
  }
59
48
 
60
49
  async function createPackage(version) {
61
50
  const file = `dist/uikit-${version}.zip`;
62
51
  const archive = archiver('zip');
63
52
 
64
- archive.pipe(fs.createWriteStream(file));
53
+ archive.pipe(createWriteStream(file));
65
54
 
66
55
  (await glob('dist/{js,css}/uikit?(-icons|-rtl)?(.min).{js,css}')).forEach(file =>
67
56
  archive.file(file, {name: file.substring(5)})
@@ -74,18 +63,3 @@ async function createPackage(version) {
74
63
  function versionFormat(version) {
75
64
  return [coerce(version).version].concat(prerelease(version) || []).join(' ');
76
65
  }
77
-
78
- async function replaceInFile(file, fn) {
79
- await write(file, fn(await read(file)));
80
- }
81
-
82
- async function sequential(tasks) {
83
- await tasks.reduce((promise, task) => promise.then(task), Promise.resolve());
84
- }
85
-
86
- async function run(cmd) {
87
- const {stdout, stderr} = await exec(cmd);
88
-
89
- stdout && console.log(stdout.trim());
90
- stderr && console.log(stderr.trim());
91
- }
package/build/scope.js CHANGED
@@ -1,12 +1,6 @@
1
- const {glob, minify, read, renderLess, write, validClassName} = require('./util');
2
- const argv = require('minimist')(process.argv.slice(2));
1
+ import {args, glob, minify, read, renderLess, replaceInFile, validClassName} from './util.js';
3
2
 
4
- argv._.forEach(arg => {
5
- const tokens = arg.split('=');
6
- argv[tokens[0]] = tokens[1] || true;
7
- });
8
-
9
- if (argv.h || argv.help) {
3
+ if (args.h || args.help) {
10
4
  console.log(`
11
5
  usage:
12
6
 
@@ -19,58 +13,45 @@ if (argv.h || argv.help) {
19
13
  scope.js cleanup // will remove current scope
20
14
 
21
15
  `);
22
- } else {
23
- run().catch(({message}) => {
24
- console.error(message);
25
- process.exitCode = 1;
26
- });
16
+ process.exit(0);
27
17
  }
18
+ const currentScopeRe = /\/\* scoped: ([^*]*) \*\//;
19
+ const currentScopeLegacyRe = /\.(uk-scope)/;
28
20
 
29
- async function run() {
30
-
31
- const files = await readFiles();
32
- const oldScope = getScope(files);
33
-
34
- if (argv.cleanup && oldScope) {
35
- cleanup(files, oldScope);
36
- } else if (oldScope) {
37
- const newScope = getNewScope();
38
-
39
- if (oldScope === newScope) {
40
- console.warn(`Already scoped with: ${oldScope}`);
41
- return;
42
- }
21
+ const files = await glob('dist/**/!(*.min).css');
22
+ const prevScope = await getScope(files);
43
23
 
44
- cleanup(files, oldScope);
45
- await scope(files, newScope);
24
+ if (args.cleanup && prevScope) {
25
+ await cleanup(files, prevScope);
26
+ } else if (prevScope) {
27
+ const newScope = getNewScope();
46
28
 
47
- } else {
48
- await scope(files, getNewScope());
29
+ if (prevScope === newScope) {
30
+ console.warn(`Already scoped with: ${prevScope}`);
31
+ process.exit(0);
49
32
  }
50
33
 
51
- await store(files);
34
+ await cleanup(files, prevScope);
35
+ await scope(files, newScope);
52
36
 
37
+ } else {
38
+ await scope(files, getNewScope());
53
39
  }
54
40
 
55
- async function readFiles() {
56
-
57
- const files = await glob('dist/**/!(*.min).css');
58
- return Promise.all(files.map(async file => {
59
-
41
+ async function getScope(files) {
42
+ for (const file of files) {
60
43
  const data = await read(file);
61
- return {file, data};
62
-
63
- }));
64
-
65
- }
66
-
67
- function getScope(files) {
68
- return files.reduce((scope, {data}) => scope || isScoped(data), '');
44
+ const scope = (data.match(currentScopeRe) || data.match(currentScopeLegacyRe) || [])[1];
45
+ if (scope) {
46
+ return scope;
47
+ }
48
+ }
49
+ return '';
69
50
  }
70
51
 
71
52
  function getNewScope() {
72
53
 
73
- const scopeFromInput = argv.scope || argv.s || 'uk-scope';
54
+ const scopeFromInput = args.scope || args.s || 'uk-scope';
74
55
 
75
56
  if (validClassName.test(scopeFromInput)) {
76
57
  return scopeFromInput;
@@ -80,49 +61,33 @@ function getNewScope() {
80
61
  }
81
62
 
82
63
  async function scope(files, scope) {
83
- await Promise.all(
84
- files.map(async store => {
85
- try {
86
-
87
- const output = await renderLess(`.${scope} {\n${stripComments(store.data)}\n}`);
88
- store.data = `/* scoped: ${scope} */\n${
89
- output
90
- .replace(new RegExp(`.${scope} ${/{(.|[\r\n])*?}/.source}`), '')
91
- .replace(new RegExp(`.${scope}${/\s((\.(uk-(drag|modal-page|offcanvas-page|offcanvas-flip)))|html)/.source}`, 'g'), '$1')
92
- }`;
93
-
94
- } catch (e) {
95
- console.error(store.file, e);
96
- }
97
- })
98
- );
99
- }
100
-
101
- async function store(files) {
102
- return Promise.all(
103
- files.map(async ({file, data}) => {
104
- await write(file, data);
105
- await minify(file);
106
- })
107
- );
64
+ for (const file of files) {
65
+ await replaceInFile(file, async data => {
66
+ const output = await renderLess(`.${scope} {\n${stripComments(data)}\n}`);
67
+ return `/* scoped: ${scope} */\n${
68
+ output
69
+ .replace(new RegExp(`.${scope} ${/{(.|[\r\n])*?}/.source}`), '')
70
+ .replace(new RegExp(`.${scope}${/\s((\.(uk-(drag|modal-page|offcanvas-page|offcanvas-flip)))|html)/.source}`, 'g'), '$1')
71
+ }`;
72
+ });
73
+ await minify(file);
74
+ }
108
75
  }
109
76
 
110
- const currentScopeRe = /\/\* scoped: ([^*]*) \*\//;
111
- const currentScopeLegacyRe = /\.(uk-scope)/;
112
-
113
- function cleanup(files, scope) {
77
+ async function cleanup(files, scope) {
114
78
  const string = scope.split(' ').map(scope => `.${scope}`).join(' ');
115
- files.forEach(store => {
116
- store.data = store.data
79
+ for (const file of files) {
80
+ await replaceInFile(file, data => data
117
81
  .replace(new RegExp(/ */.source + string + / ({[\s\S]*?})?/.source, 'g'), '') // replace classes
118
- .replace(new RegExp(currentScopeRe.source, 'g'), ''); // remove scope comment
119
- });
120
- }
121
-
122
- function isScoped(data) {
123
- return (data.match(currentScopeRe) || data.match(currentScopeLegacyRe) || [])[1];
82
+ .replace(new RegExp(currentScopeRe.source, 'g'), '') // remove scope comment
83
+ );
84
+ }
124
85
  }
125
86
 
126
87
  function stripComments(input) {
127
- return input.replace(/\/\*(.|\n)*?\*\//gm, '').split('\n').filter(line => line.trim().substr(0, 2) !== '//').join('\n');
88
+ return input
89
+ .replace(/\/\*(.|\n)*?\*\//gm, '')
90
+ .split('\n')
91
+ .filter(line => line.trim().substr(0, 2) !== '//')
92
+ .join('\n');
128
93
  }
package/build/scss.js CHANGED
@@ -1,8 +1,4 @@
1
- const fs = require('fs');
2
- const util = require('./util');
3
- const glob = require('glob');
4
-
5
- const {write} = util;
1
+ import {glob, read, write} from './util.js';
6
2
 
7
3
  const themeMixins = {};
8
4
  const coreMixins = {};
@@ -74,9 +70,10 @@ const inverseTemplate = ` @include hook-inverse-component-base();
74
70
  @include hook-inverse-component-utility();`;
75
71
 
76
72
  /* First Step: Go through all files */
77
- glob.sync('src/less/**/*.less').forEach(file => {
73
+ for (const file of await glob('src/less/**/*.less')) {
74
+
75
+ const data = await read(file);
78
76
 
79
- const data = fs.readFileSync(file, 'utf8');
80
77
  /* replace all LESS stuff with SCSS */
81
78
  let scssData = data.replace(/\/less\//g, '/scss/') // change less/ dir to scss/ on imports
82
79
  .replace(/\.less/g, '.scss') // change .less extensions to .scss on imports
@@ -98,6 +95,7 @@ glob.sync('src/less/**/*.less').forEach(file => {
98
95
  .replace(/(\.[\w-\\@]+)\s*when\s*\((\$[\w-]*)\s*=\s*(\w+)\)\s*({\s*.*?\s*})/gs, '@if ($2 == $3) {\n$1 $4\n}') // replace conditionals
99
96
  .replace(/\${/g, '#{$') // string literals: from: /~"(.*)"/g, to: '#{"$1"}'
100
97
  .replace(/[^(](-\$[\w-]*)/g, ' ($1)') // surround negative variables with brackets
98
+ .replace(/(--[\w-]+:\s*)~'([^']+)'/g, '$1$2') // string literals in custom properties
101
99
  .replace(/~('[^']+')/g, 'unquote($1)'); // string literals: for real
102
100
 
103
101
  /* File name of the current file */
@@ -115,7 +113,7 @@ glob.sync('src/less/**/*.less').forEach(file => {
115
113
 
116
114
  /* get all Variables but not from the mixin.less file */
117
115
  if (filename !== 'mixin') {
118
- scssData = getVariablesFromFile(file, scssData);
116
+ scssData = await getVariablesFromFile(file, scssData);
119
117
  }
120
118
 
121
119
  if (filename === 'uikit.theme') {
@@ -130,30 +128,30 @@ glob.sync('src/less/**/*.less').forEach(file => {
130
128
  scssData = mixinTemplate;
131
129
  }
132
130
 
133
- return write(file.replace(/less/g, 'scss').replace('.theme.', '-theme.'), scssData);
131
+ await write(file.replace(/less/g, 'scss').replace('.theme.', '-theme.'), scssData);
134
132
 
135
- });
133
+ }
136
134
 
137
135
  /* Second Step write all new needed files for SASS */
138
136
 
139
137
  /* write mixins into new file */
140
138
  const mixins_theme = Object.keys(themeMixins).map(function (key) { return themeMixins[key]; });
141
- write('src/scss/mixins-theme.scss', mixins_theme.join('\n'));
139
+ await write('src/scss/mixins-theme.scss', mixins_theme.join('\n'));
142
140
 
143
141
  const mixins_core = Object.keys(coreMixins).map(function (key) { return coreMixins[key]; });
144
- write('src/scss/mixins.scss', mixins_core.join('\n'));
142
+ await write('src/scss/mixins.scss', mixins_core.join('\n'));
145
143
 
146
144
  /* write core variables */
147
145
  const compactCoreVar = new Set();
148
146
  Object.keys(coreVar).map(key => getAllDependencies(coreVar, key).forEach(dependency => compactCoreVar.add(dependency)));
149
147
 
150
- write('src/scss/variables.scss', Array.from(compactCoreVar).join('\n'));
148
+ await write('src/scss/variables.scss', Array.from(compactCoreVar).join('\n'));
151
149
 
152
150
  /* write theme variables */
153
151
  const compactThemeVar = new Set();
154
152
  Object.keys(themeVar).map(key => getAllDependencies(themeVar, key).forEach(dependency => compactThemeVar.add(dependency)));
155
153
 
156
- write('src/scss/variables-theme.scss', Array.from(compactThemeVar).join('\n'));
154
+ await write('src/scss/variables-theme.scss', Array.from(compactThemeVar).join('\n'));
157
155
 
158
156
  /*
159
157
  * recursive function to get a dependencie Set which is ordered so that no depencies exist to a later on entry
@@ -228,7 +226,7 @@ function getMixinsFromFile(file, data) {
228
226
  * function to extract all the variables from a given file with its data.
229
227
  * @return an updated data where the icons have been replaced by the actual SVG data.
230
228
  */
231
- function getVariablesFromFile(file, data) {
229
+ async function getVariablesFromFile(file, data) {
232
230
  const regex = /(\$[\w-]*)\s*:\s*(.*);/g;
233
231
  let match = regex.exec(data);
234
232
 
@@ -239,7 +237,7 @@ function getVariablesFromFile(file, data) {
239
237
 
240
238
  const iconregex = /(\$[\w-]+)\s*:\s*"\.\.\/\.\.\/images\/backgrounds\/([\w./-]+)" !default;/g;
241
239
  const iconmatch = iconregex.exec(match[0]);
242
- let svg = fs.readFileSync(`src/images/backgrounds/${iconmatch[2]}`).toString();
240
+ let svg = (await read(`src/images/backgrounds/${iconmatch[2]}`)).toString();
243
241
  svg = `"${svg.replace(/\r?\n|\r/g, '%0A')
244
242
  .replace(/"/g, '\'')
245
243
  .replace(/\s/g, '%20')
package/build/util.js CHANGED
@@ -1,55 +1,64 @@
1
- const fs = require('fs');
2
- const less = require('less');
3
- const SVGO = require('svgo');
4
- const rollup = require('rollup');
5
- const postcss = require('postcss');
6
- const uglify = require('uglify-js');
7
- const {promisify} = require('util');
8
- const CleanCSS = require('clean-css');
9
- const html = require('rollup-plugin-html');
10
- const buble = require('@rollup/plugin-buble');
11
- const replace = require('@rollup/plugin-replace');
12
- const alias = require('@rollup/plugin-alias');
13
- const {basename, dirname, resolve} = require('path');
14
- const {version} = require('../package.json');
15
- const banner = `/*! UIkit ${version} | https://www.getuikit.com | (c) 2014 - ${new Date().getFullYear()} YOOtheme | MIT License */\n`;
16
-
17
- exports.banner = banner;
18
- exports.validClassName = /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/;
19
-
20
- exports.glob = promisify(require('glob'));
21
-
22
- const readFile = promisify(fs.readFile);
23
- exports.read = async function (file, cb) {
24
-
25
- const data = await readFile(file, 'utf8');
26
- cb && cb(data);
27
- return data;
28
-
29
- };
1
+ import fs from 'fs-extra';
2
+ import less from 'less';
3
+ import { URL } from 'url';
4
+ import postcss from 'postcss';
5
+ import globImport from 'glob';
6
+ import {rollup} from 'rollup';
7
+ import {optimize} from 'svgo';
8
+ import uglify from 'uglify-js';
9
+ import {promisify} from 'util';
10
+ import minimist from 'minimist';
11
+ import CleanCSS from 'clean-css';
12
+ import html from 'rollup-plugin-html';
13
+ import buble from '@rollup/plugin-buble';
14
+ import alias from '@rollup/plugin-alias';
15
+ import replace from '@rollup/plugin-replace';
16
+ import {basename, dirname, resolve} from 'path';
17
+ import {exec as execImport} from 'child_process';
18
+
19
+ export const exec = promisify(execImport);
20
+ export const glob = promisify(globImport);
21
+ export const readJson = fs.readJson;
22
+ export const pathExists = fs.pathExists;
23
+ export const __dirname = new URL('.', import.meta.url).pathname;
24
+
25
+ export const banner = `/*! UIkit ${await getVersion()} | https://www.getuikit.com | (c) 2014 - ${new Date().getFullYear()} YOOtheme | MIT License */\n`;
26
+ export const validClassName = /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/;
27
+
28
+ const argv = minimist(process.argv.slice(2));
29
+
30
+ argv._.forEach(arg => {
31
+ const tokens = arg.split('=');
32
+ argv[tokens[0]] = tokens[1] || true;
33
+ });
34
+
35
+ export const args = argv;
36
+
37
+ export function read(file) {
38
+ return fs.readFile(file, 'utf8');
39
+ }
30
40
 
31
- const writeFile = promisify(fs.writeFile);
32
- exports.write = async function (dest, data) {
41
+ export async function write(dest, data) {
33
42
 
34
- const err = await writeFile(dest, data);
43
+ const err = await fs.writeFile(dest, data);
35
44
 
36
45
  if (err) {
37
46
  console.log(err);
38
47
  throw err;
39
48
  }
40
49
 
41
- await exports.logFile(dest);
50
+ await logFile(dest);
42
51
 
43
52
  return dest;
44
53
 
45
- };
54
+ }
46
55
 
47
- exports.logFile = async function (file) {
48
- const data = await exports.read(file);
49
- console.log(`${cyan(file)} ${getSize(data)}`);
50
- };
56
+ export async function logFile(file) {
57
+ const data = await read(file);
58
+ console.log(`${cyan(resolve(file))} ${getSize(data)}`);
59
+ }
51
60
 
52
- exports.minify = async function (file) {
61
+ export async function minify(file) {
53
62
 
54
63
  const {styles} = await new CleanCSS({
55
64
  advanced: false,
@@ -58,19 +67,19 @@ exports.minify = async function (file) {
58
67
  returnPromise: true
59
68
  }).minify([file]);
60
69
 
61
- await exports.write(`${resolve(dirname(file), basename(file, '.css'))}.min.css`, styles);
70
+ await write(`${resolve(dirname(file), basename(file, '.css'))}.min.css`, styles);
62
71
 
63
72
  return styles;
64
73
 
65
- };
74
+ }
66
75
 
67
- exports.renderLess = async function (data, options) {
76
+ export async function renderLess(data, options) {
68
77
  return postcss()
69
- .use(postcss.plugin('calc', () =>
70
- css => {
71
- css.walk(node => {
78
+ .use({
79
+ postcssPlugin: 'calc',
80
+ Once(root) {
81
+ root.walk(node => {
72
82
  const {type} = node;
73
-
74
83
  if (type === 'decl') {
75
84
  node.value = postcss.list.space(node.value).map(value =>
76
85
  value.startsWith('calc(')
@@ -80,23 +89,23 @@ exports.renderLess = async function (data, options) {
80
89
  }
81
90
  });
82
91
  }
83
- ))
92
+ })
84
93
  .process((await less.render(data, options)).css)
85
94
  .css;
86
- };
95
+ }
87
96
 
88
- exports.compile = async function (file, dest, {external, globals, name, aliases, replaces, minify = true}) {
97
+ export async function compile(file, dest, {external, globals, name, aliases, replaces, minify = true}) {
89
98
 
90
99
  name = (name || '').replace(/[^\w]/g, '_');
91
100
 
92
- const bundle = await rollup.rollup({
101
+ const bundle = await rollup({
93
102
  external,
94
103
  input: resolve(file),
95
104
  plugins: [
96
105
  replace({
97
106
  preventAssignment: true,
98
107
  values: Object.assign({
99
- VERSION: `'${version}'`
108
+ VERSION: `'${await getVersion()}'`
100
109
  }, replaces)}
101
110
  ),
102
111
  alias({
@@ -116,61 +125,78 @@ exports.compile = async function (file, dest, {external, globals, name, aliases,
116
125
 
117
126
  let {output: [{code, map}]} = await bundle.generate({
118
127
  globals,
128
+ banner,
119
129
  format: 'umd',
120
- banner: exports.banner,
121
130
  amd: {id: `UIkit${name}`.toLowerCase()},
122
- name: `UIkit${exports.ucfirst(name)}`,
131
+ name: `UIkit${ucfirst(name)}`,
123
132
  sourcemap: !minify ? 'inline' : false
124
133
  });
125
134
 
126
135
  code = code.replace(/(>)\\n\s+|\\n\s+(<)/g, '$1 $2');
127
136
 
128
137
  return Promise.all([
129
- exports.write(`${dest}.js`, code + (!minify ? '\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,' + Buffer.from(map.toString()).toString('base64') : '')),
130
- minify ? exports.write(`${dest}.min.js`, uglify.minify(code, {output: {preamble: exports.banner}}).code) : null
138
+ write(`${dest}.js`, code + (!minify ? '\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,' + Buffer.from(map.toString()).toString('base64') : '')),
139
+ minify ? write(`${dest}.min.js`, uglify.minify(code, {output: {preamble: banner}}).code) : null
131
140
  ])[0];
132
141
 
133
- };
134
-
135
- exports.icons = async function (src) {
142
+ }
136
143
 
137
- const svgo = new SVGO({
144
+ export async function icons(src) {
138
145
 
146
+ const options = {
139
147
  plugins: [
140
- {removeViewBox: false},
141
148
  {
142
- cleanupNumericValues: {
143
- floatPrecision: 3
149
+ name: 'preset-default',
150
+ params: {
151
+ overrides: {
152
+ removeViewBox: false,
153
+ cleanupNumericValues: {
154
+ floatPrecision: 3
155
+ },
156
+ convertPathData: false,
157
+ convertShapeToPath: false,
158
+ mergePaths: false,
159
+ removeDimensions: false,
160
+ removeStyleElement: false,
161
+ removeScriptElement: false,
162
+ removeUnknownsAndDefaults: false,
163
+ removeUselessStrokeAndFill: false
164
+ }
144
165
  }
145
- },
146
- {convertPathData: false},
147
- {convertShapeToPath: false},
148
- {mergePaths: false},
149
- {removeDimensions: false},
150
- {removeStyleElement: false},
151
- {removeScriptElement: false},
152
- {removeUnknownsAndDefaults: false},
153
- {removeUselessStrokeAndFill: false}
166
+ }
154
167
  ]
168
+ };
155
169
 
156
- });
157
- const files = await exports.glob(src, {nosort: true});
158
- const icons = await Promise.all(files.map(async file => {
159
- const data = await exports.read(file);
160
- const {data: svg} = await svgo.optimize(data);
161
- return svg;
162
- }));
170
+ const files = await glob(src, {nosort: true});
171
+ const icons = await Promise.all(files.map(async file =>
172
+ (await optimize(await read(file), options)).data
173
+ ));
163
174
 
164
175
  return JSON.stringify(files.reduce((result, file, i) => {
165
176
  result[basename(file, '.svg')] = icons[i];
166
177
  return result;
167
178
  }, {}), null, ' ');
168
179
 
169
- };
180
+ }
181
+
182
+ export async function run(cmd) {
183
+ const {stdout, stderr} = await exec(cmd);
184
+
185
+ stdout && console.log(stdout.trim());
186
+ stderr && console.log(stderr.trim());
187
+ }
170
188
 
171
- exports.ucfirst = function (str) {
189
+ export function ucfirst(str) {
172
190
  return str.length ? str.charAt(0).toUpperCase() + str.slice(1) : '';
173
- };
191
+ }
192
+
193
+ export async function getVersion() {
194
+ return JSON.parse(await read(resolve(__dirname, '../package.json'))).version;
195
+ }
196
+
197
+ export async function replaceInFile(file, fn) {
198
+ await write(file, await fn(await read(file)));
199
+ }
174
200
 
175
201
  function cyan(str) {
176
202
  return `\x1b[1m\x1b[36m${str}\x1b[39m\x1b[22m`;