Skip to content

Commit

Permalink
support for better options widgets
Browse files Browse the repository at this point in the history
now an "options widget" supports hints about its rendering:
- "renderHint: buttonset" will render via buttonset instead of select (dropdown).
- "buttonsetIconClasses: key=value|key=value" let define css classes for the css icons to be used in the buttons (see fontawesome).
- "buttonsetLabels: key=value|key=value" let define labels for the buttonset (you have less horizontal space so maybe you need shorter labels).
- "renderHint: fontface" will use a styled dropdown using the keys of the dropadown as the font-family of the label.
- "renderHint: images":
- "imagesSources: key=url('path')|key=url('path')" to specify the template relative images to be used as labels of the select widget.
  • Loading branch information
bago committed May 19, 2022
1 parent 3709d4e commit a1bd793
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 24 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"jquery-ui/ui/widgets/tabs": "global:jQuery.ui.tabs",
"knockout": "global:ko",
"knockout-jqueryui": "global:kojqui",
"tinymce": "global:tinymce"
"tinymce": "global:tinymce",
"sifter": "global:Sifter"
},
"dependencies": {
"blueimp-canvas-to-blob": "3.29.0",
Expand All @@ -58,6 +59,9 @@
"toastr": "^2.1.4"
},
"devDependencies": {
"@lodder/grunt-postcss": "3.1.1",
"@selectize/selectize": "^0.13.5",
"@selectize/sifter": "^0.6.2",
"aliasify": "2.1.0",
"async": "3.2.3",
"autoprefixer": "^10.4.5",
Expand Down Expand Up @@ -87,7 +91,6 @@
"grunt-keepalive": "^1.0.0",
"grunt-newer": "^1.3.0",
"grunt-parallel": "0.5.1",
"@lodder/grunt-postcss": "3.1.1",
"grunt-release": "0.13.1",
"jasmine-core": "4.1.0",
"jshint-stylish": "2.2.1",
Expand Down
3 changes: 2 additions & 1 deletion src/css/app_standalone.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
@fa-font-path: "fontawesome";

@import (less) "../../node_modules/toastr/toastr.less";
@import (less) "../../node_modules/evol-colorpicker/css/evol-colorpicker.css";
@import (less) "../../node_modules/evol-colorpicker/css/evol-colorpicker.css";
@import (less) "../../node_modules/@selectize/selectize/src/less/selectize.less";
31 changes: 22 additions & 9 deletions src/css/app_standalone_material.less
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@font-family: "Noto Sans", "Helvetica Neue", Helvetica, Arial, "Nimbus Sans L", "Liberation Sans", Arimo, sans-serif;
@standard-border-radius: 2px;
@info-border-radius: @standard-border-radius;
@button-border-radius: @standard-border-radius;
@button-border-radius: 20px;
@large-balloon-border-radius: 2px;

@object-background-color: #DDDDDD;
Expand Down Expand Up @@ -49,6 +49,7 @@

#toolbar, #preview-toolbar {
.ui-button {
border-radius: 0;
padding-top: 7px;
padding-bottom: 7px;
line-height: 22px;
Expand All @@ -67,6 +68,10 @@
}
}

#main-toolbox #toolimages .ui-tabs > .ui-tabs-nav > li > a {
border-radius: 0;
}

