mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 05:50:35 +03:00
Improved color picker
refs https://github.com/TryGhost/Team/issues/2830 Only update the order of the colors on mouseleave (+ after the animation). This also includes some minor changes to the CSS files to remove glitches in the animation. I temporarily removed the border of the colors because they keep taking up space when the colors are hidden. Ideally we want to move those borders to :before or :after, that will also be better for the animation.
This commit is contained in:
parent
fbd46e7688
commit
73d823ad6a
@ -1,17 +1,16 @@
|
||||
<div class="gh-email-design-color-picker">
|
||||
<div class="gh-btn-group">
|
||||
<div class="gh-btn-group" {{on "mouseenter" this.onMouseEnter}} {{on "mouseleave" this.onMouseLeave}}>
|
||||
<p>{{this.currentColorObject.name}}</p>
|
||||
<label type="button" class="gh-btn gh-email-design-color custom" {{on "click" this.onOpenColorPicker}}>
|
||||
<label type="button" style={{html-safe this.customColorStyle}} class="gh-btn gh-email-design-color custom {{if this.customColorSelected "gh-btn-group-selected"}}" {{on "click" this.onOpenColorPicker}}>
|
||||
<input
|
||||
type="color"
|
||||
value={{this.colorInputValue}}
|
||||
{{on "input" this.updateColorInputValue}}
|
||||
{{on "change" this.updateColorInputValue}}
|
||||
>
|
||||
/>
|
||||
</label>
|
||||
{{#each this.availablePresetColors as |color|}}
|
||||
<button type="button" class="gh-btn gh-email-design-color {{color.class}}" {{on "click" (fn this.setCurrentColor color.value) }}></button>
|
||||
{{#each this.dynamicOrderedPresetColors as |color|}}
|
||||
<button type="button" style={{html-safe color.style}} class="gh-btn gh-email-design-color {{color.class}} {{if (eq this.currentColorObject.value color.value) "gh-btn-group-selected"}}" {{on "click" (fn this.setCurrentColor color.value) }}></button>
|
||||
{{/each}}
|
||||
<button type="button" class="gh-btn gh-email-design-color {{this.currentColorObject.class}} gh-btn-group-selected" style={{html-safe this.currentColorObject.style}}></button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,17 @@
|
||||
import Component from '@glimmer/component';
|
||||
import {action} from '@ember/object';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default class ColorPicker extends Component {
|
||||
@tracked
|
||||
orderedPresetColors = [];
|
||||
@tracked
|
||||
mouseOver = false;
|
||||
@tracked
|
||||
lastSelectedCustomColor = null;
|
||||
|
||||
timer;
|
||||
|
||||
get presetColors() {
|
||||
return this.args.presetColors ?? [];
|
||||
}
|
||||
@ -19,8 +29,81 @@ export default class ColorPicker extends Component {
|
||||
this.currentColor = value;
|
||||
}
|
||||
|
||||
get availablePresetColors() {
|
||||
return this.presetColors.filter(preset => preset.value !== this.currentColor);
|
||||
@action
|
||||
onMouseEnter() {
|
||||
this.mouseOver = true;
|
||||
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
onMouseLeave() {
|
||||
this.mouseOver = false;
|
||||
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
|
||||
// Wait 200ms after the animation to update
|
||||
// we need to do this on mouse leave, because on mouse enter it breaks the animations
|
||||
this.timer = setTimeout(() => {
|
||||
if (!this.mouseOver) {
|
||||
this.updateOrderedPresetColors();
|
||||
}
|
||||
this.timer = null;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@action
|
||||
updateOrderedPresetColors() {
|
||||
const customColorSelected = !this.presetColors.find(c => c.value === this.currentColor);
|
||||
const orderedPresetColors = this.presetColors.filter(c => c.value !== this.currentColor);
|
||||
if (!customColorSelected) {
|
||||
// Never append custom colors here
|
||||
orderedPresetColors.push(this.currentColorObject);
|
||||
} else {
|
||||
// Append custom
|
||||
//orderedPresetColors.push({
|
||||
}
|
||||
this.orderedPresetColors = orderedPresetColors;
|
||||
}
|
||||
|
||||
get dynamicOrderedPresetColors() {
|
||||
// Createa deep clone so we don't update anything
|
||||
const arr = [...this.orderedPresetColors.map((c) => {
|
||||
return {...c};
|
||||
})];
|
||||
|
||||
// Make sure all preset colors are presents
|
||||
for (const preset of this.presetColors) {
|
||||
if (!arr.find(c => c.value === preset.value)) {
|
||||
arr.push({...preset});
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
get customColorSelected() {
|
||||
if (!this.dynamicOrderedPresetColors.find(c => c.value === this.currentColor)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
get customColorStyle() {
|
||||
// Make sure the current color is present
|
||||
if (!this.dynamicOrderedPresetColors.find(c => c.value === this.currentColor)) {
|
||||
return 'background: ' + this.currentColor + ' !important;';
|
||||
} else {
|
||||
if (this.lastSelectedCustomColor) {
|
||||
return 'background: ' + this.lastSelectedCustomColor + ' !important;';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
get currentColorObject() {
|
||||
@ -33,11 +116,14 @@ export default class ColorPicker extends Component {
|
||||
value: this.currentColor,
|
||||
name: this.currentColor,
|
||||
class: 'custom-value',
|
||||
style: 'background-color: ' + this.currentColor + ' !important;'
|
||||
style: 'background: ' + this.currentColor + ' !important;'
|
||||
};
|
||||
}
|
||||
|
||||
get colorInputValue() {
|
||||
if (this.lastSelectedCustomColor) {
|
||||
return this.lastSelectedCustomColor;
|
||||
}
|
||||
if (!this.currentColorObject.value || !this.currentColorObject.value.startsWith('#')) {
|
||||
return '#000000';
|
||||
}
|
||||
@ -65,6 +151,7 @@ export default class ColorPicker extends Component {
|
||||
}
|
||||
|
||||
if (newColor.match(/#[0-9A-Fa-f]{6}$/)) {
|
||||
this.lastSelectedCustomColor = newColor.toUpperCase();
|
||||
this.setCurrentColor(newColor.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
@ -1738,6 +1738,11 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
.gh-email-design-color-picker .gh-btn-group {
|
||||
vertical-align: middle;
|
||||
|
||||
/* Required to remove glitches in mouseover during animations */
|
||||
overflow: hidden;
|
||||
padding: 4px;
|
||||
margin-right: -4px;
|
||||
}
|
||||
|
||||
.gh-email-design-color-picker .gh-btn-group p {
|
||||
@ -1775,7 +1780,7 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin: 0 0 0 5px;
|
||||
border: 1px solid transparent;
|
||||
/*border: 1px solid transparent;*/
|
||||
transition: all .15s ease-in-out;
|
||||
transition-delay: .05s;
|
||||
}
|
||||
@ -1785,7 +1790,7 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin: 0 0 0 5px;
|
||||
border: 1px solid transparent;
|
||||
/*border: 1px solid transparent;*/
|
||||
}
|
||||
|
||||
.gh-email-design-color.gh-btn-group-selected::before {
|
||||
@ -1810,7 +1815,7 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
.gh-btn-group .gh-email-design-color.transparent {
|
||||
background: transparent;
|
||||
border: 1px solid var(--lightgrey);
|
||||
/*border: 1px solid var(--lightgrey);*/
|
||||
}
|
||||
|
||||
.gh-email-design-color.transparent::after {
|
||||
@ -1828,7 +1833,7 @@ p.gh-members-import-errordetail:first-of-type {
|
||||
|
||||
.gh-btn-group .gh-email-design-color.white {
|
||||
background: var(--white) !important;
|
||||
border: 1px solid var(--lightgrey-l1);
|
||||
/*border: 1px solid var(--lightgrey-l1);*/
|
||||
}
|
||||
|
||||
.gh-btn-group .gh-email-design-color.black {
|
||||
|
Loading…
Reference in New Issue
Block a user