diff --git a/ghost/admin/app/components/modals/newsletters/components/color-picker.hbs b/ghost/admin/app/components/modals/newsletters/components/color-picker.hbs index 66fc3a05f9..c6f225744b 100644 --- a/ghost/admin/app/components/modals/newsletters/components/color-picker.hbs +++ b/ghost/admin/app/components/modals/newsletters/components/color-picker.hbs @@ -1,17 +1,16 @@
-
+

{{this.currentColorObject.name}}

-
diff --git a/ghost/admin/app/components/modals/newsletters/components/color-picker.js b/ghost/admin/app/components/modals/newsletters/components/color-picker.js index c61b6ca6a1..5f4e9d83c7 100644 --- a/ghost/admin/app/components/modals/newsletters/components/color-picker.js +++ b/ghost/admin/app/components/modals/newsletters/components/color-picker.js @@ -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()); } } diff --git a/ghost/admin/app/styles/layouts/members.css b/ghost/admin/app/styles/layouts/members.css index 43fbe8ee0b..51d5125b8d 100644 --- a/ghost/admin/app/styles/layouts/members.css +++ b/ghost/admin/app/styles/layouts/members.css @@ -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 {