selectic 3.1.1 → 3.1.3

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.
@@ -28,7 +28,7 @@ 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 top: var(--top-position, 0);\n z-index: 2000;\n height: auto;\n max-height: var(--availableSpace);\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 width: var(--list-width, 200px);\n min-width: 200px;\n display: grid;\n grid-template-rows: minmax(0, max-content) 1fr;\n}\n.selectic__extended-list.selectic-position-top {\n box-shadow: 2px -3px 12px 0px #888888;\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__is-group.selectable {\n cursor: pointer;\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.selectic .form-control-feedback.fa.selectic-search-scope {\n width: calc(var(--selectic-input-height) * 0.75);\n height: calc(var(--selectic-input-height) * 0.75);\n line-height: calc(var(--selectic-input-height) * 0.75);\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/* {{{ icons */\n\n@keyframes selectic-animation-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(359deg);\n }\n}\n\n.selectic__icon {\n height: 1em;\n fill: currentColor;\n}\n\n.selectic-spin {\n animation: selectic-animation-spin 2s infinite linear;\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 top: var(--top-position, 0);\n z-index: 2000;\n height: auto;\n max-height: var(--availableSpace);\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 width: var(--list-width, 200px);\n min-width: 200px;\n display: grid;\n grid-template-rows: minmax(0, max-content) 1fr;\n}\n.selectic__extended-list.selectic-position-top {\n box-shadow: 2px -3px 12px 0px #888888;\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.selectic-item__active.selectic-item__disabled:not(.selected) .selectic-item_icon {\n opacity: 0;\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__is-group.selectable {\n cursor: pointer;\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.selectic .form-control-feedback.fa.selectic-search-scope {\n width: calc(var(--selectic-input-height) * 0.75);\n height: calc(var(--selectic-input-height) * 0.75);\n line-height: calc(var(--selectic-input-height) * 0.75);\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/* {{{ icons */\n\n@keyframes selectic-animation-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(359deg);\n }\n}\n\n.selectic__icon {\n height: 1em;\n fill: currentColor;\n}\n\n.selectic-spin {\n animation: selectic-animation-spin 2s infinite linear;\n}\n\n/* }}} */\n";
32
32
  styleInject(css_248z);
33
33
 
34
34
  /**
@@ -134,12 +134,25 @@ function compareOptions(oldOptions, newOptions) {
134
134
  });
135
135
  });
136
136
  }
137
+ let displayLog = false;
138
+ function debug(fName, step, ...args) {
139
+ if (!displayLog) {
140
+ return;
141
+ }
142
+ console.log('--%s-- [%s]', fName, step, ...args);
143
+ }
144
+ /** Enable logs for debugging */
145
+ debug.enable = (display) => {
146
+ displayLog = display;
147
+ };
137
148
 
138
149
  /* File Purpose:
139
150
  * It keeps and computes all states at a single place.
140
151
  * Every inner components of Selectic should communicate with this file to
141
152
  * change or to get states.
142
153
  */
154
+ /* For debugging */
155
+ debug.enable(false);
143
156
  /* }}} */
144
157
  /* {{{ Static */
145
158
  function changeTexts$1(texts) {
@@ -174,12 +187,19 @@ let messages = {
174
187
  let defaultFamilyIcon = 'selectic';
175
188
  let icons = {};
176
189
  let closePreviousSelectic;
190
+ /**
191
+ * Time to wait before considering there is no other requests.
192
+ * This time is await only if there is already a requested request.
193
+ */
194
+ const DEBOUNCE_REQUEST = 250;
177
195
  /* }}} */
178
196
  let uid = 0;
179
197
  class SelecticStore {
180
198
  constructor(props = {}) {
181
199
  /* Do not need reactivity */
182
200
  this.requestId = 0;
201
+ this.requestSearchId = 0; /* Used for search request */
202
+ this.isRequesting = false;
183
203
  this._uid = ++uid;
184
204
  /* {{{ Props */
185
205
  const defaultProps = {
@@ -295,6 +315,7 @@ class SelecticStore {
295
315
  this.data.cacheItem.clear();
296
316
  this.setAutomaticClose();
297
317
  this.commit('isOpen', false);
318
+ this.clearDisplay();
298
319
  this.buildAllOptions(true);
299
320
  this.buildSelectedOptions();
300
321
  }, { deep: true });
@@ -385,6 +406,7 @@ class SelecticStore {
385
406
  /* {{{ public methods */
386
407
  commit(name, value) {
387
408
  const oldValue = this.state[name];
409
+ debug('commit', 'start', name, value, 'oldValue:', oldValue);
388
410
  if (oldValue === value) {
389
411
  return;
390
412
  }
@@ -393,8 +415,7 @@ class SelecticStore {
393
415
  case 'searchText':
394
416
  this.state.offsetItem = 0;
395
417
  this.state.activeItemIdx = -1;
396
- this.state.filteredOptions = [];
397
- this.state.totalFilteredOptions = Infinity;
418
+ this.clearDisplay();
398
419
  if (value) {
399
420
  this.buildFilteredOptions();
400
421
  }
@@ -442,6 +463,7 @@ class SelecticStore {
442
463
  }
443
464
  break;
444
465
  }
466
+ debug('commit', '(done)', name);
445
467
  }
446
468
  setAutomaticChange() {
447
469
  this.state.status.automaticChange = true;
@@ -532,25 +554,54 @@ class SelecticStore {
532
554
  if (selected === undefined) {
533
555
  selected = !isAlreadySelected;
534
556
  }
557
+ const selectedOptions = Array.isArray(state.selectedOptions)
558
+ ? state.selectedOptions
559
+ : [];
535
560
  if (id === null) {
536
- state.internalValue = [];
537
- hasChanged = internalValue.length > 0;
561
+ /* Keep disabled items: we cannot removed them because they
562
+ * are disabled */
563
+ const newSelection = selectedOptions.reduce((list, item) => {
564
+ if (item.disabled && item.id) {
565
+ list.push(item.id);
566
+ }
567
+ return list;
568
+ }, []);
569
+ state.internalValue = newSelection;
570
+ hasChanged = internalValue.length > newSelection.length;
538
571
  }
539
572
  else if (selected && !isAlreadySelected) {
573
+ let addItem = true;
540
574
  if (item === null || item === void 0 ? void 0 : item.exclusive) {
541
- /* clear the current selection because the item is exclusive */
542
- internalValue.splice(0, Infinity);
575
+ const hasDisabledSelected = selectedOptions.some((opt) => {
576
+ return opt.disabled;
577
+ });
578
+ if (hasDisabledSelected) {
579
+ /* do not remove disabled item from selection */
580
+ addItem = false;
581
+ }
582
+ else {
583
+ /* clear the current selection because the item is exclusive */
584
+ internalValue.splice(0, Infinity);
585
+ }
543
586
  }
544
587
  else if (internalValue.length === 1) {
545
588
  const selectedId = internalValue[0];
546
589
  const selectedItem = state.allOptions.find((opt) => opt.id === selectedId);
547
590
  if (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.exclusive) {
548
- /* clear the current selection because the old item was exclusive */
549
- internalValue.pop();
591
+ if (selectedItem.disabled) {
592
+ /* If selected item is disabled and exclusive do not change the selection */
593
+ addItem = false;
594
+ }
595
+ else {
596
+ /* clear the current selection because the old item was exclusive */
597
+ internalValue.pop();
598
+ }
550
599
  }
551
600
  }
552
- internalValue.push(id);
553
- hasChanged = true;
601
+ if (addItem) {
602
+ internalValue.push(id);
603
+ hasChanged = true;
604
+ }
554
605
  }
555
606
  else if (!selected && isAlreadySelected) {
556
607
  internalValue.splice(internalValue.indexOf(id), 1);
@@ -573,6 +624,11 @@ class SelecticStore {
573
624
  if (id !== oldValue) {
574
625
  return hasChanged;
575
626
  }
627
+ const oldOption = state.selectedOptions;
628
+ if (oldOption === null || oldOption === void 0 ? void 0 : oldOption.disabled) {
629
+ /* old selection is disabled so do not unselect it */
630
+ return hasChanged;
631
+ }
576
632
  id = null;
577
633
  }
578
634
  else if (id === oldValue) {
@@ -627,14 +683,14 @@ class SelecticStore {
627
683
  this.state.status.errorMessage = '';
628
684
  }
629
685
  clearCache(forceReset = false) {
686
+ debug('clearCache', 'start', forceReset);
630
687
  const isPartial = unref(this.isPartial);
631
688
  const total = isPartial ? Infinity : 0;
632
689
  this.data.cacheItem.clear();
633
690
  this.state.allOptions = [];
634
691
  this.state.totalAllOptions = total;
635
692
  this.state.totalDynOptions = total;
636
- this.state.filteredOptions = [];
637
- this.state.totalFilteredOptions = Infinity;
693
+ this.clearDisplay();
638
694
  this.state.status.errorMessage = '';
639
695
  this.state.status.hasChanged = false;
640
696
  if (forceReset) {
@@ -766,6 +822,13 @@ class SelecticStore {
766
822
  this.checkAutoSelect();
767
823
  }
768
824
  }
825
+ /** Reset the display cache in order to rebuild it */
826
+ clearDisplay() {
827
+ debug('clearDisplay', 'start');
828
+ this.state.filteredOptions = [];
829
+ this.state.totalFilteredOptions = Infinity;
830
+ }
831
+ /** rebuild the state filteredOptions to normalize their values */
769
832
  updateFilteredOptions() {
770
833
  if (!this.data.doNotUpdate) {
771
834
  this.state.filteredOptions = this.buildItems(this.state.filteredOptions);
@@ -815,7 +878,7 @@ class SelecticStore {
815
878
  });
816
879
  return listOptions;
817
880
  }
818
- /* This method is for the computed property elementOptions */
881
+ /** This method is for the computed property elementOptions */
819
882
  getElementOptions() {
820
883
  const options = deepClone(this.props.childOptions, ['data']);
821
884
  const childOptions = [];
@@ -846,7 +909,9 @@ class SelecticStore {
846
909
  });
847
910
  return childOptions;
848
911
  }
912
+ /** Generate the list of all options by combining the 3 option lists */
849
913
  buildAllOptions(keepFetched = false, stopFetch = false) {
914
+ debug('buildAllOptions', 'start', 'keepFetched', keepFetched, 'stopFetch', stopFetch);
850
915
  const allOptions = [];
851
916
  let listOptions = [];
852
917
  let elementOptions = [];
@@ -918,8 +983,6 @@ class SelecticStore {
918
983
  }
919
984
  }
920
985
  if (!stopFetch) {
921
- this.state.filteredOptions = [];
922
- this.state.totalFilteredOptions = Infinity;
923
986
  this.buildFilteredOptions().then(() => {
924
987
  /* XXX: To recompute for strict mode and auto-select */
925
988
  this.assertCorrectValue();
@@ -935,18 +998,21 @@ class SelecticStore {
935
998
  const options = this.filterOptions(allOptions, search);
936
999
  this.setFilteredOptions(options);
937
1000
  }
1001
+ debug('buildAllOptions', 'end', 'allOptions:', this.state.allOptions.length, 'totalAllOptions:', this.state.totalAllOptions);
938
1002
  }
939
1003
  async buildFilteredOptions() {
940
- if (!this.state.isOpen) {
1004
+ const state = this.state;
1005
+ if (!state.isOpen) {
941
1006
  /* Do not try to fetch anything while the select is not open */
942
1007
  return;
943
1008
  }
944
- const allOptions = this.state.allOptions;
945
- const search = this.state.searchText;
946
- const totalAllOptions = this.state.totalAllOptions;
1009
+ const allOptions = state.allOptions;
1010
+ const search = state.searchText;
1011
+ const totalAllOptions = state.totalAllOptions;
947
1012
  const allOptionsLength = allOptions.length;
948
- let filteredOptionsLength = this.state.filteredOptions.length;
1013
+ let filteredOptionsLength = state.filteredOptions.length;
949
1014
  const hasAllItems = unref(this.hasAllItems);
1015
+ debug('buildFilteredOptions', 'start', 'hasAllItems:', hasAllItems, 'allOptions', allOptions.length, 'search:', search, 'filteredOptionsLength:', filteredOptionsLength);
950
1016
  if (hasAllItems) {
951
1017
  /* Everything has already been fetched and stored in filteredOptions */
952
1018
  return;
@@ -963,16 +1029,17 @@ class SelecticStore {
963
1029
  return;
964
1030
  }
965
1031
  /* When we only have partial options */
966
- const offsetItem = this.state.offsetItem;
1032
+ const offsetItem = state.offsetItem;
967
1033
  const marginSize = unref(this.marginSize);
968
1034
  const endIndex = offsetItem + marginSize;
1035
+ debug('buildFilteredOptions', 'partial options', 'offsetItem:', offsetItem, 'marginSize:', marginSize, 'filteredOptionsLength', filteredOptionsLength);
969
1036
  if (endIndex <= filteredOptionsLength) {
970
1037
  return;
971
1038
  }
972
1039
  if (!search && endIndex <= allOptionsLength) {
973
- this.setFilteredOptions(this.buildGroupItems(allOptions), false, totalAllOptions + this.state.groups.size);
1040
+ this.setFilteredOptions(this.buildGroupItems(allOptions), false, totalAllOptions + state.groups.size);
974
1041
  const isPartial = unref(this.isPartial);
975
- if (isPartial && this.state.totalDynOptions === Infinity) {
1042
+ if (isPartial && state.totalDynOptions === Infinity) {
976
1043
  this.fetchData();
977
1044
  }
978
1045
  return;
@@ -985,6 +1052,7 @@ class SelecticStore {
985
1052
  return;
986
1053
  }
987
1054
  }
1055
+ debug('buildFilteredOptions', 'end', '(will call fetchData)', this.state.filteredOptions.length);
988
1056
  await this.fetchData();
989
1057
  }
990
1058
  async buildSelectedOptions() {
@@ -1038,6 +1106,39 @@ class SelecticStore {
1038
1106
  state.selectedOptions = items[0];
1039
1107
  }
1040
1108
  }
1109
+ async fetchRequest(fetchCallback, search, offset, limit) {
1110
+ const searchRqId = ++this.requestSearchId;
1111
+ if (!search) {
1112
+ ++this.requestId;
1113
+ }
1114
+ const requestId = this.requestId;
1115
+ debug('fetchRequest', 'start', 'search:', search, 'offset:', offset, 'limit:', limit, 'requestId:', requestId, 'requestSearchId:', searchRqId, 'isRequesting:', this.isRequesting);
1116
+ if (this.isRequesting) {
1117
+ debug('fetchRequest', `await ${DEBOUNCE_REQUEST}ms`);
1118
+ /* debounce the call to avoid sending too much requests */
1119
+ await new Promise((resolve) => {
1120
+ setTimeout(resolve, DEBOUNCE_REQUEST);
1121
+ });
1122
+ /* Check if there are other requested requests, in such case drop this one */
1123
+ if (requestId !== this.requestId || (search && searchRqId !== this.requestSearchId)) {
1124
+ debug('fetchRequest', '××deprecated××', requestId, searchRqId);
1125
+ return false;
1126
+ }
1127
+ }
1128
+ this.isRequesting = true;
1129
+ const response = await fetchCallback(search, offset, limit);
1130
+ /* Check if request is obsolete */
1131
+ if (requestId !== this.requestId || (search && searchRqId !== this.requestSearchId)) {
1132
+ debug('fetchRequest', '×××deprecated×××', requestId, searchRqId);
1133
+ return false;
1134
+ }
1135
+ this.isRequesting = false;
1136
+ const deprecated = searchRqId !== this.requestSearchId;
1137
+ debug('fetchRequest', 'end', response.result.length, response.total, deprecated);
1138
+ return Object.assign(Object.assign({}, response), {
1139
+ /* this is to fulfill the cache */
1140
+ deprecated: deprecated });
1141
+ }
1041
1142
  async fetchData() {
1042
1143
  const state = this.state;
1043
1144
  const labels = this.data.labels;
@@ -1059,9 +1160,14 @@ class SelecticStore {
1059
1160
  const offset = filteredOptionsLength - this.nbGroups(state.filteredOptions) - dynOffset;
1060
1161
  const nbItems = endIndex - offset;
1061
1162
  const limit = Math.ceil(nbItems / pageSize) * pageSize;
1163
+ debug('fetchData', 'start', 'search:', search, 'offset:', offset, 'limit:', limit);
1062
1164
  try {
1063
- const requestId = ++this.requestId;
1064
- const { total: rTotal, result } = await fetchCallback(search, offset, limit);
1165
+ const response = await this.fetchRequest(fetchCallback, search, offset, limit);
1166
+ if (!response) {
1167
+ debug('fetchData', '×× deprecated ××', search, offset, limit);
1168
+ return;
1169
+ }
1170
+ const { total: rTotal, result, deprecated } = response;
1065
1171
  let total = rTotal;
1066
1172
  let errorMessage = '';
1067
1173
  /* Assert result is correctly formatted */
@@ -1079,11 +1185,12 @@ class SelecticStore {
1079
1185
  if (!search) {
1080
1186
  /* update cache */
1081
1187
  state.totalDynOptions = total;
1082
- const old = state.dynOptions.splice(offset, limit, ...result);
1188
+ const old = state.dynOptions.splice(offset, result.length, ...result);
1083
1189
  if (compareOptions(old, result)) {
1084
1190
  /* Added options are the same as previous ones.
1085
1191
  * Stop fetching to avoid infinite loop
1086
1192
  */
1193
+ debug('fetchData', 'no new values');
1087
1194
  if (!unref(this.hasFetchedAllItems)) {
1088
1195
  /* Display error if all items are not fetch
1089
1196
  * We can have the case where old value and result
@@ -1091,14 +1198,21 @@ class SelecticStore {
1091
1198
  * total is 0 */
1092
1199
  errorMessage = labels.wrongQueryResult;
1093
1200
  }
1094
- setTimeout(() => this.buildAllOptions(true, true), 0);
1201
+ setTimeout(() => {
1202
+ debug('fetchData', 'before buildAllOptions (stopped)', 'offsetItem:', this.state.offsetItem, 'allOptions:', this.state.allOptions.length);
1203
+ this.buildAllOptions(true, true);
1204
+ }, 0);
1095
1205
  }
1096
1206
  else {
1097
- setTimeout(() => this.buildAllOptions(true), 0);
1207
+ setTimeout(() => {
1208
+ debug('fetchData', 'before buildAllOptions', 'offsetItem:', this.state.offsetItem, 'allOptions:', this.state.allOptions.length);
1209
+ this.buildAllOptions(true);
1210
+ }, 0);
1098
1211
  }
1099
1212
  }
1100
- /* Check request is not obsolete */
1101
- if (requestId !== this.requestId) {
1213
+ /* Check request (without search) is not obsolete */
1214
+ if (deprecated) {
1215
+ debug('fetchData', '××× deprecated ×××', search, offset, limit);
1102
1216
  return;
1103
1217
  }
1104
1218
  if (!search) {
@@ -1127,14 +1241,17 @@ class SelecticStore {
1127
1241
  }
1128
1242
  catch (e) {
1129
1243
  state.status.errorMessage = e.message;
1244
+ debug('fetchData', 'error', e.message);
1130
1245
  if (!search) {
1131
1246
  state.totalDynOptions = 0;
1132
1247
  this.buildAllOptions(true, true);
1133
1248
  }
1134
1249
  }
1135
1250
  this.state.status.searching = false;
1251
+ debug('fetchData', 'end');
1136
1252
  }
1137
1253
  filterOptions(options, search) {
1254
+ debug('filterOptions', 'start', 'options:', options.length, 'search:', search);
1138
1255
  if (!search) {
1139
1256
  return this.buildGroupItems(options);
1140
1257
  }
@@ -1145,6 +1262,7 @@ class SelecticStore {
1145
1262
  addStaticFilteredOptions(fromDynamic = false) {
1146
1263
  const search = this.state.searchText;
1147
1264
  let continueLoop = fromDynamic;
1265
+ debug('addStaticFilteredOptions', 'start', 'fromDynamic:', fromDynamic, 'optionBehaviorOperation:', this.state.optionBehaviorOperation);
1148
1266
  if (this.state.optionBehaviorOperation !== 'sort') {
1149
1267
  return;
1150
1268
  }
@@ -1170,6 +1288,7 @@ class SelecticStore {
1170
1288
  }
1171
1289
  this.setFilteredOptions(options, true);
1172
1290
  }
1291
+ debug('addStaticFilteredOptions', 'end');
1173
1292
  }
1174
1293
  buildSelectedItems(ids) {
1175
1294
  return this.buildItems(ids.map((id) => {
@@ -1211,6 +1330,7 @@ class SelecticStore {
1211
1330
  }
1212
1331
  buildGroupItems(options, previousItem) {
1213
1332
  let previousGroupId = previousItem && previousItem.group;
1333
+ debug('buildGroupItems', 'start', 'options:', options.length, 'previousGroupId:', previousGroupId);
1214
1334
  const list = this.buildItems(options).reduce((items, item) => {
1215
1335
  if (item.group !== previousGroupId) {
1216
1336
  const groupId = item.group;
@@ -1227,6 +1347,7 @@ class SelecticStore {
1227
1347
  items.push(item);
1228
1348
  return items;
1229
1349
  }, []);
1350
+ debug('buildGroupItems', 'end', list.length);
1230
1351
  return list;
1231
1352
  }
1232
1353
  buildOptionBehavior(optionBehavior, state) {
@@ -1277,15 +1398,23 @@ class SelecticStore {
1277
1398
  if (doNotCheck || !hasFetchedAllItems) {
1278
1399
  return;
1279
1400
  }
1401
+ const selectedOptions = state.selectedOptions;
1280
1402
  const enabledOptions = state.allOptions.filter((opt) => !opt.disabled);
1281
- const nb = enabledOptions.length;
1403
+ const nbEnabled = enabledOptions.length;
1282
1404
  const value = state.internalValue;
1283
1405
  const hasValue = Array.isArray(value) ? value.length > 0 : value !== null;
1284
- const hasValidValue = hasValue && (Array.isArray(value) ? value.every((val) => this.hasValue(val)) :
1406
+ const hasDisabledSelected = Array.isArray(selectedOptions)
1407
+ ? selectedOptions.some((opt) => opt.disabled)
1408
+ : false;
1409
+ const hasOnlyValidValue = hasValue && !hasDisabledSelected && (Array.isArray(value) ? value.every((val) => this.hasValue(val)) :
1285
1410
  this.hasValue(value));
1286
- const isEmpty = nb === 0;
1287
- const hasOnlyOneOption = nb === 1 && hasValidValue && !state.allowClearSelection;
1288
- if (hasOnlyOneOption || isEmpty) {
1411
+ const isEmpty = nbEnabled === 0;
1412
+ const hasOnlyOneOption = nbEnabled === 1 && hasOnlyValidValue && !state.allowClearSelection;
1413
+ const isExclusiveDisabledItem = Array.isArray(selectedOptions) /* which means "multiple" mode */
1414
+ && selectedOptions.length === 1
1415
+ && selectedOptions[0].exclusive
1416
+ && selectedOptions[0].disabled;
1417
+ if (hasOnlyOneOption || isEmpty || isExclusiveDisabledItem) {
1289
1418
  if (state.isOpen) {
1290
1419
  this.setAutomaticClose();
1291
1420
  this.commit('isOpen', false);
@@ -1344,6 +1473,7 @@ class SelecticStore {
1344
1473
  }
1345
1474
  /** assign new value to the filteredOptions and apply change depending on it */
1346
1475
  setFilteredOptions(options, add = false, length = 0) {
1476
+ debug('setFilteredOptions', 'start', 'options:', options.length, 'add', add, 'length', length);
1347
1477
  if (!add) {
1348
1478
  this.state.filteredOptions = options;
1349
1479
  this.state.totalFilteredOptions = length || options.length;
@@ -1704,6 +1834,18 @@ let MainInput = class MainInput extends Vue {
1704
1834
  ? Array.isArray(value) && value.length > 0
1705
1835
  : value !== null;
1706
1836
  }
1837
+ get disabledList() {
1838
+ const state = this.store.state;
1839
+ const isMultiple = state.multiple;
1840
+ const value = state.selectedOptions;
1841
+ if (!isMultiple || !value) {
1842
+ return [];
1843
+ }
1844
+ const disabledValues = value.filter((option) => {
1845
+ return option.disabled;
1846
+ });
1847
+ return disabledValues;
1848
+ }
1707
1849
  get displayPlaceholder() {
1708
1850
  const placeholder = this.store.state.placeholder;
1709
1851
  const hasValue = this.hasValue;
@@ -1722,10 +1864,12 @@ let MainInput = class MainInput extends Vue {
1722
1864
  const state = this.store.state;
1723
1865
  const isMultiple = state.multiple;
1724
1866
  const value = state.internalValue;
1725
- const hasOnlyOneValue = Array.isArray(value) && value.length === 1;
1867
+ const nbSelection = (Array.isArray(value) && value.length) || 0;
1868
+ const hasOnlyOneValue = nbSelection === 1;
1869
+ const hasOnlyDisabled = nbSelection <= this.disabledList.length;
1726
1870
  /* Should not display the clear action if there is only one selected
1727
1871
  * item in multiple (as this item has already its remove icon) */
1728
- return !isMultiple || !hasOnlyOneValue;
1872
+ return !isMultiple || !hasOnlyOneValue || !hasOnlyDisabled;
1729
1873
  }
1730
1874
  get clearedLabel() {
1731
1875
  const isMultiple = this.store.state.multiple;
@@ -1843,6 +1987,9 @@ let MainInput = class MainInput extends Vue {
1843
1987
  /* Check if there is enough space to display items like there are
1844
1988
  * currently shown */
1845
1989
  const el = this.$refs.selectedItems;
1990
+ if (!el) {
1991
+ return;
1992
+ }
1846
1993
  const parentEl = el.parentElement;
1847
1994
  if (!document.contains(parentEl)) {
1848
1995
  /* The element is currently not in DOM */
@@ -1941,7 +2088,7 @@ let MainInput = class MainInput extends Vue {
1941
2088
  click: () => this.$emit('item:click', item.id),
1942
2089
  } },
1943
2090
  h("span", { class: "selectic-input__selected-items__value" }, item.text),
1944
- !this.isDisabled && (h(Icon$1, { icon: "times", class: "selectic-input__selected-items__icon", store: this.store, on: {
2091
+ !this.isDisabled && !item.disabled && (h(Icon$1, { icon: "times", class: "selectic-input__selected-items__icon", store: this.store, on: {
1945
2092
  'click.prevent.stop': () => this.selectItem(item.id),
1946
2093
  } }))))),
1947
2094
  this.moreSelectedNb && (h("div", { class: "single-value more-items", title: this.moreSelectedTitle }, this.moreSelectedNb)))),
@@ -2695,7 +2842,8 @@ let Selectic = class Selectic extends Vue {
2695
2842
  const store = this.store;
2696
2843
  const keepOpenWithOtherSelectic = this.params.keepOpenWithOtherSelectic;
2697
2844
  const extendedList = this.$refs.extendedList;
2698
- if (!extendedList) {
2845
+ const extendedListEl = extendedList === null || extendedList === void 0 ? void 0 : extendedList.$el;
2846
+ if (!extendedListEl) {
2699
2847
  /* this component is not focused anymore */
2700
2848
  if (!keepOpenWithOtherSelectic) {
2701
2849
  this.removeListeners();
@@ -2704,7 +2852,7 @@ let Selectic = class Selectic extends Vue {
2704
2852
  return;
2705
2853
  }
2706
2854
  const target = evt.target;
2707
- if (!extendedList.$el.contains(target) && !this.$el.contains(target)) {
2855
+ if (!extendedListEl.contains(target) && !this.$el.contains(target)) {
2708
2856
  store.commit('isOpen', false);
2709
2857
  }
2710
2858
  };
@@ -2797,14 +2945,23 @@ let Selectic = class Selectic extends Vue {
2797
2945
  /* }}} */
2798
2946
  /* {{{ private methods */
2799
2947
  computeWidth() {
2800
- const el = this.$refs.mainInput.$el;
2801
- this.width = el.offsetWidth;
2948
+ var _a;
2949
+ const mainInput = (_a = this.$refs) === null || _a === void 0 ? void 0 : _a.mainInput;
2950
+ const mainEl = mainInput === null || mainInput === void 0 ? void 0 : mainInput.$el;
2951
+ if (!mainEl) {
2952
+ /* This method has been called too soon (before render function)
2953
+ * or too late (after unmount) */
2954
+ return;
2955
+ }
2956
+ this.width = mainEl.offsetWidth;
2802
2957
  }
2803
2958
  computeOffset(doNotAddListener = false) {
2804
- const mainInput = this.$refs.mainInput;
2959
+ var _a;
2960
+ const mainInput = (_a = this.$refs) === null || _a === void 0 ? void 0 : _a.mainInput;
2805
2961
  const mainEl = mainInput === null || mainInput === void 0 ? void 0 : mainInput.$el;
2806
2962
  if (!mainEl) {
2807
- /* This method has been called too soon (before render function) */
2963
+ /* This method has been called too soon (before render function)
2964
+ * or too late (after unmount) */
2808
2965
  return;
2809
2966
  }
2810
2967
  const _elementsListeners = this._elementsListeners;
@@ -2938,13 +3095,14 @@ let Selectic = class Selectic extends Vue {
2938
3095
  checkFocus() {
2939
3096
  /* Await that focused element becomes active */
2940
3097
  setTimeout(() => {
3098
+ var _a;
2941
3099
  const focusedEl = document.activeElement;
2942
- const extendedList = this.$refs.extendedList;
3100
+ const extendedList = (_a = this.$refs) === null || _a === void 0 ? void 0 : _a.extendedList;
2943
3101
  /* check if there is a focused element (if none the body is
2944
3102
  * selected) and if it is inside current Selectic */
2945
3103
  if (focusedEl === document.body
2946
3104
  || this.$el.contains(focusedEl)
2947
- || (extendedList && extendedList.$el.contains(focusedEl))) {
3105
+ || (extendedList === null || extendedList === void 0 ? void 0 : extendedList.$el.contains(focusedEl))) {
2948
3106
  return;
2949
3107
  }
2950
3108
  this.store.commit('isOpen', false);
@@ -7,6 +7,14 @@ version which want to upgrade them to latest version.
7
7
 
8
8
  **This is not something you have to read to understand and to use Selectic.**
9
9
 
10
+ ## 3.0.x → 3.1.x
11
+
12
+ Selectic no more depends on Font-awesome. It embeds its own icons (from Material Design Icons).
13
+
14
+ It is still possible to use Font-awesome icons (or from any other libraries).
15
+
16
+ Read [the documentation section related to changing icons](./changeIcons.md) for more information on how to handle them.
17
+
10
18
  ## 1.3.x → 3.x
11
19
 
12
20
  ### Vue2 → Vue3
@@ -5,10 +5,10 @@
5
5
  There are some icons in selectic. But sometimes it is useful to change them (because you want to use yours or the same of your favorite theme).
6
6
 
7
7
  There are 3 ways to changes these icons:
8
- * Call the static `changeIcons()` method. It changes icons for all selectic components.
8
+ * Call the static `changeIcons(icons, iconFamily)` method. It changes icons for all selectic components.
9
9
  * Change the `icons` property. It changes icons only for the component.
10
10
  * Change the `iconFamily` property. It changes the icons origin only for the component.
11
- * Call the `changeIcons()` method on the component. It changes icons only for the component.
11
+ * Call the `changeIcons(icons, iconFamily)` method on the component. It changes icons only for the component.
12
12
 
13
13
  _Changes made locally take precedence over changes made globally_.
14
14
 
@@ -116,3 +116,9 @@ this.$refs.selectic.changeIcons({
116
116
  * <span class="fa fa-thumbs-o-up"></span>
117
117
  */
118
118
  ```
119
+
120
+ It is possible to change only the icon family:
121
+ ```javascript
122
+ // change icons for all selectic components to use FA-6 icons
123
+ Selectic.changeIcons(null, 'font-awesome-6');
124
+ ```