fix: Color picker event triggers and UX
This commit is contained in:
parent
e1a2e42e54
commit
ee904bad9c
4 changed files with 102 additions and 110 deletions
BIN
frappe/public/images/color-circle.png
Normal file
BIN
frappe/public/images/color-circle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue