diff --git a/frappe/public/images/color-circle.png b/frappe/public/images/color-circle.png
new file mode 100644
index 0000000000..1dce698365
Binary files /dev/null and b/frappe/public/images/color-circle.png differ
diff --git a/frappe/public/js/frappe/color_picker/color_picker.js b/frappe/public/js/frappe/color_picker/color_picker.js
index 6844d6cd37..e1e63758aa 100644
--- a/frappe/public/js/frappe/color_picker/color_picker.js
+++ b/frappe/public/js/frappe/color_picker/color_picker.js
@@ -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 = `
- RECENT
-
- COLOR PICKER
+
+ ${__('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