Skip to content

Commit

Permalink
feat: add spot illustration support into dialtone (#502)
Browse files Browse the repository at this point in the history
* feat: add spot illustration support into dialtone

* change to theme based on primary color hex rather than css class. updated docs

* move theming to bottom of adding icons page

* fix width issue on spot illustration footer

* set auto height on spot illustration footer
  • Loading branch information
braddialpad authored Nov 18, 2021
1 parent ae4d871 commit 6893861
Show file tree
Hide file tree
Showing 12 changed files with 32,385 additions and 122 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ docs/assets/css
docs/assets/fonts
docs/_includes/icons
docs/_includes/patterns
docs/_includes/spot

# Logs and databases #
######################
Expand Down
18 changes: 18 additions & 0 deletions docs/.eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ module.exports = function(eleventyConfig) {

return svg;
});
eleventyConfig.addLiquidShortcode("spot", function(name, classes, dimension) {
var fs = require("fs");
var path = "_includes/spot/" + name + ".svg";
var svg = fs.readFileSync(path).toString("utf-8");
var defaultClasses = "d-svg__" + name;

// If we have classes, add them
if (classes != null) {
svg = svg.replace(defaultClasses, defaultClasses + " " + classes);
}

// If we need to change the size, do that too
if (dimension != null) {
svg = svg.replace('viewBox="0 0 24 24"', 'viewBox="0 0' + dimension + dimension + '"');
}

return svg;
});

// Generate header areas with anchor links
eleventyConfig.addLiquidShortcode("header", function(tag, text, increment) {
Expand Down
4 changes: 4 additions & 0 deletions docs/_data/site-nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
{
"title": "Patterns",
"url": "/design/illustrations/patterns/"
},
{
"title": "Spot Illustrations",
"url": "/design/illustrations/spot/"
}
]
},
Expand Down
14 changes: 14 additions & 0 deletions docs/_data/svg-spot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"name": "Browser List Callout",
"file": "browser-list-callout",
"vue": "SpotBrowserListCallout",
"desc": "Browser List Callout"
},
{
"name": "Browser Table Graph",
"file": "browser-table-graph",
"vue": "SpotBrowserTableGraph",
"desc": "Browser Table Graph"
}
]
22 changes: 22 additions & 0 deletions docs/assets/less/dialtone-docs.less
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@
grid-template-columns: repeat(var(--icon-grid-columns), [col] var(--icon-card-width));
}

.d-gl-docsite-icons--large {
.d-gl-docsite-icons();
--icon-card-width: 18rem;
--icon-grid-columns: auto-fit;
grid-auto-rows: 18rem;

}

.dialtone-icon-grid__item {
position: relative;
}
Expand Down Expand Up @@ -223,6 +231,12 @@
}
}

.dialtone-icon-card__footer-spot-illustration {
.dialtone-icon-card__footer();
width: calc(var(--icon-card-width)*1.5);
min-height: auto
}

.dialtone-icon-card__list {
display: flex;
flex-direction: column;
Expand All @@ -247,6 +261,14 @@
}
}

.dialtone-icon-card__icon--autosize {
margin-bottom: var(--su4);
svg {
height: auto;
width: 100%;
}
}

