Skip to content

Commit

Permalink
placement options WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
lenadax committed Sep 23, 2024
1 parent 52c122e commit 6ef1eb1
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 3 deletions.
92 changes: 91 additions & 1 deletion js/src/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export class ColorPicker {

this.dropdown_elem = $('<div />')
.addClass('color-picker-wrapper')
.css('top', this.elem.outerHeight())
.insertAfter(this.elem);
this.picker_container = $('<div />')
.addClass('color-picker-container')
Expand All @@ -48,6 +47,7 @@ export class ColorPicker {
.text('✕')
.appendTo(this.dropdown_elem);

this.placement = options.placement;
this.slider_size = options.slider_size;
let iro_opts = this.init_opts(options);
this.picker = new iro.ColorPicker(this.picker_container.get(0), iro_opts);
Expand Down Expand Up @@ -117,6 +117,8 @@ export class ColorPicker {
this.close_btn.on('click', this.close);
this.on_keydown = this.on_keydown.bind(this);
this.on_click = this.on_click.bind(this);

this.place(options.placement, options.preview_elem);
}

get active_swatch() {
Expand Down Expand Up @@ -177,6 +179,90 @@ export class ColorPicker {
return iro_opts;
}

place(placement, custom_preview) {
let left, top;

const auto_place = (on_top, on_bottom, prefers) => {
const window_height = $(window).height();
const dd_height = this.dropdown_elem.outerHeight();
const offset = this.elem[0].getBoundingClientRect();
const y_pos = offset.top + this.elem.outerHeight();
const below = window_height - y_pos;

if (!prefers || prefers === 'bottom') {
if (below >= dd_height) {
return on_bottom;
} else if (y_pos >= dd_height) {
on_top -= dd_height;
} else {
return on_bottom;
}
} else if (prefers === 'top') {
if (y_pos >= dd_height) {
on_top -= dd_height;
} else if (below >= dd_height) {
return on_bottom;
} else {
return on_bottom;
}
}

return on_top;
}

switch (placement) {

case 'left':
left = - this.dropdown_elem.outerWidth();
top = auto_place(0, -this.elem.outerHeight());
break;

case 'right':
left = this.elem.outerWidth();
if (!custom_preview && this.preview) {
// default preview elem
left += this.preview.elem.outerWidth(true);
}
top = auto_place(0, -this.elem.outerHeight());
break;

case 'top':
left = 0;
top = -(this.dropdown_elem.outerHeight() + this.elem.outerHeight());
break;

case 'bottom':
left = 0;
top = 0;
break;

case 'static':
left = 0;
top = 0;
this.dropdown_elem.css('position', 'static');
break;

case 'auto-top':
left = 0;
top = auto_place(-this.elem.outerHeight(), 0, 'top');
break;

case 'auto':
left = 0;
top = auto_place(-this.elem.outerHeight(), 0);
break;

default:
console.warn(`Unknown placement: ${placement}`);
break;
}

this.dropdown_elem.css(
'transform',
`translate(${left}px, ${top}px)`
);
}

update_color() {
this.color = this.picker.color.clone();
this.preview.color = this.color.rgbaString;
Expand All @@ -185,6 +271,9 @@ export class ColorPicker {
}

open(evt) {
if (['auto-top', 'auto', 'left', 'right'].includes(this.placement)) {
this.place(this.placement);
}
if (this.dropdown_elem.css('display') === 'none') {
this.dropdown_elem.show();
$(window).on('keydown', this.on_keydown);
Expand Down Expand Up @@ -291,6 +380,7 @@ export class ColorWidget {
}
let options = {
format: elem.data('format'),
placement: elem.data('placement'),
preview_elem: elem.data('preview_elem'),
sliders: elem.data('sliders'),
box_width: elem.data('box_width'),
Expand Down
47 changes: 47 additions & 0 deletions src/yafowil/widget/color/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,52 @@ def wheel_example():
}


DOC_PLACEMENT = """
Placement
---------
The color widget can be initialized with a variety of placement options.
'auto', 'auto-top', 'left' and 'right' options will automatically horizontally
align the widget on top or bottom of the input field, depending on available
space within the viewport.
Supported options:
- top
- bottom
- left
- right
- static
- auto (top/bottom)
.. code-block:: python
color = factory(
'color',
name='colorwidget',
props={
'label': 'Placement on right side',
'placement': 'right'
}
)
"""


def placement_example():
part = factory(u'fieldset', name='yafowil.widget.color.default')
part['color'] = factory(
'#field:color',
props={
'label': 'Placement on right side',
'placement': 'right'
})
return {
'widget': part,
'doc': DOC_PLACEMENT,
'title': 'Placement on right side'
}


DOC_DIM = """
Custom dimensions
-----------------
Expand Down Expand Up @@ -627,6 +673,7 @@ def get_example():
return [
default_example(),
wheel_example(),
placement_example(),
layout_example(),
dim_example(),
length_example(),
Expand Down
76 changes: 75 additions & 1 deletion src/yafowil/widget/color/resources/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ var yafowil_color = (function (exports, $) {
}
this.dropdown_elem = $('<div />')
.addClass('color-picker-wrapper')
.css('top', this.elem.outerHeight())
.insertAfter(this.elem);
this.picker_container = $('<div />')
.addClass('color-picker-container')
Expand All @@ -369,6 +368,7 @@ var yafowil_color = (function (exports, $) {
.addClass('close-button')
.text('✕')
.appendTo(this.dropdown_elem);
this.placement = options.placement;
this.slider_size = options.slider_size;
let iro_opts = this.init_opts(options);
this.picker = new iro.ColorPicker(this.picker_container.get(0), iro_opts);
Expand Down Expand Up @@ -433,6 +433,7 @@ var yafowil_color = (function (exports, $) {
this.close_btn.on('click', this.close);
this.on_keydown = this.on_keydown.bind(this);
this.on_click = this.on_click.bind(this);
this.place(options.placement, options.preview_elem);
}
get active_swatch() {
return this._active_swatch;
Expand Down Expand Up @@ -488,13 +489,85 @@ var yafowil_color = (function (exports, $) {
});
return iro_opts;
}
place(placement, custom_preview) {
let left, top;
const auto_place = (on_top, on_bottom, prefers) => {
const window_height = $(window).height();
const dd_height = this.dropdown_elem.outerHeight();
const offset = this.elem[0].getBoundingClientRect();
const y_pos = offset.top + this.elem.outerHeight();
const below = window_height - y_pos;
if (!prefers || prefers === 'bottom') {
if (below >= dd_height) {
return on_bottom;
} else if (y_pos >= dd_height) {
on_top -= dd_height;
} else {
return on_bottom;
}
} else if (prefers === 'top') {
if (y_pos >= dd_height) {
on_top -= dd_height;
} else if (below >= dd_height) {
return on_bottom;
} else {
return on_bottom;
}
}
return on_top;
};
switch (placement) {
case 'left':
left = - this.dropdown_elem.outerWidth();
top = auto_place(0, -this.elem.outerHeight());
break;
case 'right':
left = this.elem.outerWidth();
if (!custom_preview && this.preview) {
left += this.preview.elem.outerWidth(true);
}
top = auto_place(0, -this.elem.outerHeight());
break;
case 'top':
left = 0;
top = -(this.dropdown_elem.outerHeight() + this.elem.outerHeight());
break;
case 'bottom':
left = 0;
top = 0;
break;
case 'static':
left = 0;
top = 0;
this.dropdown_elem.css('position', 'static');
break;
case 'auto-top':
left = 0;
top = auto_place(-this.elem.outerHeight(), 0, 'top');
break;
case 'auto':
left = 0;
top = auto_place(-this.elem.outerHeight(), 0);
break;
default:
console.warn(`Unknown placement: ${placement}`);
break;
}
this.dropdown_elem.css(
'transform',
`translate(${left}px, ${top}px)`
);
}
update_color() {
this.color = this.picker.color.clone();
this.preview.color = this.color.rgbaString;
let evt = new $.Event('color_update', {origin: this});
this.elem.trigger(evt);
}
open(evt) {
if (['auto-top', 'auto', 'left', 'right'].includes(this.placement)) {
this.place(this.placement);
}
if (this.dropdown_elem.css('display') === 'none') {
this.dropdown_elem.show();
$(window).on('keydown', this.on_keydown);
Expand Down Expand Up @@ -593,6 +666,7 @@ var yafowil_color = (function (exports, $) {
}
let options = {
format: elem.data('format'),
placement: elem.data('placement'),
preview_elem: elem.data('preview_elem'),
sliders: elem.data('sliders'),
box_width: elem.data('box_width'),
Expand Down
Loading

0 comments on commit 6ef1eb1

Please sign in to comment.