mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
🎨 first pass at animated icons for save-state buttons (#637)
refs https://github.com/TryGhost/Ghost/issues/7515 - adds animated spinner and check SVG icons - improves SVG sizing/alignment in buttons - disables old technique of fixing button size because it doesn't work now that buttons have more than a single spinner when running/saved/failed - fixes broken spinner in `gh-spin-button` components
This commit is contained in:
parent
10653fbca6
commit
2f767bef1e
8 changed files with 62 additions and 13 deletions
|
@ -94,11 +94,11 @@ const GhTaskButton = Component.extend({
|
||||||
setSize: observer('isRunning', function () {
|
setSize: observer('isRunning', function () {
|
||||||
if (this.get('isRunning')) {
|
if (this.get('isRunning')) {
|
||||||
this.set('hasRun', true);
|
this.set('hasRun', true);
|
||||||
this.$().width(this.$().width());
|
// this.$().width(this.$().width());
|
||||||
this.$().height(this.$().height());
|
// this.$().height(this.$().height());
|
||||||
} else {
|
} else {
|
||||||
this.$().width('');
|
// this.$().width('');
|
||||||
this.$().height('');
|
// this.$().height('');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -292,23 +292,51 @@ fieldset[disabled] .gh-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-btn-icon svg {
|
.gh-btn-icon svg,
|
||||||
margin-right: 10px;
|
.gh-btn-block svg {
|
||||||
height: 13px;
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
margin-right: 0.5em;
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-btn-icon-right svg {
|
.gh-btn-icon-right svg {
|
||||||
margin-left: 10px;
|
margin-left: 0.5em;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gh-btn-block svg {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.gh-btn-icon svg path {
|
.gh-btn-icon svg path {
|
||||||
stroke: #fff;
|
stroke: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/* Animated button icons
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
path.animated-check-circle {
|
||||||
|
stroke: white;
|
||||||
|
stroke-dashoffset: 300;
|
||||||
|
stroke-dasharray: 300;
|
||||||
|
animation: dash 4s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dash {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 300;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/* Loading Button Spinner
|
/* Loading Button Spinner
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
path.animated-check-circle {
|
||||||
|
stroke: white;
|
||||||
|
stroke-dashoffset: 300;
|
||||||
|
stroke-dasharray: 300;
|
||||||
|
animation: dash 4s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dash {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 300;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Icons
|
/* Icons
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
/* CUSTOM GENERATED FILE */
|
/* CUSTOM GENERATED FILE */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{#if showSpinner}}
|
{{#if showSpinner}}
|
||||||
<span class="spinner"></span>
|
<span>{{inline-svg "spinner"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if buttonText}}
|
{{#if buttonText}}
|
||||||
{{buttonText}}
|
{{buttonText}}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
)}}
|
)}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<span>
|
<span>
|
||||||
{{#if isRunning}}<span class="spinner"></span>{{/if}}
|
{{#if isRunning}}{{inline-svg "spinner"}}{{/if}}
|
||||||
{{if (or isIdle isRunning) buttonText}}
|
{{if (or isIdle isRunning) buttonText}}
|
||||||
{{#if isSuccess}}{{inline-svg "check-circle"}} {{successText}}{{/if}}
|
{{#if isSuccess}}{{inline-svg "check-circle"}} {{successText}}{{/if}}
|
||||||
{{#if isFailure}}{{inline-svg "close"}} {{failureText}}{{/if}}
|
{{#if isFailure}}{{inline-svg "close"}} {{failureText}}{{/if}}
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g><path d="M16.659 8.134l-7.146 6.67-2.159-2.158c-.195-.195-.512-.195-.707 0s-.195.512 0 .707l2.5 2.5c.097.098.225.147.353.147.123 0 .245-.045.341-.134l7.5-7c.202-.188.212-.505.024-.707-.188-.202-.503-.213-.706-.025zM12 0c-6.617 0-12 5.383-12 12s5.383 12 12 12 12-5.383 12-12-5.383-12-12-12zm0 23c-6.065 0-11-4.935-11-11s4.935-11 11-11 11 4.935 11 11-4.935 11-11 11z"/></g></svg>
|
<svg width="26px" height="26px" viewBox="-1 -1 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="check-circle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path class="animated-check-circle" d="M19.6004116,2.71490714 C17.5353801,1.0196018 14.8927356,0 12,0 C5.38938053,0 0,5.38938053 0,12 C0,18.6106195 5.38938053,24 12,24 C18.6106195,24 24,18.6106195 24,12 C24,9.71681416 23.3628319,7.59292035 22.2743363,5.78761062 L11.0442478,17.0442478 L5.49557522,11.4955752" id="Shape" stroke="#000000" stroke-width="2"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 622 B |
1
ghost/admin/public/assets/icons/spinner.svg
Normal file
1
ghost/admin/public/assets/icons/spinner.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width='24px' height='24px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-default"><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(0 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(30 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.08333333333333333s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(60 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.16666666666666666s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(90 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.25s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(120 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.3333333333333333s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(150 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.4166666666666667s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(180 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.5s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(210 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.5833333333333334s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(240 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.6666666666666666s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(270 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.75s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(300 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.8333333333333334s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#fefefe' transform='rotate(330 50 50) translate(0 -40)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.9166666666666666s' repeatCount='indefinite'/></rect></svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -49,7 +49,7 @@ describe('Integration: Component: gh-task-button', function() {
|
||||||
this.get('myTask').perform();
|
this.get('myTask').perform();
|
||||||
|
|
||||||
run.later(this, function () {
|
run.later(this, function () {
|
||||||
expect(this.$('button')).to.have.descendants('span.spinner');
|
expect(this.$('button')).to.have.descendants('svg');
|
||||||
}, 20);
|
}, 20);
|
||||||
|
|
||||||
wait().then(done);
|
wait().then(done);
|
||||||
|
@ -189,7 +189,7 @@ describe('Integration: Component: gh-task-button', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('keeps button size when showing spinner', function (done) {
|
it.skip('keeps button size when showing spinner', function (done) {
|
||||||
this.set('myTask', task(function* () {
|
this.set('myTask', task(function* () {
|
||||||
yield timeout(50);
|
yield timeout(50);
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Add table
Reference in a new issue