selectic 3.0.14 → 3.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,12 +32,13 @@ function styleInject(css, ref) {
32
32
  }
33
33
  }
34
34
 
35
- var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n overflow: auto;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
35
+ var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-container{\n overflow: auto;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n min-width: max-content;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
36
36
  styleInject(css_248z);
37
37
 
38
38
  /**
39
39
  * Clone the object and its inner properties.
40
40
  * @param obj The object to be clone.
41
+ * @param attributes list of attributes to not clone.
41
42
  * @param refs internal reference to object to avoid cyclic references
42
43
  * @returns a copy of obj
43
44
  */
@@ -299,7 +300,7 @@ class SelecticStore {
299
300
  const value = deepClone(this.props.value);
300
301
  /* set initial value for non reactive attribute */
301
302
  this.cacheRequest = new Map();
302
- const stateParam = deepClone(this.props.params);
303
+ const stateParam = deepClone(this.props.params, ['data']);
303
304
  if (stateParam.optionBehavior) {
304
305
  this.buildOptionBehavior(stateParam.optionBehavior, stateParam);
305
306
  delete stateParam.optionBehavior;
@@ -444,13 +445,10 @@ class SelecticStore {
444
445
  selectItem(id, selected, keepOpen = false) {
445
446
  const state = this.state;
446
447
  let hasChanged = false;
447
- const isPartial = vue.unref(this.isPartial);
448
+ const item = state.allOptions.find((opt) => opt.id === id);
448
449
  /* Check that item is not disabled */
449
- if (!isPartial) {
450
- const item = state.allOptions.find((opt) => opt.id === id);
451
- if (item && item.disabled) {
452
- return;
453
- }
450
+ if (item === null || item === void 0 ? void 0 : item.disabled) {
451
+ return;
454
452
  }
455
453
  if (state.strictValue && !this.hasValue(id)) {
456
454
  /* reject invalid values */
@@ -468,6 +466,18 @@ class SelecticStore {
468
466
  hasChanged = internalValue.length > 0;
469
467
  }
470
468
  else if (selected && !isAlreadySelected) {
469
+ if (item === null || item === void 0 ? void 0 : item.exclusive) {
470
+ /* clear the current selection because the item is exclusive */
471
+ internalValue.splice(0, Infinity);
472
+ }
473
+ else if (internalValue.length === 1) {
474
+ const selectedId = internalValue[0];
475
+ const selectedItem = state.allOptions.find((opt) => opt.id === selectedId);
476
+ if (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.exclusive) {
477
+ /* clear the current selection because the old item was exclusive */
478
+ internalValue.pop();
479
+ }
480
+ }
471
481
  internalValue.push(id);
472
482
  hasChanged = true;
473
483
  }
@@ -1770,24 +1780,26 @@ let List = class List extends vtyx.Vue {
1770
1780
  }
1771
1781
  /* }}} */
1772
1782
  render() {
1773
- return (vtyx.h("ul", { on: {
1783
+ return (vtyx.h("div", { class: "selectic__extended-list__list-container", on: {
1774
1784
  scroll: this.checkOffset,
1775
1785
  }, ref: "elList" },
1776
- !!this.topOffset && (vtyx.h("li", { class: "selectic-item", style: `height:${this.topOffset}px;` })),
1777
- this.shortOptions.map((option, idx) => (vtyx.h("li", { on: {
1778
- 'click.prevent.stop': () => this.click(option),
1779
- 'mouseover': () => this.onMouseOver(idx),
1780
- }, class: ['selectic-item', option.className || '', {
1781
- 'selected': option.selected,
1782
- 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
1783
- 'selectic-item__disabled': !!option.disabled,
1784
- 'selectic-item__is-in-group': !!option.group,
1785
- 'selectic-item__is-group': option.isGroup,
1786
- }], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
1787
- this.isMultiple && (vtyx.h("span", { class: "fa fa-fw fa-check selectic-item_icon" })),
1788
- option.icon && (vtyx.h("span", { class: option.icon })),
1789
- option.text))),
1790
- !!this.bottomOffset && (vtyx.h("li", { class: "selectic-item", style: `height:${this.bottomOffset}px;` }))));
1786
+ vtyx.h("ul", { class: "selectic__extended-list__list-items" },
1787
+ !!this.topOffset && (vtyx.h("li", { class: "selectic-item", style: `height:${this.topOffset}px;` })),
1788
+ this.shortOptions.map((option, idx) => (vtyx.h("li", { on: {
1789
+ 'click.prevent.stop': () => this.click(option),
1790
+ 'mouseover': () => this.onMouseOver(idx),
1791
+ }, class: ['selectic-item', option.className || '', {
1792
+ 'selected': option.selected,
1793
+ 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
1794
+ 'selectic-item__disabled': !!option.disabled,
1795
+ 'selectic-item__exclusive': !!option.exclusive,
1796
+ 'selectic-item__is-in-group': !!option.group,
1797
+ 'selectic-item__is-group': option.isGroup,
1798
+ }], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
1799
+ this.isMultiple && (vtyx.h("span", { class: "fa fa-fw fa-check selectic-item_icon" })),
1800
+ option.icon && (vtyx.h("span", { class: option.icon })),
1801
+ option.text))),
1802
+ !!this.bottomOffset && (vtyx.h("li", { class: "selectic-item", style: `height:${this.bottomOffset}px;` })))));
1791
1803
  }
1792
1804
  };
1793
1805
  __decorate$2([
@@ -1987,7 +1999,7 @@ let ExtendedList = class ExtendedList extends vtyx.Vue {
1987
1999
  return (vtyx.h("div", { style: this.positionStyle, class: "selectic selectic__extended-list" },
1988
2000
  !state.hideFilter && (vtyx.h(Filter, { store: this.store })),
1989
2001
  isGroup && (vtyx.h("span", { class: "selectic-item selectic-item--header selectic-item__is-group" }, this.topGroup)),
1990
- vtyx.h(List$1, { store: store, class: "selectic__extended-list__list-items", on: {
2002
+ vtyx.h(List$1, { store: store, on: {
1991
2003
  groupId: this.getGroup,
1992
2004
  } }),
1993
2005
  this.infoMessage && (vtyx.h("div", { class: "selectic__message alert-info" }, this.infoMessage)),
@@ -2264,7 +2276,7 @@ let Selectic = class Selectic extends vtyx.Vue {
2264
2276
  this.store.props.selectionIsExcluded = this.selectionIsExcluded;
2265
2277
  }
2266
2278
  onOptionsChange() {
2267
- this.store.props.options = deepClone(this.options);
2279
+ this.store.props.options = deepClone(this.options, ['data']);
2268
2280
  }
2269
2281
  onTextsChange() {
2270
2282
  const texts = this.texts;
@@ -2439,7 +2451,7 @@ let Selectic = class Selectic extends vtyx.Vue {
2439
2451
  var _a, _b, _c;
2440
2452
  this._elementsListeners = [];
2441
2453
  this.store = new SelecticStore({
2442
- options: deepClone(this.options),
2454
+ options: deepClone(this.options, ['data']),
2443
2455
  value: deepClone(this.value),
2444
2456
  selectionIsExcluded: this.selectionIsExcluded,
2445
2457
  disabled: this.disabled,
@@ -28,12 +28,13 @@ function styleInject(css, ref) {
28
28
  }
29
29
  }
30
30
 
31
- var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n overflow: auto;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
31
+ var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-container{\n overflow: auto;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n min-width: max-content;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
32
32
  styleInject(css_248z);
33
33
 
34
34
  /**
35
35
  * Clone the object and its inner properties.
36
36
  * @param obj The object to be clone.
37
+ * @param attributes list of attributes to not clone.
37
38
  * @param refs internal reference to object to avoid cyclic references
38
39
  * @returns a copy of obj
39
40
  */
@@ -295,7 +296,7 @@ class SelecticStore {
295
296
  const value = deepClone(this.props.value);
296
297
  /* set initial value for non reactive attribute */
297
298
  this.cacheRequest = new Map();
298
- const stateParam = deepClone(this.props.params);
299
+ const stateParam = deepClone(this.props.params, ['data']);
299
300
  if (stateParam.optionBehavior) {
300
301
  this.buildOptionBehavior(stateParam.optionBehavior, stateParam);
301
302
  delete stateParam.optionBehavior;
@@ -440,13 +441,10 @@ class SelecticStore {
440
441
  selectItem(id, selected, keepOpen = false) {
441
442
  const state = this.state;
442
443
  let hasChanged = false;
443
- const isPartial = unref(this.isPartial);
444
+ const item = state.allOptions.find((opt) => opt.id === id);
444
445
  /* Check that item is not disabled */
445
- if (!isPartial) {
446
- const item = state.allOptions.find((opt) => opt.id === id);
447
- if (item && item.disabled) {
448
- return;
449
- }
446
+ if (item === null || item === void 0 ? void 0 : item.disabled) {
447
+ return;
450
448
  }
451
449
  if (state.strictValue && !this.hasValue(id)) {
452
450
  /* reject invalid values */
@@ -464,6 +462,18 @@ class SelecticStore {
464
462
  hasChanged = internalValue.length > 0;
465
463
  }
466
464
  else if (selected && !isAlreadySelected) {
465
+ if (item === null || item === void 0 ? void 0 : item.exclusive) {
466
+ /* clear the current selection because the item is exclusive */
467
+ internalValue.splice(0, Infinity);
468
+ }
469
+ else if (internalValue.length === 1) {
470
+ const selectedId = internalValue[0];
471
+ const selectedItem = state.allOptions.find((opt) => opt.id === selectedId);
472
+ if (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.exclusive) {
473
+ /* clear the current selection because the old item was exclusive */
474
+ internalValue.pop();
475
+ }
476
+ }
467
477
  internalValue.push(id);
468
478
  hasChanged = true;
469
479
  }
@@ -1766,24 +1776,26 @@ let List = class List extends Vue {
1766
1776
  }
1767
1777
  /* }}} */
1768
1778
  render() {
1769
- return (h("ul", { on: {
1779
+ return (h("div", { class: "selectic__extended-list__list-container", on: {
1770
1780
  scroll: this.checkOffset,
1771
1781
  }, ref: "elList" },
1772
- !!this.topOffset && (h("li", { class: "selectic-item", style: `height:${this.topOffset}px;` })),
1773
- this.shortOptions.map((option, idx) => (h("li", { on: {
1774
- 'click.prevent.stop': () => this.click(option),
1775
- 'mouseover': () => this.onMouseOver(idx),
1776
- }, class: ['selectic-item', option.className || '', {
1777
- 'selected': option.selected,
1778
- 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
1779
- 'selectic-item__disabled': !!option.disabled,
1780
- 'selectic-item__is-in-group': !!option.group,
1781
- 'selectic-item__is-group': option.isGroup,
1782
- }], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
1783
- this.isMultiple && (h("span", { class: "fa fa-fw fa-check selectic-item_icon" })),
1784
- option.icon && (h("span", { class: option.icon })),
1785
- option.text))),
1786
- !!this.bottomOffset && (h("li", { class: "selectic-item", style: `height:${this.bottomOffset}px;` }))));
1782
+ h("ul", { class: "selectic__extended-list__list-items" },
1783
+ !!this.topOffset && (h("li", { class: "selectic-item", style: `height:${this.topOffset}px;` })),
1784
+ this.shortOptions.map((option, idx) => (h("li", { on: {
1785
+ 'click.prevent.stop': () => this.click(option),
1786
+ 'mouseover': () => this.onMouseOver(idx),
1787
+ }, class: ['selectic-item', option.className || '', {
1788
+ 'selected': option.selected,
1789
+ 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
1790
+ 'selectic-item__disabled': !!option.disabled,
1791
+ 'selectic-item__exclusive': !!option.exclusive,
1792
+ 'selectic-item__is-in-group': !!option.group,
1793
+ 'selectic-item__is-group': option.isGroup,
1794
+ }], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
1795
+ this.isMultiple && (h("span", { class: "fa fa-fw fa-check selectic-item_icon" })),
1796
+ option.icon && (h("span", { class: option.icon })),
1797
+ option.text))),
1798
+ !!this.bottomOffset && (h("li", { class: "selectic-item", style: `height:${this.bottomOffset}px;` })))));
1787
1799
  }
1788
1800
  };
1789
1801
  __decorate$2([
@@ -1983,7 +1995,7 @@ let ExtendedList = class ExtendedList extends Vue {
1983
1995
  return (h("div", { style: this.positionStyle, class: "selectic selectic__extended-list" },
1984
1996
  !state.hideFilter && (h(Filter, { store: this.store })),
1985
1997
  isGroup && (h("span", { class: "selectic-item selectic-item--header selectic-item__is-group" }, this.topGroup)),
1986
- h(List$1, { store: store, class: "selectic__extended-list__list-items", on: {
1998
+ h(List$1, { store: store, on: {
1987
1999
  groupId: this.getGroup,
1988
2000
  } }),
1989
2001
  this.infoMessage && (h("div", { class: "selectic__message alert-info" }, this.infoMessage)),
@@ -2260,7 +2272,7 @@ let Selectic = class Selectic extends Vue {
2260
2272
  this.store.props.selectionIsExcluded = this.selectionIsExcluded;
2261
2273
  }
2262
2274
  onOptionsChange() {
2263
- this.store.props.options = deepClone(this.options);
2275
+ this.store.props.options = deepClone(this.options, ['data']);
2264
2276
  }
2265
2277
  onTextsChange() {
2266
2278
  const texts = this.texts;
@@ -2435,7 +2447,7 @@ let Selectic = class Selectic extends Vue {
2435
2447
  var _a, _b, _c;
2436
2448
  this._elementsListeners = [];
2437
2449
  this.store = new SelecticStore({
2438
- options: deepClone(this.options),
2450
+ options: deepClone(this.options, ['data']),
2439
2451
  value: deepClone(this.value),
2440
2452
  selectionIsExcluded: this.selectionIsExcluded,
2441
2453
  disabled: this.disabled,
package/doc/list.md CHANGED
@@ -25,12 +25,13 @@ It is possible to define the `option` more precisely.
25
25
  * **id** {`string | number`} _(mandatory)_: The option identifier. *It is important that it is unique among all other options*.
26
26
  * **text** {`string`} _(mandatory)_: The text which is displayed to select the option or when it is selected.
27
27
  * **title** {`string`}: Text displayed in `title` when cursor is over the option (default: `''`).
28
- * **disabled** {`boolean`}: if `true` this option cannot be selected (default: `false`).
28
+ * **disabled** {`boolean`}: if `true`, this option cannot be selected (default: `false`).
29
29
  * **className** {`string`}: `class` that are applied on the option (default: `''`).
30
30
  * **style** {`string`}: css style which are applied on the option (default: `''`).
31
31
  * **icon** {`string`}: class names which are applied on a `<span>` before text in the option to display an icon (default: `''`).
32
32
  * **options** {`options[]`}: an other list of options. The current option is considered as a group (equivalent of `optgroup`) (default: `undefined`).
33
- * **group** {`string | number`}: If set the option is part of the given group. This property is needed only in dynamic mode if the option is part of an optgroup (default: `null`).
33
+ * **group** {`string | number`}: If set, the option is part of the given group. This property is needed only in dynamic mode if the option is part of an optgroup (default: `null`).
34
+ * **exclusive** {`boolean`}: If set to `true`, in multiple mode, this option will be the only one selected. It means that it clears the previous selected options, and if another option is selected, this option is no more selected.
34
35
  * **data** {`any`}: You can store any information here, it will be provided when getting selected options. _It is not used by selectic so it can be anything you want_ (default: `undefined`).
35
36
 
36
37
  ```javascript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selectic",
3
- "version": "3.0.14",
3
+ "version": "3.0.16",
4
4
  "description": "Smart Select for VueJS 3.x",
5
5
  "main": "dist/selectic.common.js",
6
6
  "module": "dist/selectic.esm.js",
@@ -41,10 +41,10 @@
41
41
  "vtyx": "4.0.5"
42
42
  },
43
43
  "devDependencies": {
44
- "@babel/types": "^7.16.7",
45
- "rollup": "^2.63.0",
44
+ "@babel/types": "^7.19.4",
45
+ "rollup": "^2.79.1",
46
46
  "rollup-plugin-postcss": "^3.1.8",
47
- "tape": "^4.14.0",
47
+ "tape": "^4.16.1",
48
48
  "typescript": "~4.5"
49
49
  }
50
50
  }
@@ -255,6 +255,7 @@ export default class ExtendedList extends Vue<Props> {
255
255
  store={this.store}
256
256
  />
257
257
  )}
258
+
258
259
  {isGroup && (
259
260
  <span
260
261
  class="selectic-item selectic-item--header selectic-item__is-group"
@@ -264,7 +265,6 @@ export default class ExtendedList extends Vue<Props> {
264
265
  )}
265
266
  <List
266
267
  store={store}
267
- class="selectic__extended-list__list-items"
268
268
  on={{
269
269
  groupId: this.getGroup,
270
270
  }}
package/src/List.tsx CHANGED
@@ -22,7 +22,7 @@ export interface Props {
22
22
  @Component
23
23
  export default class List extends Vue<Props> {
24
24
  public $refs: {
25
- elList: HTMLUListElement;
25
+ elList: HTMLDivElement;
26
26
  };
27
27
 
28
28
  /* {{{ props */
@@ -241,53 +241,59 @@ export default class List extends Vue<Props> {
241
241
 
242
242
  public render() {
243
243
  return (
244
- <ul
244
+ <div
245
+ class="selectic__extended-list__list-container"
245
246
  on={{
246
247
  scroll: this.checkOffset,
247
248
  }}
248
249
  ref="elList"
249
250
  >
250
- {!!this.topOffset && (
251
- <li
252
- class="selectic-item"
253
- style={`height:${this.topOffset}px;`}
254
- ></li>
255
- )}
256
- {this.shortOptions.map((option, idx) => (
257
- <li
258
- on={{
259
- 'click.prevent.stop': () => this.click(option),
260
- 'mouseover': () => this.onMouseOver(idx),
261
- }}
262
- class={['selectic-item', option.className || '', {
263
- 'selected': option.selected,
264
- 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
265
- 'selectic-item__disabled': !!option.disabled,
266
- 'selectic-item__is-in-group': !!option.group,
267
- 'selectic-item__is-group': option.isGroup,
268
- }]}
269
- style={option.style}
270
- title={option.title}
271
- key={'selectic-item-' + (idx + this.startIndex)}
251
+ <ul
252
+ class="selectic__extended-list__list-items"
272
253
  >
273
- {this.isMultiple && (
274
- <span
275
- class="fa fa-fw fa-check selectic-item_icon"
276
- ></span>
277
- )}
278
- {option.icon && (
279
- <span class={option.icon}></span>
280
- )}
281
- {option.text}
282
- </li>
283
- ))}
284
- {!!this.bottomOffset && (
285
- <li
286
- class="selectic-item"
287
- style={`height:${this.bottomOffset}px;`}
288
- ></li>
289
- )}
290
- </ul>
254
+ {!!this.topOffset && (
255
+ <li
256
+ class="selectic-item"
257
+ style={`height:${this.topOffset}px;`}
258
+ ></li>
259
+ )}
260
+ {this.shortOptions.map((option, idx) => (
261
+ <li
262
+ on={{
263
+ 'click.prevent.stop': () => this.click(option),
264
+ 'mouseover': () => this.onMouseOver(idx),
265
+ }}
266
+ class={['selectic-item', option.className || '', {
267
+ 'selected': option.selected,
268
+ 'selectic-item__active': idx + this.startIndex === this.store.state.activeItemIdx,
269
+ 'selectic-item__disabled': !!option.disabled,
270
+ 'selectic-item__exclusive': !!option.exclusive,
271
+ 'selectic-item__is-in-group': !!option.group,
272
+ 'selectic-item__is-group': option.isGroup,
273
+ }]}
274
+ style={option.style}
275
+ title={option.title}
276
+ key={'selectic-item-' + (idx + this.startIndex)}
277
+ >
278
+ {this.isMultiple && (
279
+ <span
280
+ class="fa fa-fw fa-check selectic-item_icon"
281
+ ></span>
282
+ )}
283
+ {option.icon && (
284
+ <span class={option.icon}></span>
285
+ )}
286
+ {option.text}
287
+ </li>
288
+ ))}
289
+ {!!this.bottomOffset && (
290
+ <li
291
+ class="selectic-item"
292
+ style={`height:${this.bottomOffset}px;`}
293
+ ></li>
294
+ )}
295
+ </ul>
296
+ </div>
291
297
  );
292
298
  }
293
299
  }
package/src/Store.tsx CHANGED
@@ -29,6 +29,7 @@ export interface OptionValue {
29
29
  style?: string;
30
30
  icon?: string;
31
31
  options?: OptionValue[];
32
+ exclusive?: boolean;
32
33
 
33
34
  /* Used to store specific information about this option.
34
35
  * This `data` is not used by Selectic. */
@@ -593,7 +594,7 @@ export default class SelecticStore {
593
594
  this.cacheRequest = new Map();
594
595
 
595
596
  const stateParam: SelecticStoreStateParams | SelecticStoreState =
596
- deepClone(this.props.params);
597
+ deepClone(this.props.params, ['data']);
597
598
 
598
599
  if (stateParam.optionBehavior) {
599
600
  this.buildOptionBehavior(
@@ -766,14 +767,11 @@ export default class SelecticStore {
766
767
  public selectItem(id: OptionId, selected?: boolean, keepOpen = false) {
767
768
  const state = this.state;
768
769
  let hasChanged = false;
769
- const isPartial = unref(this.isPartial);
770
+ const item = state.allOptions.find((opt) => opt.id === id);
770
771
 
771
772
  /* Check that item is not disabled */
772
- if (!isPartial) {
773
- const item = state.allOptions.find((opt) => opt.id === id);
774
- if (item && item.disabled) {
775
- return;
776
- }
773
+ if (item?.disabled) {
774
+ return;
777
775
  }
778
776
 
779
777
  if (state.strictValue && !this.hasValue(id)) {
@@ -795,6 +793,17 @@ export default class SelecticStore {
795
793
  hasChanged = internalValue.length > 0;
796
794
  } else
797
795
  if (selected && !isAlreadySelected) {
796
+ if (item?.exclusive) {
797
+ /* clear the current selection because the item is exclusive */
798
+ internalValue.splice(0, Infinity);
799
+ } else if (internalValue.length === 1) {
800
+ const selectedId = internalValue[0];
801
+ const selectedItem = state.allOptions.find((opt) => opt.id === selectedId);
802
+ if (selectedItem?.exclusive) {
803
+ /* clear the current selection because the old item was exclusive */
804
+ internalValue.pop();
805
+ }
806
+ }
798
807
  internalValue.push(id);
799
808
  hasChanged = true;
800
809
  } else
@@ -192,9 +192,12 @@
192
192
  padding: 0;
193
193
  min-width: 200px;
194
194
  }
195
+ .selectic__extended-list__list-container{
196
+ overflow: auto;
197
+ }
195
198
  .selectic__extended-list__list-items {
196
199
  max-height: calc(var(--selectic-input-height) * 10);
197
- overflow: auto;
200
+ min-width: max-content;
198
201
  padding-left: 0;
199
202
  }
200
203
 
package/src/index.tsx CHANGED
@@ -561,7 +561,7 @@ export default class Selectic extends Vue<Props> {
561
561
 
562
562
  @Watch('options', { deep: true })
563
563
  public onOptionsChange() {
564
- this.store.props.options = deepClone(this.options);
564
+ this.store.props.options = deepClone(this.options, ['data']);
565
565
  }
566
566
 
567
567
  @Watch('texts', { deep: true })
@@ -782,7 +782,7 @@ export default class Selectic extends Vue<Props> {
782
782
  this._elementsListeners = [];
783
783
 
784
784
  this.store = new Store({
785
- options: deepClone(this.options),
785
+ options: deepClone(this.options, ['data']),
786
786
  value: deepClone(this.value),
787
787
  selectionIsExcluded: this.selectionIsExcluded,
788
788
  disabled: this.disabled,
package/src/tools.ts CHANGED
@@ -3,6 +3,7 @@ import { unref } from 'vue';
3
3
  /**
4
4
  * Clone the object and its inner properties.
5
5
  * @param obj The object to be clone.
6
+ * @param attributes list of attributes to not clone.
6
7
  * @param refs internal reference to object to avoid cyclic references
7
8
  * @returns a copy of obj
8
9
  */
@@ -202,8 +202,10 @@ tape.test('selectItem()', (st) => {
202
202
 
203
203
  st.test('when "multiple" is true', (sTest) => {
204
204
  function getStore() {
205
- const options = getOptions(6);
205
+ const options = getOptions(8);
206
206
  options[4].disabled = true;
207
+ options[6].exclusive = true;
208
+ options[7].exclusive = true;
207
209
 
208
210
  const store = new Store({
209
211
  options: options,
@@ -363,7 +365,6 @@ tape.test('selectItem()', (st) => {
363
365
  t.end();
364
366
  });
365
367
 
366
-
367
368
  sTest.test('should clear selection', (t) => {
368
369
  const store = getStore();
369
370
  store.state.internalValue = [1, 4];
@@ -412,5 +413,29 @@ tape.test('selectItem()', (st) => {
412
413
  t.is(store.state.status.hasChanged, false);
413
414
  t.end();
414
415
  });
416
+
417
+ sTest.test('should keep only exclusive item', (t) => {
418
+ const store = getStore();
419
+ store.state.internalValue = [1, 4, 5];
420
+
421
+ store.selectItem(6, true);
422
+ t.deepEqual(store.state.internalValue, [6]);
423
+ t.is(store.state.status.hasChanged, true);
424
+
425
+ store.selectItem(7, true);
426
+ t.deepEqual(store.state.internalValue, [7]);
427
+ t.is(store.state.status.hasChanged, true);
428
+
429
+ store.selectItem(1, true);
430
+ t.deepEqual(store.state.internalValue, [1]);
431
+ t.is(store.state.status.hasChanged, true);
432
+
433
+ store.selectItem(5, true);
434
+ t.deepEqual(store.state.internalValue, [1, 5]);
435
+ t.is(store.state.status.hasChanged, true);
436
+
437
+ t.is(store.state.selectionIsExcluded, false);
438
+ t.end();
439
+ });
415
440
  });
416
441
  });
package/types/List.d.ts CHANGED
@@ -8,7 +8,7 @@ export interface Props {
8
8
  }
9
9
  export default class List extends Vue<Props> {
10
10
  $refs: {
11
- elList: HTMLUListElement;
11
+ elList: HTMLDivElement;
12
12
  };
13
13
  private store;
14
14
  private itemHeight;
package/types/Store.d.ts CHANGED
@@ -15,6 +15,7 @@ export interface OptionValue {
15
15
  style?: string;
16
16
  icon?: string;
17
17
  options?: OptionValue[];
18
+ exclusive?: boolean;
18
19
  data?: any;
19
20
  }
20
21
  declare type OptionBehaviorOperation = 'sort' | 'force';
package/types/tools.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Clone the object and its inner properties.
3
3
  * @param obj The object to be clone.
4
+ * @param attributes list of attributes to not clone.
4
5
  * @param refs internal reference to object to avoid cyclic references
5
6
  * @returns a copy of obj
6
7
  */