From ee904bad9c8a24e1e621bca37256a67aacc9917f Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 28 Sep 2020 18:44:53 +0530 Subject: [PATCH] fix: Color picker event triggers and UX --- frappe/public/images/color-circle.png | Bin 0 -> 3783 bytes .../js/frappe/color_picker/color_picker.js | 28 +++-- .../public/js/frappe/form/controls/color.js | 109 ++++++++++-------- frappe/public/scss/color_picker.scss | 75 +++++------- 4 files changed, 102 insertions(+), 110 deletions(-) create mode 100644 frappe/public/images/color-circle.png diff --git a/frappe/public/images/color-circle.png b/frappe/public/images/color-circle.png new file mode 100644 index 0000000000000000000000000000000000000000..1dce698365dc7e90e2683ff23c4bb259fd220d6a GIT binary patch literal 3783 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 - RECENT
-
- COLOR PICKER
+
+ ${__('SWATCHES')}
+
+
+ ${__('COLOR PICKER')}
@@ -32,10 +39,9 @@ class Picker { this.hue_map = this.color_picker_wrapper.getElementsByClassName('hue-map')[0]; this.swatches_wrapper = this.color_picker_wrapper.getElementsByClassName('swatches')[0]; this.hue_selector_circle = this.hue_map.getElementsByClassName('hue-selector')[0]; - this.set_selector_position(); + this.refresh(); this.setup_events(); this.setup_swatches(); - this.update_color_map(); } setup_events() { @@ -58,15 +64,15 @@ class Picker { }); } - set_selector_position() { + set_selector_position(silent) { this.hue = utils.get_hue(this.color); this.color_selector_position = this.get_pointer_coords(); this.hue_selector_position = { x: this.hue * this.hue_map.offsetWidth / 360, y: this.hue_map.offsetHeight / 2 }; - this.update_color_selector(); - this.update_hue_selector(); + this.update_color_selector(silent); + this.update_hue_selector(silent); } setup_color_event() { @@ -91,14 +97,14 @@ class Picker { ); } - update_color_selector() { + update_color_selector(silent) { let x = this.color_selector_position.x; let y = this.color_selector_position.y; // set color selector position and background this.color_selector_circle.style.top = (y - this.color_selector_circle.offsetHeight / 2) + 'px'; this.color_selector_circle.style.left = (x - this.color_selector_circle.offsetWidth / 2) + 'px'; this.color_map.style.color = this.color; - this.on_change && this.on_change(this.color); + !silent && this.on_change && this.on_change(this.color); } setup_hue_event() { @@ -136,7 +142,7 @@ class Picker { let width = this.color_map.offsetWidth; let height = this.color_map.offsetHeight; let x = utils.clamp(0, s * width / 100, width); - let y = utils.clamp(0, (1 - v * height) / 100, height); + let y = utils.clamp(0, (1 - (v / 100)) * height, height); return {x, y}; } diff --git a/frappe/public/js/frappe/form/controls/color.js b/frappe/public/js/frappe/form/controls/color.js index 61f15c224f..f96137d0a0 100644 --- a/frappe/public/js/frappe/form/controls/color.js +++ b/frappe/public/js/frappe/form/controls/color.js @@ -3,34 +3,31 @@ import Picker from '../../color_picker/color_picker'; frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({ make_input: function () { this._super(); - this.colors = [ - "#ffc4c4", "#ff8989", "#ff4d4d", "#a83333", - "#ffe8cd", "#ffd19c", "#ffb868", "#a87945", - "#ffd2c2", "#ffa685", "#ff7846", "#a85b5b", - "#ffd7d7", "#ffb1b1", "#ff8989", "#a84f2e", - "#fffacd", "#fff168", "#fff69c", "#a89f45", - "#ebf8cc", "#d9f399", "#c5ec63", "#7b933d", - "#cef6d1", "#9deca2", "#6be273", "#428b46", - "#d2f8ed", "#a4f3dd", "#77ecca", "#49937e", - "#d2f1ff", "#a6e4ff", "#78d6ff", "#4f8ea8", - "#d2d2ff", "#a3a3ff", "#7575ff", "#4d4da8", - "#dac7ff", "#b592ff", "#8e58ff", "#5e3aa8", - "#f8d4f8", "#f3aaf0", "#ec7dea", "#934f92" - ]; this.make_color_input(); }, make_color_input: function () { let picker_wrapper = $('
'); this.picker = new Picker({ parent: picker_wrapper[0], - color: "#ffc4c4", + color: this.get_color() || '#F4F5F5', swatches: [ - "#ffc4c4", "#d9f399", "#78d6ff", "#fff69c", "#d2f8ed" + '#449CF0', + '#ECAD4B', + '#29CD42', + '#761ACB', + '#CB2929', + '#ED6396', + '#29CD42', + '#4463F0', + '#EC864B', + '#4F9DD9', + '#39E4A5', + '#B4CD29', ] }); this.$wrapper.popover({ - trigger: 'click', + trigger: 'manual', offset: `${-this.$wrapper.width() / 4}, 5`, placement: 'bottom', template: ` @@ -41,56 +38,66 @@ frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({ `, content: () => picker_wrapper, html: true + }).on('show.bs.popover', () => { + setTimeout(() => { + this.picker.refresh(); + }, 10); + }).on('hidden.bs.popover', () => { + $('body').off('click.color-popover'); + $(window).off('hashchange.color-popover'); + }); + + this.$input.on('click', (e) => { + this.$wrapper.popover('show'); + if (!this.get_color()) { + this.$input.val(''); + } + e.stopPropagation(); + $('body').on('click.color-popover', (ev) => { + if (!$(ev.target).parents().is('.popover')) { + this.$wrapper.popover('hide'); + } + }); + $(window).on('hashchange.color-popover', () => { + this.$wrapper.popover('hide'); + }); }); this.picker.on_change = (color) => { this.set_value(color); }; + + if (!this.selected_color) { + this.selected_color = $(`
`); + this.selected_color.insertAfter(this.$input); + } + }, + refresh() { + this._super(); + this.picker.refresh(); }, set_formatted_input: function(value) { this._super(value); - if (!value) value = '#F4F5F5'; - const contrast = frappe.ui.color.get_contrast_color(value); - - this.$input.css({ - "background-color": value, "color": contrast + this.$input.val(value || __('Choose a color')); + this.selected_color.css({ + "background-color": value || 'transparent', }); + this.selected_color.toggleClass('no-value', !value); + if (this.picker.color !== value) { + this.picker.color = value; + this.picker.refresh(); + } }, - bind_events: function () { - // var mousedown_happened = false; - // this.$wrapper.on("click", ".color-box", (e) => { - // mousedown_happened = false; - - // var color_val = $(e.target).data("color"); - // this.set_value(color_val); - // // set focus so that we can blur it later - // this.set_focus(); - // }); - - // this.$wrapper.find(".color-box").mousedown(() => { - // mousedown_happened = true; - // }); - - // this.$input.on("focus", () => { - // this.$color_pallete.show(); - // }); - // this.$input.on("blur", () => { - // if (mousedown_happened) { - // // cancel the blur event - // mousedown_happened = false; - // } else { - // // blur event is okay - // $(this.$color_pallete).hide(); - // } - // }); + get_color() { + return this.validate(this.get_value()); }, validate: function (value) { - if(value === '') { + if (value === '') { return ''; } var is_valid = /^#[0-9A-F]{6}$/i.test(value); - if(is_valid) { + if (is_valid) { return value; } return null; diff --git a/frappe/public/scss/color_picker.scss b/frappe/public/scss/color_picker.scss index 5b80a97702..f9fa1c13b2 100644 --- a/frappe/public/scss/color_picker.scss +++ b/frappe/public/scss/color_picker.scss @@ -1,9 +1,11 @@ .color-picker { font-size: var(--text-xs); color: var(--text-muted); + --color-picker-width: 210px; + width: var(--color-picker-width); .swatches { margin-top: 10px; - margin-bottom: 15px; + margin-bottom: 10px; display: flex; flex-wrap: wrap; } @@ -34,8 +36,8 @@ } &::before { - width: calc(100%); - height: calc(100%); + width: 100%; + height: 100%; background-color: currentColor; border: 2px solid white; } @@ -58,7 +60,7 @@ margin-top: 10px; color: transparent; position: relative; - width: 210px; + width: auto; height: 140px; /* background: linear-gradient(0deg, black, transparent), linear-gradient(90deg, white, transparent), red; */ border-radius: 6px; @@ -67,7 +69,7 @@ .hue-map { color: transparent; - width: 210px; + width: auto; height: 14px; position: relative; background: linear-gradient( @@ -86,48 +88,25 @@ } .picker-arrow { - left: 0 !important; + left: 15px !important; } -// .color-picker-wrapper { -// position: relative; -// z-index: 999; -// } - -// .color-picker { -// border-radius: 4px; -// box-shadow: 0 4px 12px rgba(0,0,0,.15); -// background: #fff; -// border: 1px solid var(--border-color); -// width: 290px; -// height: 106px; -// padding-top: 10px; -// padding-left: 5px; -// position: absolute; -// top: 0; -// left: 0; - -// &:after, -// &:before { -// border: solid transparent; -// content: " "; -// height: 0; -// width: 0; -// pointer-events: none; -// position: absolute; -// bottom: 100%; -// left: 30px; -// } -// &:after { -// border-color: rgba(255, 255, 255, 0); -// border-bottom-color: #fff; -// border-width: 8px; -// margin-left: -8px; -// } -// &:before { -// border-color: rgba(221, 221, 221, 0); -// border-bottom-color: var(--border-color); -// border-width: 9px; -// margin-left: -9px; -// } -// } \ No newline at end of file +.frappe-control[data-fieldtype='Color'] { + input { + padding-left: 40px; + } + .selected-color { + width: 22px; + height: 22px; + border-radius: 5px; + background-color: red; + position: absolute; + top: calc(50% + 1px); + left: 5px; + content: ' '; + &.no-value { + background: url('/assets/frappe/images/color-circle.png'); + background-size: contain; + } + } +} \ No newline at end of file