#main-toolbox #tooltabs.ui-tabs > .ui-tabs-nav {
box-shadow: 0 0 10px @shadow-color;
position: absolute;
Expand All @@ -81,6 +86,9 @@
li {
margin: 1px 1px 0 0;
line-height: @topbar-height - 4px;
a {
border-radius: 0;
}
}
}
}
Expand All @@ -99,6 +107,7 @@
}
li > a when (@buttonstyle) {
background-color: transparent;
border-radius: 0;
&:hover {
background-color: lighten(@mosaico-ui-background-color, 10%);
border-bottom: 3px solid lighten(@mosaico-ui-background-color, 10%);
Expand Down Expand Up @@ -179,12 +188,13 @@
color: @button-background-color;
}

.mo .propInput .data-select select {
.mo .propInput .mo-select select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.mo .propInput .data-select:after {
background-color: transparent;
.mo .propInput .mo-select:after,
.mo .propInput .data-select .selectize-control.single .selectize-input:after {
background-color: transparent !important;
color: lighten(@text-color, 30%);
}
.mo .propInput .evo-pointer:before {
Expand All @@ -195,7 +205,8 @@
background-color: transparent;
color: lighten(@text-color, 30%);
}
.mo .propInput .data-select:hover:after,
.mo .propInput .mo-select:hover:after,
.mo .propInput .data-select .selectize-control.single .selectize-input:hover:after,
.mo .propInput .evo-pointer:hover:before,
.mo .ui-button.ui-spinner-button.ui-state-hover,
.mo .propInput .data-integer .ui-button-text,
Expand Down Expand Up @@ -308,11 +319,12 @@
.mo .propInput input[type=number],
.mo .propInput input[type=url],
.mo .propInput select,
.mo .propInput .data-select select,
.mo .propInput .mo-select select,
.mo .propInput .data-select .selectize-control .selectize-input,
.mo .propInput .ui-spinner .ui-spinner-input {
border-width: 0 0 2px 0;
background-color: transparent;
&:hover, &:focus {
&:hover, &:focus, &.focus {
border-color: @link-color;
}
}
Expand Down Expand Up @@ -371,9 +383,10 @@

}

// file manager broser button
// file manager browser button + buttonsets
.mo .propInput .ui-buttonset,
.mo .propInput .ui-textbutton .ui-textbutton-button {
border-radius: 50%;
border-radius: @button-border-radius;
box-shadow: 1px 1px 3px @shadow-color;
}

Expand Down
52 changes: 52 additions & 0 deletions src/css/style_elements_selectize.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.selectize-control.single {
// hide the autocomplete/edit input as we are in a non-editable select
&.selectize-force-single-noadd .selectize-input {
cursor: default;
> input {
display: none !important;
}
&.input-active {
cursor: inherit;
}
}
&.selectize-hint-images .selectize-input, &.selectize-hint-images .selectize-input.input-active {
padding-top: 2px;
padding-bottom: 0px;
padding-right: 32px;
}
.selectize-input, .selectize-input.input-active {
// default selectize uses relative but we don't need that.
position: initial;
.input-style();
margin: 0;
&:after {
.button-style();
margin: 0;

position: absolute;
top: 0;
right: 0;
bottom: 0;
line-height: 30px;
width: 28px;
margin-right: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;

font-family: FontAwesome;
content: "\f0d7";
font-weight: normal;

pointer-events:none;
}
}
.selectize-input.dropdown-active::before {
// prevent the 1px move
display: none;
}
.selectize-dropdown {
.win();
z-index: 1000;
}
}

11 changes: 8 additions & 3 deletions src/css/style_mosaico_tools.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
.noSelectedBlock, .customStyleHelp, .objEmpty, .galleryEmpty {
font-size: 1.2em;
}
.propInput .data-select::after,
.propInput .evo-pointer::before {
.propInput .mo-select::after,
.propInput .evo-pointer::before,
.propInput .selectize-input::after {
width: 31px;
padding: 0 10px;
}
Expand Down Expand Up @@ -71,6 +72,7 @@
@import (optional) "style_elements_drupal.less"; // TODO remove me
@import "style_elements_jquery.less";
@import "style_elements_input_range.less";
@import "style_elements_selectize.less";
@import (optional) "style_elements_qtip.less"; // TODO remove me

*,
Expand Down Expand Up @@ -104,7 +106,10 @@
border: @input-error-border-style;
}
}
.data-select {
.ui-button {
margin: 0;
}
.mo-select {
display: block;
.input-select();
}
Expand Down
87 changes: 87 additions & 0 deletions src/js/bindings/selectize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"use strict";
/* global global: false, console: false */
var $ = require("jquery");
var ko = require("knockout");
// selectize doesn't work if we don't expose this in the global (window) object
global.Sifter = require('@selectize/sifter');
var Selectize = require('@selectize/selectize');

// automatic dropdown direction: loop-logic like the one we contributed to Colorpicker
if (!Selectize.prototype.positionDropdownOriginal) {
Selectize.prototype.positionDropdownOriginal = Selectize.prototype.positionDropdown;
Selectize.prototype.positionDropdown = function () {
var el = this.$wrapper;
var i = 0;

while (el !== null && i < 100) {
// Look up the first parent with non-visibile overflow and compute the relative position
if (el.css('overflow') !== 'visible') {
var offset = el.offset();

offset.top += this.$control.outerHeight(true);

var dropdownHeight = this.$dropdown.prop('scrollHeight') + 5; // 5 - padding value;
var controlPosTop = this.$control.get(0).getBoundingClientRect().top;
var wrapperHeight = this.$wrapper.height();

var position = controlPosTop + dropdownHeight + wrapperHeight > global.innerHeight ? 'top' : 'bottom';
var styles = {
width: this.$control.outerWidth(),
left: 0,
top: position === 'top' ? - dropdownHeight : wrapperHeight,
};

this.$dropdown.css(styles);
break;
}
if (el[0].tagName == 'HTML') break;
else el = el.offsetParent();
i++;
}
};
}

ko.bindingHandlers.selectize = {
init: function(element, valueAccessor, allBindingsAccessor) {
var $element = $(element);

var renderFunction = function(type, item, escape) {
return '<div class="' + type + '">' + escape(item.text) + '</div>';
};

var overrideRenderFunction = allBindingsAccessor.get("selectizeRenderer");
if (typeof overrideRenderFunction !== 'undefined' && overrideRenderFunction !== null) renderFunction = overrideRenderFunction;

$element.selectize({
maxItems: 1,
closeAfterSelect: true,
selectOnTab: true,
/* @see https://github.com/selectize/selectize.js/discussions/1804
onClear: function() {
return false;
},
onDelete: function() {
return false;
},
*/
// dropdownParent: 'body',
// openOnFocus: true,
onChange: function(value) {
valueAccessor()(value);
},
render: {
option: renderFunction.bind(undefined, 'option'),
item: renderFunction.bind(undefined, 'item')
},
});

ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$element[0].selectize.destroy();
});
},

update: function(element, valueAccessor) {
var value = valueAccessor();
element.selectize.setValue(ko.utils.unwrapObservable(value), true);
},
};
Loading

0 comments on commit a1bd793

Please sign in to comment.