fix: Color picker event triggers and UX

This commit is contained in:
Suraj Shetty 2020-09-28 18:44:53 +05:30
parent e1a2e42e54
commit ee904bad9c
4 changed files with 102 additions and 110 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -10,13 +10,20 @@ class Picker {
this.setup_picker();
}
refresh() {
this.set_selector_position(true);
this.update_color_map();
}
setup_picker() {
let color_picker_template = document.createElement('template');
color_picker_template.innerHTML = `
<div class="color-picker">
RECENT <br>
<div class="swatches"></div>
COLOR PICKER <br>
<div class="swatch-section">
${__('SWATCHES')}<br>
<div class="swatches"></div>
</div>
${__('COLOR PICKER')}<br>
<div class="color-map">
<div class="color-selector"></div>
</div>
@ -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};
}

View file

@ -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 = $('<div>');
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 = $(`<div class="selected-color"></div>`);
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;

View file

@ -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;
// }
// }
.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;
}
}
}