.dialtone-icon-card__title {
font-size: var(--fs16);
font-weight: var(--fw-bold);
Expand Down
14 changes: 10 additions & 4 deletions docs/design/icons/adding.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
<li>For system icons: {% code %}./lib/build/svg/system/{% endcode %}</li>
<li>For brand icons: {% code %}./lib/build/svg/brand/{% endcode %}</li>
<li>For patterns: {% code %}./lib/build/svg/patterns/{% endcode %}</li>
<li>For spot illustrations: {% code %}./lib/build/svg/spot/{% endcode %}</li>
</ul>
</li>
<li><strong>Add icon or pattern information to the correct data file.</strong> System, Brand, and Pattern SVGs all have their own icon data file.
<ul class="d-stack8">
<li>System icons: {% code%}./docs/_data/svg-system.json{% endcode %}</li>
<li>For brand icons: {% code%}./docs/_data/svg-brand.json{% endcode %}</li>
<li>For patterns: {% code%}./docs/_data/svg-patterns.json{% endcode %}</li>
<li>For patterns: {% code %}./docs/_data/svg-patterns.json{% endcode %}</li>
<li>For spot illustrations: {% code %}./docs/_data/svg-spot.json{% endcode %}</li>
</ul>
The data is pulled from the data files in the ordered it's entered, so you must place it in alphabetical order in the data file. Here is an example of information you must provide is:<br/><br/>
{% codeWell %}
Expand All @@ -50,10 +52,14 @@
<li><strong>Desc:</strong> This is a description about the icon and where it is used.</li>
</ul>
</li>
<li>Once finished, run the following command: {% code %}gulp svg{% endcode %}. This will recompile the entire {% code %}./lib/build/svg/{% endcode %} folder. To create new SVGs and build the documentation site, run {% code %}gulp svg watch{% endcode %}.</li>
<li>Verify your changes have been updated on the website.</li>
<li>Verify your changes have been updated on the website by running {% code %}npm run start{% endcode %} and navigating to {% code %}localhost:4000{% endcode %}. If you would like to verify your final output svg file run {% code %}npm run build{% endcode %} and look in the {% code %}./lib/dist/svg{% endcode %} folder</li>
<li>Commit and push your branch to Dialtone.</li>
<li>Open a pull request.</li>
<li>Once approved it will be merged.</li>
<li>Once approved it can be merged into staging and will go out in the next dialtone release.</li>
{% endol %}
</section>
<section class="d-stack16">
{% paragraph %}<strong>A note on theming</strong>{% endparagraph %}
{% paragraph %}Spot Illustrations allow for theming, meaning the primary color of the illustration will change when the theme changes. If your spot illustration svg contains a fill or a stroke with the dialtone primary color {% code %}#6C3DFF{% endcode %} then it will automatically change when the theme's primary color changes.{% endparagraph %}
{% paragraph %}You may often wish to derive lighter or darker colors based on the primary color when making a spot illustration. In these instances it is recommended to set opacity while still using the primary color as the base color so these colors will also change with the theme.{% endparagraph %}
</section>
50 changes: 50 additions & 0 deletions docs/design/illustrations/spot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
layout: page-no-toc
title: Spot Illustrations
description: Spot illustrations are the slightly grown up version of icons with a little more detail. A spot illustration is an image that typically works in tandem with inline text to communicate a state in a more friendly way. They’re most often used in empty states, onboarding, and in-product announcements.

---
<section class="d-stack16 d-px16">
{% header "h2", "Theming" %}
{% paragraph %}It is possible for the primary color of your spot illustration to change with the theme. See <a href="/design/icons/adding" class="d-link link--link">Adding Icons</a> for details on how to do this.{% endparagraph %}
</section>
<div class="d-stack64">
<div class="d-stack16 d-p16">
{% header "h2", "Illustrations" %}
<div class="d-gl-docsite-icons--large">
{% for p in svg-spot %}
{% assign name = p.name %}
{% assign file = p.file %}
{% assign vue = p.vue %}
{% assign desc = p.desc %}
<div id="{{ name }}" class="dialtone-icon-grid__item">
<aside class="dialtone-icon-card js-dialtone-icon-card" data-selected="no">
<header class="dialtone-icon-card__header js-dialtone-icon-card-copy-area">
<div class="dialtone-icon-card__icon--autosize">
{% assign path = file %}
{% spot path, "js-svg" %}
</div>
<p class="dialtone-icon-card__subtitle">{{ name }}</p>
</header>
<footer class="dialtone-icon-card__footer-spot-illustration js-dialtone-icon-card-footer">
<div class="dialtone-icon-card__content">
<h2 class="dialtone-icon-card__title">{{ name }}</h2>
<div class="dialtone-icon-card__list">
<span class="dialtone-icon-card__list__item">
<strong>SVG:</strong> <span class="code-example">{{ file }}</span>
</span>
<span class="dialtone-icon-card__list__item">
<strong>Vue:</strong> <span class="code-example js-vue-file">{{ vue }}</span>
</span>
</div>
<p class="dialtone-icon-card__description">{{ desc }}</p>
</div>
</footer>
</aside>
</div>
{% endfor %}
</div>
</div>
</div>

<script src="/{{ site.paths.js }}/icons.js"></script>
100 changes: 84 additions & 16 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var settings = {
styles: true, // Turn on/off style tasks
svgs: true, // Turn on/off SVG tasks
patterns: true, // Turn on/off SVG Pattern tasks
spot: true, // Turn on/off SVG spot illustration tasks
fonts: true, // Turn on/off webfonts
favicons: false, // Turn on/off Favicons tasks
sync: true, // Turn on/off sync tasks
Expand Down Expand Up @@ -71,6 +72,7 @@ var lessFileOrder = () => order([
'utilities/internals.less'
])

const PRIMARY_COLOR = '#6c3dff'

// ================================================================================
// @ PATHS
Expand Down Expand Up @@ -115,6 +117,12 @@ var paths = {
outputDocs: './docs/_includes/patterns/',
outputVue: './lib/dist/vue/patterns/',
},
spot: {
input: './lib/build/svg/spot/**/*.svg',
outputLib: './lib/dist/svg/spot/',
outputDocs: './docs/_includes/spot/',
outputVue: './lib/dist/vue/spot/',
},
favicons: {
dpName: 'Dialpad',
dpBgColor: '#FFFFFF',
Expand Down Expand Up @@ -155,7 +163,8 @@ var paths = {
docsExcludeCSS: '!./docs/assets/css/**/*',
docsExcludeFonts: '!./docs/assets/fonts/**/*',
docsExcludeSVG: '!./docs/_includes/icons/**/*',
docsExcludePatterns: '!./docs/_includes/patterns/**/*'
docsExcludePatterns: '!./docs/_includes/patterns/**/*',
docsExcludeSpot: '!./docs/_includes/spot/**/*'
}
}

Expand Down Expand Up @@ -312,6 +321,20 @@ var docStylesDev = function(done) {
done();
};

const moveStyleTagsToEOF = function(file, enc, cb) {
if (file.isBuffer()) {
const styleTagsRegex = /<style[\s\S]*<\/style>/gmi;
let code = file.contents.toString();
const result = styleTagsRegex.exec(code);
if (!result) return cb(null, file);
const matchedText = result[0];
code = code.replace(styleTagsRegex, '');
code = code + matchedText;
file.contents = Buffer.from(code)
}
return cb(null, file);
}

// ================================================================================
// @@ COMPILE SVGS
// Lint and optimize SVG files
Expand Down Expand Up @@ -378,20 +401,6 @@ var buildSystemSVGs = function(done) {
done();
};

const moveStyleTagsToEOF = function(file, enc, cb) {
if (file.isBuffer()) {
const styleTagsRegex = /<style[\s\S]*<\/style>/gmi;
let code = file.contents.toString();
const result = styleTagsRegex.exec(code);
if (!result) return cb(null, file);
const matchedText = result[0];
code = code.replace(styleTagsRegex, '');
code = code + matchedText;
file.contents = Buffer.from(code)
}
return cb(null, file);
}

var buildBrandSVGs = function(done) {

// Make sure this feature is activated before running
Expand Down Expand Up @@ -499,6 +508,63 @@ var buildPatternSVGs = function(done) {
done();
};

var buildSpotIllustrationSVGs = function(done) {

// Make sure this feature is activated before running
if (!settings.spot) return done();
const strokeRegex = new RegExp(`stroke="${PRIMARY_COLOR}"`, 'gi')
const fillRegex = new RegExp(`fill="${PRIMARY_COLOR}"`, 'gi')
// Compile system icons
return src(paths.spot.input)
// replace any instances of the primary color in SVG with the theme class
.pipe(replace(strokeRegex, 'class=\"d-svg-primary--stroke\"'))
.pipe(replace(fillRegex, 'class=\"d-svg-primary--fill\"'))
.pipe(replace('<svg', function(match) {
var name = path.parse(this.file.path).name;
var converted = name.toLowerCase().replace(/-(.)/g, function(match,group1) {
return group1.toUpperCase();
});
var title = name.replace(/\b\S/g, t => t.toUpperCase()).replace(/[-]+/g, " ");

return match + ' aria-hidden="true" focusable="false" aria-label="' + title + '" class="d-svg ' + converted + '" xmlns="http://www.w3.org/2000/svg"';
}))
.pipe(svgmin({
plugins: [{
convertPathData: {
transformPrecision: 4,
}
}, {
cleanupNumericValues: {
floatPrecision: 2,
}
}, {
collapseGroups: true,
}, {
removeTitle: true,
}, {
removeViewBox: false,
}, {
removeUselessStrokeAndFill: true,
}]
}))
.pipe(dest(paths.spot.outputLib))
.pipe(dest(paths.spot.outputDocs))
.pipe(replace('<svg', '<template>\n <svg'))
.pipe(replace('</svg>', '</svg>\n</template>'))
// move any style tags within the svg into style tags of the vue component
.pipe(through2.obj(moveStyleTagsToEOF))
.pipe(replace('<style>', '<style scoped>'))
.pipe(rename(function(file) {
var converted = file.basename.replace(/\b\S/g, t => t.toUpperCase()).replace(/[-]+/g, '');

file.basename = 'Spot' + converted;
file.extname = '.vue';
}))
.pipe(dest(paths.spot.outputVue));

done();
};

// ================================================================================
// @@ FAVICONS
// ================================================================================
Expand Down Expand Up @@ -698,6 +764,7 @@ var watchFiles = function(done) {
paths.watch.docsExcludeFonts,
paths.watch.docsExcludeSVG,
paths.watch.docsExcludePatterns,
paths.watch.docsExcludeSpot,
], series(exports.buildWatch, reloadBrowser));
watcher.on('change', function (event) {
if (event.type === 'deleted') { // if a file is deleted, forget about it
Expand All @@ -721,7 +788,8 @@ exports.clean = series(
exports.svg = series(
buildSystemSVGs,
buildBrandSVGs,
buildPatternSVGs
buildPatternSVGs,
buildSpotIllustrationSVGs,
);

const buildDocsProd = (done) => buildDocs(done, 'prod')
Expand Down
8 changes: 8 additions & 0 deletions lib/build/less/dialtone-globals.less
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,11 @@ body {
fill: currentColor;
}
}

.d-svg-primary--stroke {
stroke: var(--primary-color);
}

.d-svg-primary--fill {
fill: var(--primary-color);
}
Loading

0 comments on commit 6893861

Please sign in to comment.