diff --git a/.build/iconfont.html b/.build/iconfont.html
new file mode 100644
index 0000000000..a61a6ad330
--- /dev/null
+++ b/.build/iconfont.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+ Tabler Icons - version <%= v %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <% glyphs.forEach(function(glyph) { %>
+
+
+
<%= glyph.name %>
+
+ ti ti-<%= glyph.name %>
+ \<%= glyph.unicode[0].codePointAt(0).toString(16) %>
+
+
+ <% }) %>
+
+
+
+
+
+
+
diff --git a/.build/iconfont.scss b/.build/iconfont.scss
new file mode 100644
index 0000000000..97c21d4e80
--- /dev/null
+++ b/.build/iconfont.scss
@@ -0,0 +1,40 @@
+/*!
+ * Tabler Icons <%= v %> by tabler - https://tabler.io
+ * License - https://github.com/tabler/tabler-icons/blob/master/LICENSE
+ */
+$ti-font-family: '<%= fileName %>' !default;
+$ti-font-path: './fonts' !default;
+$ti-font-display: null !default;
+$ti-icon-prefix: 'ti' !default;
+
+@font-face {
+ font-family: $ti-font-family;
+ font-style: normal;
+ font-weight: 400;
+ font-display: $ti-font-display;
+ src: url('#{$ti-font-path}/<%= fileName %>.eot');
+ src: url('#{$ti-font-path}/<%= fileName %>.eot?#iefix') format('embedded-opentype'),
+ url('#{$ti-font-path}/<%= fileName %>.woff2') format('woff2'),
+ url('#{$ti-font-path}/<%= fileName %>.woff') format('woff'),
+ url('#{$ti-font-path}/<%= fileName %>.ttf') format('truetype');
+}
+
+.#{$ti-icon-prefix} {
+ font-family: $ti-font-family !important;
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+<% glyphs.forEach(function(glyph) { %>
+$ti-icon-<%= glyph.name %>: '\<%= glyph.unicode[0].codePointAt(0).toString(16) %>';<% }); %>
+
+<% glyphs.forEach(function(glyph) { %>
+.#{$ti-icon-prefix}-<%= glyph.name %>:before { content: $ti-icon-<%= glyph.name %>; }<% }); %>
diff --git a/.gitignore b/.gitignore
index bdc37d5f4d..4cf967de6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ package-lock.json
Gemfile.lock
packages/*
.DS_Store
+icons-outlined/
diff --git a/gulpfile.js b/gulpfile.js
index aca7c77001..e39b14e40b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -6,6 +6,11 @@ const gulp = require('gulp'),
p = require('./package.json'),
zip = require('gulp-zip'),
puppeteer = require('puppeteer'),
+ outlineStroke = require('svg-outline-stroke'),
+ iconfont = require('gulp-iconfont'),
+ template = require('lodash.template'),
+ sass = require('node-sass'),
+ cleanCSS = require('clean-css'),
argv = require('minimist')(process.argv.slice(2));
async function asyncForEach(array, callback) {
@@ -73,7 +78,7 @@ const createScreenshot = async (filePath) => {
const printChangelog = function (newIcons, modifiedIcons, renamedIcons, pretty = false) {
if (newIcons.length > 0) {
- if(pretty) {
+ if (pretty) {
console.log(`### ${newIcons.length} new icons:`);
newIcons.forEach(function (icon, i) {
@@ -122,7 +127,7 @@ const printChangelog = function (newIcons, modifiedIcons, renamedIcons, pretty =
}
};
-const generateIconsPreview = function(files, destFile, cb, columnsCount = 17, paddingOuter = 5) {
+const generateIconsPreview = function (files, destFile, cb, columnsCount = 17, paddingOuter = 5) {
const padding = 29,
iconSize = 24;
@@ -170,10 +175,130 @@ const generateIconsPreview = function(files, destFile, cb, columnsCount = 17, pa
//*********************************************************************************************
+gulp.task('iconfont-prepare', function (cb) {
+ cp.exec('mkdir -p icons-outlined/ && rm -fd ./icons-outlined/* && mkdir -p && rm -fd ./iconfont/*', function () {
+ cb();
+ });
+});
+
+gulp.task('iconfont-clean', function (cb) {
+ cp.exec('rm -rf ./icons-outlined', function () {
+ cb();
+ });
+});
+
+gulp.task('iconfont-svg-outline', function (cb) {
+
+ cp.exec('mkdir -p icons-outlined/ && rm -fd ./icons-outlined/*', async () => {
+ let files = glob.sync("./icons/*.svg");
+
+ let iconfontUnicode = {};
+
+ if(fs.existsSync('./iconfont-unicode.json')) {
+ iconfontUnicode = require('./iconfont-unicode');
+ }
+
+ await asyncForEach(files, async function (file) {
+ const name = path.basename(file, '.svg'),
+ unicode = iconfontUnicode[name];
+
+ await console.log('Stroke for:', file, unicode);
+
+ let strokedSVG = fs.readFileSync(file).toString();
+
+ strokedSVG = strokedSVG
+ .replace('width="24"', 'width="1000"')
+ .replace('height="24"', 'height="1000"');
+
+ await outlineStroke(strokedSVG, {
+ optCurve: false,
+ steps: 4,
+ round: 0,
+ centerHorizontally: true,
+ fixedWidth: true,
+ color: 'black'
+ }).then(outlined => {
+ if(unicode) {
+ fs.writeFileSync(`icons-outlined/u${unicode.toUpperCase()}-${name}.svg`, outlined);
+ } else {
+ fs.writeFileSync(`icons-outlined/${name}.svg`, outlined);
+ }
+ }).catch(error => console.log(error));
+ });
+
+ cb();
+ });
+});
+
+gulp.task('iconfont', function () {
+ let maxUnicode = 59905;
+
+ if(fs.existsSync('./iconfont-unicode.json')) {
+ const iconfontUnicode = require('./iconfont-unicode');
+
+ for(const name in iconfontUnicode) {
+ const unicode = parseInt(iconfontUnicode[name], 16);
+
+ maxUnicode = Math.max(maxUnicode, unicode);
+ }
+ }
+
+ return gulp.src(['icons-outlined/*.svg'])
+ .pipe(iconfont({
+ fontName: 'tabler-icons',
+ prependUnicode: true,
+ formats: ['ttf', 'eot', 'woff', 'woff2'],
+ normalize: true,
+ startUnicode: maxUnicode
+ }))
+ .on('glyphs', function (glyphs, options) {
+ //glyphs json
+ let glyphsObject = {};
+
+ glyphs.forEach(function (glyph) {
+ glyphsObject[glyph.name] = glyph.unicode[0].codePointAt(0).toString(16);
+ });
+
+ fs.writeFileSync(`iconfont-unicode.json`, JSON.stringify(glyphsObject));
+
+ //css
+ options['glyphs'] = glyphs;
+ options['v'] = p.version;
+
+ const compiled = template(fs.readFileSync('.build/iconfont.scss').toString());
+ const result = compiled(options);
+
+ fs.writeFileSync('iconfont/tabler-icons.scss', result);
+
+ //html
+ const compiledHtml = template(fs.readFileSync('.build/iconfont.html').toString());
+ const resultHtml = compiledHtml(options);
+
+ fs.writeFileSync('iconfont/tabler-icons.html', resultHtml);
+ })
+ .pipe(gulp.dest('iconfont/fonts'));
+});
+
+gulp.task('iconfont-css', function (cb) {
+ sass.render({
+ file: 'iconfont/tabler-icons.scss',
+ outputStyle: 'expanded'
+ }, function (err, result) {
+ fs.writeFileSync('iconfont/tabler-icons.css', result.css);
+
+ const cleanOutput = new cleanCSS({}).minify(result.css);
+ fs.writeFileSync('iconfont/tabler-icons.min.css', cleanOutput.styles);
+
+ cb();
+ });
+});
+
+gulp.task('build-iconfont', gulp.series('iconfont-prepare', 'iconfont-svg-outline', 'iconfont', 'iconfont-css', 'iconfont-clean'));
+
gulp.task('build-zip', function () {
const version = p.version;
- return gulp.src('{icons/**/*,icons-png/**/*,tabler-sprite.svg,tabler-sprite-nostroke.svg}')
+ return gulp.src('{icons/**/*,icons-png/**/*,iconfont/**/*,tabler-sprite.svg,tabler-sprite-nostroke.svg}')
.pipe(zip(`tabler-icons-${version}.zip`))
.pipe(gulp.dest('packages'))
});
@@ -319,7 +444,7 @@ gulp.task('changelog-commit', function (cb) {
gulp.task('changelog', function (cb) {
const version = argv['latest-tag'] || `v${p.version}`;
- if(version) {
+ if (version) {
cp.exec(`git diff ${version} HEAD --name-status`, function (err, ret) {
let newIcons = [], modifiedIcons = [], renamedIcons = [];
@@ -351,7 +476,7 @@ gulp.task('changelog-image', function (cb) {
const version = argv['latest-version'] || `${p.version}`,
newVersion = argv['new-version'] || `${p.version}`;
- if(version) {
+ if (version) {
cp.exec(`git diff v${version} HEAD --name-status`, function (err, ret) {
let newIcons = [];
@@ -360,11 +485,11 @@ gulp.task('changelog-image', function (cb) {
newIcons.push(fileName);
});
- newIcons = newIcons.map(function(icon){
+ newIcons = newIcons.map(function (icon) {
return `./icons/${icon}.svg`;
});
- if(newIcons.length > 0) {
+ if (newIcons.length > 0) {
generateIconsPreview(newIcons, `.github/tabler-icons-${newVersion}.svg`, cb, 6, 24);
} else {
cb();
@@ -390,4 +515,4 @@ gulp.task('svg-to-png', gulp.series('build-jekyll', 'clean-png', async (cb) => {
cb();
}));
-gulp.task('build', gulp.series('optimize', 'build-jekyll', 'build-copy', 'icons-sprite', 'icons-preview', 'svg-to-png', 'changelog-image', 'build-zip'));
+gulp.task('build', gulp.series('optimize', 'build-jekyll', 'build-copy', 'icons-sprite', 'icons-preview', 'svg-to-png', 'build-iconfont', 'changelog-image', 'build-zip'));
diff --git a/package.json b/package.json
index 89fec1ff2a..d09d581f96 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"files": [
"icons/*",
"icons-png/*",
+ "iconfont/*",
"tabler-sprite.svg",
"tabler-sprite-nostroke.svg"
],
@@ -29,12 +30,15 @@
},
"description": "",
"devDependencies": {
+ "clean-css": "4.2.3",
"glob": "7.1.6",
"gulp": "4.0.2",
+ "gulp-iconfont": "10.0.3",
"gulp-zip": "5.0.1",
"minimist": "1.2.5",
"puppeteer": "2.1.1",
- "release-it": "13.1.2"
+ "release-it": "13.1.2",
+ "svg-outline-stroke": "1.2.4"
},
"release-it": {
"hooks": {
@@ -50,5 +54,9 @@
"github": {
"release": true
}
+ },
+ "dependencies": {
+ "lodash.template": "^4.5.0",
+ "node-sass": "^4.13.1"
}
}