selectic 3.1.4 → 3.2.0
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.
- package/dist/selectic.common.js +99 -33
- package/dist/selectic.esm.js +99 -33
- package/package.json +3 -3
- package/src/Icon.tsx +3 -0
- package/src/List.tsx +9 -3
- package/src/Store.tsx +3 -2
- package/src/css/selectic.css +19 -0
- package/src/icons/dot.tsx +17 -0
- package/src/index.tsx +1 -1
- package/src/tools.ts +85 -23
- package/test/Tools/tools.spec.js +151 -0
- package/types/List.d.ts +1 -1
- package/types/Store.d.ts +1 -1
- package/types/icons/dot.d.ts +6 -0
- package/types/tools.d.ts +10 -4
package/dist/selectic.common.js
CHANGED
|
@@ -32,7 +32,7 @@ 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 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";
|
|
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\n.selectic .has-feedback {\n position: relative;\n}\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\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\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\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\n.selectic__extended-list.selectic-position-top {\n box-shadow: 2px -3px 12px 0px #888888;\n}\n\n.selectic__extended-list__list-container{\n overflow: auto;\n}\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\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__active:not(.selected) .single-select_icon {\n opacity: 0;\n}\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\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\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\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\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\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";
|
|
36
36
|
styleInject(css_248z);
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -111,32 +111,76 @@ function assignObject(obj, ...sourceObjects) {
|
|
|
111
111
|
}
|
|
112
112
|
return result;
|
|
113
113
|
}
|
|
114
|
-
/**
|
|
115
|
-
*
|
|
114
|
+
/**
|
|
115
|
+
* Ckeck whether a value is primitive.
|
|
116
|
+
* @returns true if val is primitive and false otherwise.
|
|
116
117
|
*/
|
|
117
|
-
function
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
function isPrimitive(val) {
|
|
119
|
+
/* The value null is treated explicitly because in JavaScript
|
|
120
|
+
* `typeof null === 'object'` is evaluated to `true`.
|
|
121
|
+
*/
|
|
122
|
+
return val === null || (typeof val !== 'object' && typeof val !== 'function');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Performs a deep comparison between two objects to determine if they
|
|
126
|
+
* should be considered equal.
|
|
127
|
+
*
|
|
128
|
+
* @param objA object to compare to objB.
|
|
129
|
+
* @param objB object to compare to objA.
|
|
130
|
+
* @param attributes list of attributes to not compare.
|
|
131
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
132
|
+
* @returns true if objA should be considered equal to objB.
|
|
133
|
+
*/
|
|
134
|
+
function isDeepEqual(objA, objB, ignoreAttributes = [], refs = new WeakMap()) {
|
|
135
|
+
objA = vue.unref(objA);
|
|
136
|
+
objB = vue.unref(objB);
|
|
137
|
+
/* For primitive types */
|
|
138
|
+
if (isPrimitive(objA)) {
|
|
139
|
+
return isPrimitive(objB) && Object.is(objA, objB);
|
|
140
|
+
}
|
|
141
|
+
/* For functions (follow the behavior of _.isEqual and compare functions
|
|
142
|
+
* by reference). */
|
|
143
|
+
if (typeof objA === 'function') {
|
|
144
|
+
return typeof objB === 'function' && objA === objB;
|
|
145
|
+
}
|
|
146
|
+
/* For circular references */
|
|
147
|
+
if (refs.has(objA)) {
|
|
148
|
+
return refs.get(objA) === objB;
|
|
149
|
+
}
|
|
150
|
+
refs.set(objA, objB);
|
|
151
|
+
/* For objects */
|
|
152
|
+
if (typeof objA === 'object') {
|
|
153
|
+
if (typeof objB !== 'object') {
|
|
125
154
|
return false;
|
|
126
155
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
156
|
+
/* For arrays */
|
|
157
|
+
if (Array.isArray(objA)) {
|
|
158
|
+
return Array.isArray(objB) &&
|
|
159
|
+
objA.length === objB.length &&
|
|
160
|
+
!objA.some((val, idx) => !isDeepEqual(val, objB[idx], ignoreAttributes, refs));
|
|
161
|
+
}
|
|
162
|
+
/* For RegExp */
|
|
163
|
+
if (objA instanceof RegExp) {
|
|
164
|
+
return objB instanceof RegExp &&
|
|
165
|
+
objA.source === objB.source &&
|
|
166
|
+
objA.flags === objB.flags;
|
|
167
|
+
}
|
|
168
|
+
/* For Date */
|
|
169
|
+
if (objA instanceof Date) {
|
|
170
|
+
return objB instanceof Date && objA.getTime() === objB.getTime();
|
|
171
|
+
}
|
|
172
|
+
/* This should be an object */
|
|
173
|
+
const aRec = objA;
|
|
174
|
+
const bRec = objB;
|
|
175
|
+
const aKeys = Object.keys(aRec).filter((key) => !ignoreAttributes.includes(key));
|
|
176
|
+
const bKeys = Object.keys(bRec).filter((key) => !ignoreAttributes.includes(key));
|
|
177
|
+
const differentKeyFound = aKeys.some((key) => {
|
|
178
|
+
return !bKeys.includes(key) ||
|
|
179
|
+
!isDeepEqual(aRec[key], bRec[key], ignoreAttributes, refs);
|
|
138
180
|
});
|
|
139
|
-
|
|
181
|
+
return aKeys.length === bKeys.length && !differentKeyFound;
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
140
184
|
}
|
|
141
185
|
let displayLog = false;
|
|
142
186
|
function debug(fName, step, ...args) {
|
|
@@ -1190,7 +1234,7 @@ class SelecticStore {
|
|
|
1190
1234
|
/* update cache */
|
|
1191
1235
|
state.totalDynOptions = total;
|
|
1192
1236
|
const old = state.dynOptions.splice(offset, result.length, ...result);
|
|
1193
|
-
if (
|
|
1237
|
+
if (isDeepEqual(old, result)) {
|
|
1194
1238
|
/* Added options are the same as previous ones.
|
|
1195
1239
|
* Stop fetching to avoid infinite loop
|
|
1196
1240
|
*/
|
|
@@ -1493,7 +1537,7 @@ class SelecticStore {
|
|
|
1493
1537
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1494
1538
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1495
1539
|
*/
|
|
1496
|
-
var __decorate$
|
|
1540
|
+
var __decorate$e = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1497
1541
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1498
1542
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1499
1543
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1505,7 +1549,7 @@ let IconCaretDown = class IconCaretDown extends vtyx.Vue {
|
|
|
1505
1549
|
vtyx.h("path", { d: "M7,10L12,15L17,10H7Z" })));
|
|
1506
1550
|
}
|
|
1507
1551
|
};
|
|
1508
|
-
IconCaretDown = __decorate$
|
|
1552
|
+
IconCaretDown = __decorate$e([
|
|
1509
1553
|
vtyx.Component
|
|
1510
1554
|
], IconCaretDown);
|
|
1511
1555
|
var IconCaretDown$1 = IconCaretDown;
|
|
@@ -1513,7 +1557,7 @@ var IconCaretDown$1 = IconCaretDown;
|
|
|
1513
1557
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1514
1558
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1515
1559
|
*/
|
|
1516
|
-
var __decorate$
|
|
1560
|
+
var __decorate$d = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1517
1561
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1518
1562
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1519
1563
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1525,7 +1569,7 @@ let IconCaretUp = class IconCaretUp extends vtyx.Vue {
|
|
|
1525
1569
|
vtyx.h("path", { d: "M7,15L12,10L17,15H7Z" })));
|
|
1526
1570
|
}
|
|
1527
1571
|
};
|
|
1528
|
-
IconCaretUp = __decorate$
|
|
1572
|
+
IconCaretUp = __decorate$d([
|
|
1529
1573
|
vtyx.Component
|
|
1530
1574
|
], IconCaretUp);
|
|
1531
1575
|
var IconCaretUp$1 = IconCaretUp;
|
|
@@ -1533,7 +1577,7 @@ var IconCaretUp$1 = IconCaretUp;
|
|
|
1533
1577
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1534
1578
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1535
1579
|
*/
|
|
1536
|
-
var __decorate$
|
|
1580
|
+
var __decorate$c = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1537
1581
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1538
1582
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1539
1583
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1545,11 +1589,28 @@ let IconCheck = class IconCheck extends vtyx.Vue {
|
|
|
1545
1589
|
vtyx.h("path", { d: "M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z" })));
|
|
1546
1590
|
}
|
|
1547
1591
|
};
|
|
1548
|
-
IconCheck = __decorate$
|
|
1592
|
+
IconCheck = __decorate$c([
|
|
1549
1593
|
vtyx.Component
|
|
1550
1594
|
], IconCheck);
|
|
1551
1595
|
var IconCheck$1 = IconCheck;
|
|
1552
1596
|
|
|
1597
|
+
var __decorate$b = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1598
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1599
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1600
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1601
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1602
|
+
};
|
|
1603
|
+
let IconDot = class IconDot extends vtyx.Vue {
|
|
1604
|
+
render() {
|
|
1605
|
+
return (vtyx.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24" },
|
|
1606
|
+
vtyx.h("circle", { cx: "8", cy: "16", r: "3.5" })));
|
|
1607
|
+
}
|
|
1608
|
+
};
|
|
1609
|
+
IconDot = __decorate$b([
|
|
1610
|
+
vtyx.Component
|
|
1611
|
+
], IconDot);
|
|
1612
|
+
var IconDot$1 = IconDot;
|
|
1613
|
+
|
|
1553
1614
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1554
1615
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1555
1616
|
*/
|
|
@@ -1698,6 +1759,8 @@ let Icon = class Icon extends vtyx.Vue {
|
|
|
1698
1759
|
return IconCaretUp$1;
|
|
1699
1760
|
case 'check':
|
|
1700
1761
|
return IconCheck$1;
|
|
1762
|
+
case 'dot':
|
|
1763
|
+
return IconDot$1;
|
|
1701
1764
|
case 'search':
|
|
1702
1765
|
return IconSearch$1;
|
|
1703
1766
|
case 'spinner':
|
|
@@ -2452,8 +2515,10 @@ let List = class List extends vtyx.Vue {
|
|
|
2452
2515
|
onOffsetChange() {
|
|
2453
2516
|
this.checkOffset();
|
|
2454
2517
|
}
|
|
2455
|
-
onFilteredOptionsChange() {
|
|
2456
|
-
|
|
2518
|
+
onFilteredOptionsChange(oldVal, newVal) {
|
|
2519
|
+
if (!isDeepEqual(oldVal, newVal)) {
|
|
2520
|
+
this.checkOffset();
|
|
2521
|
+
}
|
|
2457
2522
|
}
|
|
2458
2523
|
onGroupIdChange() {
|
|
2459
2524
|
this.$emit('groupId', this.groupId);
|
|
@@ -2483,6 +2548,7 @@ let List = class List extends vtyx.Vue {
|
|
|
2483
2548
|
'selectic-item__is-group': option.isGroup,
|
|
2484
2549
|
}], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
|
|
2485
2550
|
this.isMultiple && (vtyx.h(Icon$1, { icon: "check", store: this.store, class: "selectic-item_icon" })),
|
|
2551
|
+
!this.isMultiple && (vtyx.h(Icon$1, { icon: "dot", store: this.store, class: "selectic-item_icon single-select_icon" })),
|
|
2486
2552
|
option.icon && (option.icon.includes(':')
|
|
2487
2553
|
? vtyx.h(Icon$1, { icon: option.icon, store: this.store })
|
|
2488
2554
|
: vtyx.h(Icon$1, { icon: `raw:${option.icon}`, store: this.store })),
|
|
@@ -3013,7 +3079,7 @@ let Selectic = class Selectic extends vtyx.Vue {
|
|
|
3013
3079
|
else {
|
|
3014
3080
|
this.removeListeners();
|
|
3015
3081
|
if (state.status.hasChanged) {
|
|
3016
|
-
this
|
|
3082
|
+
this.emit('change', this.getValue(), state.selectionIsExcluded);
|
|
3017
3083
|
this.store.resetChange();
|
|
3018
3084
|
}
|
|
3019
3085
|
this.emit('close');
|
package/dist/selectic.esm.js
CHANGED
|
@@ -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.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";
|
|
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\n.selectic .has-feedback {\n position: relative;\n}\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\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\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\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\n.selectic__extended-list.selectic-position-top {\n box-shadow: 2px -3px 12px 0px #888888;\n}\n\n.selectic__extended-list__list-container{\n overflow: auto;\n}\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\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__active:not(.selected) .single-select_icon {\n opacity: 0;\n}\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\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\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\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\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\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
|
/**
|
|
@@ -107,32 +107,76 @@ function assignObject(obj, ...sourceObjects) {
|
|
|
107
107
|
}
|
|
108
108
|
return result;
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
111
|
-
*
|
|
110
|
+
/**
|
|
111
|
+
* Ckeck whether a value is primitive.
|
|
112
|
+
* @returns true if val is primitive and false otherwise.
|
|
112
113
|
*/
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
function isPrimitive(val) {
|
|
115
|
+
/* The value null is treated explicitly because in JavaScript
|
|
116
|
+
* `typeof null === 'object'` is evaluated to `true`.
|
|
117
|
+
*/
|
|
118
|
+
return val === null || (typeof val !== 'object' && typeof val !== 'function');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Performs a deep comparison between two objects to determine if they
|
|
122
|
+
* should be considered equal.
|
|
123
|
+
*
|
|
124
|
+
* @param objA object to compare to objB.
|
|
125
|
+
* @param objB object to compare to objA.
|
|
126
|
+
* @param attributes list of attributes to not compare.
|
|
127
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
128
|
+
* @returns true if objA should be considered equal to objB.
|
|
129
|
+
*/
|
|
130
|
+
function isDeepEqual(objA, objB, ignoreAttributes = [], refs = new WeakMap()) {
|
|
131
|
+
objA = unref(objA);
|
|
132
|
+
objB = unref(objB);
|
|
133
|
+
/* For primitive types */
|
|
134
|
+
if (isPrimitive(objA)) {
|
|
135
|
+
return isPrimitive(objB) && Object.is(objA, objB);
|
|
136
|
+
}
|
|
137
|
+
/* For functions (follow the behavior of _.isEqual and compare functions
|
|
138
|
+
* by reference). */
|
|
139
|
+
if (typeof objA === 'function') {
|
|
140
|
+
return typeof objB === 'function' && objA === objB;
|
|
141
|
+
}
|
|
142
|
+
/* For circular references */
|
|
143
|
+
if (refs.has(objA)) {
|
|
144
|
+
return refs.get(objA) === objB;
|
|
145
|
+
}
|
|
146
|
+
refs.set(objA, objB);
|
|
147
|
+
/* For objects */
|
|
148
|
+
if (typeof objA === 'object') {
|
|
149
|
+
if (typeof objB !== 'object') {
|
|
121
150
|
return false;
|
|
122
151
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
152
|
+
/* For arrays */
|
|
153
|
+
if (Array.isArray(objA)) {
|
|
154
|
+
return Array.isArray(objB) &&
|
|
155
|
+
objA.length === objB.length &&
|
|
156
|
+
!objA.some((val, idx) => !isDeepEqual(val, objB[idx], ignoreAttributes, refs));
|
|
157
|
+
}
|
|
158
|
+
/* For RegExp */
|
|
159
|
+
if (objA instanceof RegExp) {
|
|
160
|
+
return objB instanceof RegExp &&
|
|
161
|
+
objA.source === objB.source &&
|
|
162
|
+
objA.flags === objB.flags;
|
|
163
|
+
}
|
|
164
|
+
/* For Date */
|
|
165
|
+
if (objA instanceof Date) {
|
|
166
|
+
return objB instanceof Date && objA.getTime() === objB.getTime();
|
|
167
|
+
}
|
|
168
|
+
/* This should be an object */
|
|
169
|
+
const aRec = objA;
|
|
170
|
+
const bRec = objB;
|
|
171
|
+
const aKeys = Object.keys(aRec).filter((key) => !ignoreAttributes.includes(key));
|
|
172
|
+
const bKeys = Object.keys(bRec).filter((key) => !ignoreAttributes.includes(key));
|
|
173
|
+
const differentKeyFound = aKeys.some((key) => {
|
|
174
|
+
return !bKeys.includes(key) ||
|
|
175
|
+
!isDeepEqual(aRec[key], bRec[key], ignoreAttributes, refs);
|
|
134
176
|
});
|
|
135
|
-
|
|
177
|
+
return aKeys.length === bKeys.length && !differentKeyFound;
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
136
180
|
}
|
|
137
181
|
let displayLog = false;
|
|
138
182
|
function debug(fName, step, ...args) {
|
|
@@ -1186,7 +1230,7 @@ class SelecticStore {
|
|
|
1186
1230
|
/* update cache */
|
|
1187
1231
|
state.totalDynOptions = total;
|
|
1188
1232
|
const old = state.dynOptions.splice(offset, result.length, ...result);
|
|
1189
|
-
if (
|
|
1233
|
+
if (isDeepEqual(old, result)) {
|
|
1190
1234
|
/* Added options are the same as previous ones.
|
|
1191
1235
|
* Stop fetching to avoid infinite loop
|
|
1192
1236
|
*/
|
|
@@ -1489,7 +1533,7 @@ class SelecticStore {
|
|
|
1489
1533
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1490
1534
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1491
1535
|
*/
|
|
1492
|
-
var __decorate$
|
|
1536
|
+
var __decorate$e = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1493
1537
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1494
1538
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1495
1539
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1501,7 +1545,7 @@ let IconCaretDown = class IconCaretDown extends Vue {
|
|
|
1501
1545
|
h("path", { d: "M7,10L12,15L17,10H7Z" })));
|
|
1502
1546
|
}
|
|
1503
1547
|
};
|
|
1504
|
-
IconCaretDown = __decorate$
|
|
1548
|
+
IconCaretDown = __decorate$e([
|
|
1505
1549
|
Component
|
|
1506
1550
|
], IconCaretDown);
|
|
1507
1551
|
var IconCaretDown$1 = IconCaretDown;
|
|
@@ -1509,7 +1553,7 @@ var IconCaretDown$1 = IconCaretDown;
|
|
|
1509
1553
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1510
1554
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1511
1555
|
*/
|
|
1512
|
-
var __decorate$
|
|
1556
|
+
var __decorate$d = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1513
1557
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1514
1558
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1515
1559
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1521,7 +1565,7 @@ let IconCaretUp = class IconCaretUp extends Vue {
|
|
|
1521
1565
|
h("path", { d: "M7,15L12,10L17,15H7Z" })));
|
|
1522
1566
|
}
|
|
1523
1567
|
};
|
|
1524
|
-
IconCaretUp = __decorate$
|
|
1568
|
+
IconCaretUp = __decorate$d([
|
|
1525
1569
|
Component
|
|
1526
1570
|
], IconCaretUp);
|
|
1527
1571
|
var IconCaretUp$1 = IconCaretUp;
|
|
@@ -1529,7 +1573,7 @@ var IconCaretUp$1 = IconCaretUp;
|
|
|
1529
1573
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1530
1574
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1531
1575
|
*/
|
|
1532
|
-
var __decorate$
|
|
1576
|
+
var __decorate$c = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1533
1577
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1534
1578
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1535
1579
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1541,11 +1585,28 @@ let IconCheck = class IconCheck extends Vue {
|
|
|
1541
1585
|
h("path", { d: "M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z" })));
|
|
1542
1586
|
}
|
|
1543
1587
|
};
|
|
1544
|
-
IconCheck = __decorate$
|
|
1588
|
+
IconCheck = __decorate$c([
|
|
1545
1589
|
Component
|
|
1546
1590
|
], IconCheck);
|
|
1547
1591
|
var IconCheck$1 = IconCheck;
|
|
1548
1592
|
|
|
1593
|
+
var __decorate$b = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
1594
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1595
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1596
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1597
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1598
|
+
};
|
|
1599
|
+
let IconDot = class IconDot extends Vue {
|
|
1600
|
+
render() {
|
|
1601
|
+
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24" },
|
|
1602
|
+
h("circle", { cx: "8", cy: "16", r: "3.5" })));
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
IconDot = __decorate$b([
|
|
1606
|
+
Component
|
|
1607
|
+
], IconDot);
|
|
1608
|
+
var IconDot$1 = IconDot;
|
|
1609
|
+
|
|
1549
1610
|
/* This icon is from <https://github.com/Templarian/MaterialDesign>,
|
|
1550
1611
|
* distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license
|
|
1551
1612
|
*/
|
|
@@ -1694,6 +1755,8 @@ let Icon = class Icon extends Vue {
|
|
|
1694
1755
|
return IconCaretUp$1;
|
|
1695
1756
|
case 'check':
|
|
1696
1757
|
return IconCheck$1;
|
|
1758
|
+
case 'dot':
|
|
1759
|
+
return IconDot$1;
|
|
1697
1760
|
case 'search':
|
|
1698
1761
|
return IconSearch$1;
|
|
1699
1762
|
case 'spinner':
|
|
@@ -2448,8 +2511,10 @@ let List = class List extends Vue {
|
|
|
2448
2511
|
onOffsetChange() {
|
|
2449
2512
|
this.checkOffset();
|
|
2450
2513
|
}
|
|
2451
|
-
onFilteredOptionsChange() {
|
|
2452
|
-
|
|
2514
|
+
onFilteredOptionsChange(oldVal, newVal) {
|
|
2515
|
+
if (!isDeepEqual(oldVal, newVal)) {
|
|
2516
|
+
this.checkOffset();
|
|
2517
|
+
}
|
|
2453
2518
|
}
|
|
2454
2519
|
onGroupIdChange() {
|
|
2455
2520
|
this.$emit('groupId', this.groupId);
|
|
@@ -2479,6 +2544,7 @@ let List = class List extends Vue {
|
|
|
2479
2544
|
'selectic-item__is-group': option.isGroup,
|
|
2480
2545
|
}], style: option.style, title: option.title, key: 'selectic-item-' + (idx + this.startIndex) },
|
|
2481
2546
|
this.isMultiple && (h(Icon$1, { icon: "check", store: this.store, class: "selectic-item_icon" })),
|
|
2547
|
+
!this.isMultiple && (h(Icon$1, { icon: "dot", store: this.store, class: "selectic-item_icon single-select_icon" })),
|
|
2482
2548
|
option.icon && (option.icon.includes(':')
|
|
2483
2549
|
? h(Icon$1, { icon: option.icon, store: this.store })
|
|
2484
2550
|
: h(Icon$1, { icon: `raw:${option.icon}`, store: this.store })),
|
|
@@ -3009,7 +3075,7 @@ let Selectic = class Selectic extends Vue {
|
|
|
3009
3075
|
else {
|
|
3010
3076
|
this.removeListeners();
|
|
3011
3077
|
if (state.status.hasChanged) {
|
|
3012
|
-
this
|
|
3078
|
+
this.emit('change', this.getValue(), state.selectionIsExcluded);
|
|
3013
3079
|
this.store.resetChange();
|
|
3014
3080
|
}
|
|
3015
3081
|
this.emit('close');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "selectic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Smart Select for VueJS 3.x",
|
|
5
5
|
"main": "dist/selectic.common.js",
|
|
6
6
|
"module": "dist/selectic.esm.js",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"vtyx": "4.2.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@babel/types": "^7.
|
|
46
|
-
"rollup": "^2.79.
|
|
45
|
+
"@babel/types": "^7.28.1",
|
|
46
|
+
"rollup": "^2.79.2",
|
|
47
47
|
"rollup-plugin-postcss": "^4.0.2",
|
|
48
48
|
"tape": "^4.17.0",
|
|
49
49
|
"typescript": "~4.8"
|
package/src/Icon.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import Store, { IconFamily, IconKey, IconValue } from './Store';
|
|
|
8
8
|
import IconCaretDown from './icons/caret-down';
|
|
9
9
|
import IconCaretUp from './icons/caret-up';
|
|
10
10
|
import IconCheck from './icons/check';
|
|
11
|
+
import IconDot from './icons/dot';
|
|
11
12
|
import IconQuestion from './icons/question';
|
|
12
13
|
import IconSearch from './icons/search';
|
|
13
14
|
import IconSpinner from './icons/spinner';
|
|
@@ -87,6 +88,8 @@ export default class Icon extends Vue<Props> {
|
|
|
87
88
|
return IconCaretUp;
|
|
88
89
|
case 'check':
|
|
89
90
|
return IconCheck;
|
|
91
|
+
case 'dot':
|
|
92
|
+
return IconDot;
|
|
90
93
|
case 'search':
|
|
91
94
|
return IconSearch;
|
|
92
95
|
case 'spinner':
|
package/src/List.tsx
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* It handles interactions with these items.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {Vue, Component, Prop, Watch, h} from 'vtyx';
|
|
6
|
+
import { Vue, Component, Prop, Watch, h } from 'vtyx';
|
|
7
7
|
import { unref } from 'vue';
|
|
8
8
|
|
|
9
9
|
import Store, {
|
|
@@ -11,6 +11,7 @@ import Store, {
|
|
|
11
11
|
OptionId,
|
|
12
12
|
} from './Store';
|
|
13
13
|
import Icon from './Icon';
|
|
14
|
+
import { isDeepEqual } from './tools';
|
|
14
15
|
|
|
15
16
|
export interface Props {
|
|
16
17
|
store: Store;
|
|
@@ -222,8 +223,10 @@ export default class List extends Vue<Props> {
|
|
|
222
223
|
}
|
|
223
224
|
|
|
224
225
|
@Watch('filteredOptions', { deep: true })
|
|
225
|
-
public onFilteredOptionsChange() {
|
|
226
|
-
|
|
226
|
+
public onFilteredOptionsChange(oldVal: OptionItem[], newVal: OptionItem[]) {
|
|
227
|
+
if (!isDeepEqual(oldVal, newVal)) {
|
|
228
|
+
this.checkOffset();
|
|
229
|
+
}
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
@Watch('groupId')
|
|
@@ -280,6 +283,9 @@ export default class List extends Vue<Props> {
|
|
|
280
283
|
{this.isMultiple && (
|
|
281
284
|
<Icon icon="check" store={this.store} class="selectic-item_icon" />
|
|
282
285
|
)}
|
|
286
|
+
{!this.isMultiple && (
|
|
287
|
+
<Icon icon="dot" store={this.store} class="selectic-item_icon single-select_icon" />
|
|
288
|
+
)}
|
|
283
289
|
{option.icon && (
|
|
284
290
|
option.icon.includes(':')
|
|
285
291
|
? <Icon icon={option.icon} store={this.store} />
|
package/src/Store.tsx
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { reactive, watch, unref, computed, ComputedRef } from 'vue';
|
|
8
8
|
import {
|
|
9
9
|
assignObject,
|
|
10
|
-
|
|
10
|
+
isDeepEqual,
|
|
11
11
|
convertToRegExp,
|
|
12
12
|
debug,
|
|
13
13
|
deepClone,
|
|
@@ -378,6 +378,7 @@ export type IconKey =
|
|
|
378
378
|
| 'caret-down'
|
|
379
379
|
| 'caret-up'
|
|
380
380
|
| 'check'
|
|
381
|
+
| 'dot'
|
|
381
382
|
| 'search'
|
|
382
383
|
| 'spinner'
|
|
383
384
|
| 'strikethrough'
|
|
@@ -1704,7 +1705,7 @@ export default class SelecticStore {
|
|
|
1704
1705
|
state.totalDynOptions = total;
|
|
1705
1706
|
const old = state.dynOptions.splice(offset, result.length, ...result);
|
|
1706
1707
|
|
|
1707
|
-
if (
|
|
1708
|
+
if (isDeepEqual(old, result)) {
|
|
1708
1709
|
/* Added options are the same as previous ones.
|
|
1709
1710
|
* Stop fetching to avoid infinite loop
|
|
1710
1711
|
*/
|
package/src/css/selectic.css
CHANGED
|
@@ -60,9 +60,11 @@
|
|
|
60
60
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
|
61
61
|
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
|
62
62
|
}
|
|
63
|
+
|
|
63
64
|
.selectic .has-feedback {
|
|
64
65
|
position: relative;
|
|
65
66
|
}
|
|
67
|
+
|
|
66
68
|
.selectic .has-feedback .form-control {
|
|
67
69
|
padding-right: calc(var(--selectic-input-height) + 4px);
|
|
68
70
|
}
|
|
@@ -141,11 +143,13 @@
|
|
|
141
143
|
margin-right: 3px;
|
|
142
144
|
cursor: default;
|
|
143
145
|
}
|
|
146
|
+
|
|
144
147
|
.selectic-input__clear-icon {
|
|
145
148
|
align-self: center;
|
|
146
149
|
margin-left: 3px;
|
|
147
150
|
cursor: pointer;
|
|
148
151
|
}
|
|
152
|
+
|
|
149
153
|
.selectic-input__clear-icon:hover {
|
|
150
154
|
color: var(--selectic-selected-item-color);
|
|
151
155
|
}
|
|
@@ -159,6 +163,7 @@
|
|
|
159
163
|
cursor: var(--selectic-cursor-disabled);
|
|
160
164
|
background-color: var(--selectic-bg-disabled);
|
|
161
165
|
}
|
|
166
|
+
|
|
162
167
|
.selectic-input.disabled .more-items {
|
|
163
168
|
background-color: var(--selectic-more-items-bg-disabled);
|
|
164
169
|
}
|
|
@@ -197,12 +202,15 @@
|
|
|
197
202
|
display: grid;
|
|
198
203
|
grid-template-rows: minmax(0, max-content) 1fr;
|
|
199
204
|
}
|
|
205
|
+
|
|
200
206
|
.selectic__extended-list.selectic-position-top {
|
|
201
207
|
box-shadow: 2px -3px 12px 0px #888888;
|
|
202
208
|
}
|
|
209
|
+
|
|
203
210
|
.selectic__extended-list__list-container{
|
|
204
211
|
overflow: auto;
|
|
205
212
|
}
|
|
213
|
+
|
|
206
214
|
.selectic__extended-list__list-items {
|
|
207
215
|
max-height: calc(var(--selectic-input-height) * 10);
|
|
208
216
|
min-width: max-content;
|
|
@@ -241,9 +249,15 @@
|
|
|
241
249
|
background-color: var(--selectic-active-item-bg);
|
|
242
250
|
color: var(--selectic-active-item-color);
|
|
243
251
|
}
|
|
252
|
+
|
|
244
253
|
.selectic-item__active:not(.selected) .selectic-item_icon {
|
|
245
254
|
opacity: 0.2;
|
|
246
255
|
}
|
|
256
|
+
|
|
257
|
+
.selectic-item__active:not(.selected) .single-select_icon {
|
|
258
|
+
opacity: 0;
|
|
259
|
+
}
|
|
260
|
+
|
|
247
261
|
.selectic-item__active.selectic-item__disabled:not(.selected) .selectic-item_icon {
|
|
248
262
|
opacity: 0;
|
|
249
263
|
}
|
|
@@ -269,11 +283,13 @@
|
|
|
269
283
|
.selectic-item.selected {
|
|
270
284
|
color: var(--selectic-selected-item-color);
|
|
271
285
|
}
|
|
286
|
+
|
|
272
287
|
.selectic-search-scope {
|
|
273
288
|
color: #e0e0e0;
|
|
274
289
|
left: auto;
|
|
275
290
|
right: 10px;
|
|
276
291
|
}
|
|
292
|
+
|
|
277
293
|
.selectic .form-control-feedback.fa.selectic-search-scope {
|
|
278
294
|
width: calc(var(--selectic-input-height) * 0.75);
|
|
279
295
|
height: calc(var(--selectic-input-height) * 0.75);
|
|
@@ -311,6 +327,7 @@
|
|
|
311
327
|
padding-bottom: 10px;
|
|
312
328
|
margin-bottom: 0px;
|
|
313
329
|
}
|
|
330
|
+
|
|
314
331
|
.selectic .filter-input {
|
|
315
332
|
height: calc(var(--selectic-input-height) * 0.75);
|
|
316
333
|
}
|
|
@@ -375,6 +392,7 @@
|
|
|
375
392
|
color: var(--selectic-more-items-color, var(--selectic-info-color));
|
|
376
393
|
cursor: help;
|
|
377
394
|
}
|
|
395
|
+
|
|
378
396
|
.selectic-input__selected-items__value {
|
|
379
397
|
grid-area: value;
|
|
380
398
|
align-self: center;
|
|
@@ -390,6 +408,7 @@
|
|
|
390
408
|
justify-self: center;
|
|
391
409
|
margin-left: 5px;
|
|
392
410
|
}
|
|
411
|
+
|
|
393
412
|
.selectic-input__selected-items__icon:hover {
|
|
394
413
|
color: var(--selectic-selected-item-color);
|
|
395
414
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {Vue, Component, h} from 'vtyx';
|
|
2
|
+
|
|
3
|
+
export interface Props {}
|
|
4
|
+
|
|
5
|
+
@Component
|
|
6
|
+
export default class IconDot extends Vue<Props> {
|
|
7
|
+
public render() {
|
|
8
|
+
return (
|
|
9
|
+
<svg
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
viewBox="0 0 24 24"
|
|
12
|
+
>
|
|
13
|
+
<circle cx="8" cy="16" r="3.5" />
|
|
14
|
+
</svg>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -560,7 +560,7 @@ export default class Selectic extends Vue<Props> {
|
|
|
560
560
|
} else {
|
|
561
561
|
this.removeListeners();
|
|
562
562
|
if (state.status.hasChanged) {
|
|
563
|
-
this
|
|
563
|
+
this.emit('change', this.getValue(), state.selectionIsExcluded);
|
|
564
564
|
this.store.resetChange();
|
|
565
565
|
}
|
|
566
566
|
this.emit('close');
|
package/src/tools.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { unref } from 'vue';
|
|
2
|
-
import { OptionValue } from './Store';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Clone the object and its inner properties.
|
|
@@ -8,7 +7,11 @@ import { OptionValue } from './Store';
|
|
|
8
7
|
* @param refs internal reference to object to avoid cyclic references
|
|
9
8
|
* @returns a copy of obj
|
|
10
9
|
*/
|
|
11
|
-
export function deepClone<T = any>(
|
|
10
|
+
export function deepClone<T = any>(
|
|
11
|
+
origObject: T,
|
|
12
|
+
ignoreAttributes: string[] = [],
|
|
13
|
+
refs: WeakMap<any, any> = new WeakMap()
|
|
14
|
+
): T {
|
|
12
15
|
const obj = unref(origObject);
|
|
13
16
|
|
|
14
17
|
/* For circular references */
|
|
@@ -88,34 +91,93 @@ export function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial
|
|
|
88
91
|
return result as T;
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
/**
|
|
92
|
-
*
|
|
94
|
+
/**
|
|
95
|
+
* Ckeck whether a value is primitive.
|
|
96
|
+
* @returns true if val is primitive and false otherwise.
|
|
97
|
+
*/
|
|
98
|
+
function isPrimitive<T = any>(val: T): boolean {
|
|
99
|
+
/* The value null is treated explicitly because in JavaScript
|
|
100
|
+
* `typeof null === 'object'` is evaluated to `true`.
|
|
101
|
+
*/
|
|
102
|
+
return val === null || (typeof val !== 'object' && typeof val !== 'function');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Performs a deep comparison between two objects to determine if they
|
|
107
|
+
* should be considered equal.
|
|
108
|
+
*
|
|
109
|
+
* @param objA object to compare to objB.
|
|
110
|
+
* @param objB object to compare to objA.
|
|
111
|
+
* @param attributes list of attributes to not compare.
|
|
112
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
113
|
+
* @returns true if objA should be considered equal to objB.
|
|
93
114
|
*/
|
|
94
|
-
export function
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
export function isDeepEqual<T = any>(
|
|
116
|
+
objA: T,
|
|
117
|
+
objB: T,
|
|
118
|
+
ignoreAttributes: string[] = [],
|
|
119
|
+
refs: WeakMap<any, any> = new WeakMap()
|
|
120
|
+
): boolean {
|
|
121
|
+
objA = unref(objA);
|
|
122
|
+
objB = unref(objB);
|
|
123
|
+
|
|
124
|
+
/* For primitive types */
|
|
125
|
+
if (isPrimitive(objA)) {
|
|
126
|
+
return isPrimitive(objB) && Object.is(objA, objB);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* For functions (follow the behavior of _.isEqual and compare functions
|
|
130
|
+
* by reference). */
|
|
131
|
+
if (typeof objA === 'function') {
|
|
132
|
+
return typeof objB === 'function' && objA === objB;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* For circular references */
|
|
136
|
+
if (refs.has(objA)) {
|
|
137
|
+
return refs.get(objA) === objB;
|
|
97
138
|
}
|
|
139
|
+
refs.set(objA, objB);
|
|
98
140
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (keys.length !== Object.keys(newOption).length) {
|
|
141
|
+
/* For objects */
|
|
142
|
+
if (typeof objA === 'object') {
|
|
143
|
+
if (typeof objB !== 'object') {
|
|
103
144
|
return false;
|
|
104
145
|
}
|
|
105
|
-
return keys.every((optionKey) => {
|
|
106
|
-
const key = optionKey as keyof OptionValue;
|
|
107
|
-
const oldValue = oldOption[key];
|
|
108
|
-
const newValue = newOption[key];
|
|
109
146
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
147
|
+
/* For arrays */
|
|
148
|
+
if (Array.isArray(objA)) {
|
|
149
|
+
return Array.isArray(objB) &&
|
|
150
|
+
objA.length === objB.length &&
|
|
151
|
+
!objA.some((val, idx) => !isDeepEqual(val, (objB as unknown[])[idx], ignoreAttributes, refs));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* For RegExp */
|
|
155
|
+
if (objA instanceof RegExp) {
|
|
156
|
+
return objB instanceof RegExp &&
|
|
157
|
+
objA.source === objB.source &&
|
|
158
|
+
objA.flags === objB.flags;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* For Date */
|
|
162
|
+
if (objA instanceof Date) {
|
|
163
|
+
return objB instanceof Date && objA.getTime() === objB.getTime();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* This should be an object */
|
|
167
|
+
const aRec = objA as Record<string, any>;
|
|
168
|
+
const bRec = objB as Record<string, any>;
|
|
169
|
+
const aKeys = Object.keys(aRec).filter((key) => !ignoreAttributes.includes(key));
|
|
170
|
+
const bKeys = Object.keys(bRec).filter((key) => !ignoreAttributes.includes(key));
|
|
171
|
+
|
|
172
|
+
const differentKeyFound = aKeys.some((key) => {
|
|
173
|
+
return !bKeys.includes(key) ||
|
|
174
|
+
!isDeepEqual(aRec[key], bRec[key], ignoreAttributes, refs);
|
|
117
175
|
});
|
|
118
|
-
|
|
176
|
+
|
|
177
|
+
return aKeys.length === bKeys.length && !differentKeyFound;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return true;
|
|
119
181
|
}
|
|
120
182
|
|
|
121
183
|
let displayLog = false;
|
package/test/Tools/tools.spec.js
CHANGED
|
@@ -5,6 +5,7 @@ const {
|
|
|
5
5
|
assignObject,
|
|
6
6
|
convertToRegExp,
|
|
7
7
|
deepClone,
|
|
8
|
+
isDeepEqual,
|
|
8
9
|
} = toolFile;
|
|
9
10
|
|
|
10
11
|
tape.test('assignObject()', (st) => {
|
|
@@ -402,3 +403,153 @@ tape.test('deepClone()', (st) => {
|
|
|
402
403
|
tst.end();
|
|
403
404
|
});
|
|
404
405
|
});
|
|
406
|
+
|
|
407
|
+
tape.test('isDeepEqual()', (st) => {
|
|
408
|
+
const fn = () => {};
|
|
409
|
+
const obj = {
|
|
410
|
+
a: 1,
|
|
411
|
+
b: 'b',
|
|
412
|
+
c: false,
|
|
413
|
+
d: undefined,
|
|
414
|
+
e: null,
|
|
415
|
+
f: {},
|
|
416
|
+
g: fn,
|
|
417
|
+
spe1: NaN,
|
|
418
|
+
spe2: Infinity,
|
|
419
|
+
spe3: '',
|
|
420
|
+
spe4: [],
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
st.test('should compare simple objects', (tst) => {
|
|
424
|
+
const objA = obj;
|
|
425
|
+
const objB = deepClone(obj);
|
|
426
|
+
|
|
427
|
+
tst.is(isDeepEqual(objB, objA), true, 'should be equal');
|
|
428
|
+
|
|
429
|
+
objB.a = objB.a.toString();
|
|
430
|
+
tst.is(isDeepEqual(objA, objB), false, 'should not be equal');
|
|
431
|
+
tst.end();
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
st.test('should compare nested objects', (tst) => {
|
|
435
|
+
const deep1 = obj;
|
|
436
|
+
const deep2 = {
|
|
437
|
+
deep: deep1,
|
|
438
|
+
added: 'a value',
|
|
439
|
+
};
|
|
440
|
+
const objA = {
|
|
441
|
+
d: deep2,
|
|
442
|
+
}
|
|
443
|
+
const objB = deepClone(objA);
|
|
444
|
+
|
|
445
|
+
tst.is(isDeepEqual(objA, objB), true, 'should be equal');
|
|
446
|
+
tst.end();
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
st.test('with arrays', (tst) => {
|
|
450
|
+
const nestedArray1 = [
|
|
451
|
+
obj,
|
|
452
|
+
{ a: 'value' },
|
|
453
|
+
null,
|
|
454
|
+
undefined,
|
|
455
|
+
42,
|
|
456
|
+
'value',
|
|
457
|
+
];
|
|
458
|
+
const nestedArray2 = deepClone(nestedArray1);
|
|
459
|
+
const arrayA = [
|
|
460
|
+
{
|
|
461
|
+
deep: nestedArray1,
|
|
462
|
+
},
|
|
463
|
+
nestedArray2,
|
|
464
|
+
42, 'value', null, undefined, [[]],
|
|
465
|
+
];
|
|
466
|
+
const arrayB = deepClone(arrayA);
|
|
467
|
+
|
|
468
|
+
tst.is(isDeepEqual(arrayA, arrayB), true, 'should be equal');
|
|
469
|
+
tst.end();
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
st.test('with RegExp', (tst) => {
|
|
473
|
+
const regA1 = /hello?/gi;
|
|
474
|
+
const regA2 = /.* [aA]+?/;
|
|
475
|
+
|
|
476
|
+
const regB1 = deepClone(regA1);
|
|
477
|
+
const regB2 = {rgx: regA2};
|
|
478
|
+
|
|
479
|
+
tst.is(isDeepEqual(regA1, regB1), true, 'should be equal');
|
|
480
|
+
tst.is(isDeepEqual(regA2, regB2), false, 'should not be equal');
|
|
481
|
+
tst.end();
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
st.test('with Date', (tst) => {
|
|
485
|
+
const dateA = new Date('1996-06-27');
|
|
486
|
+
const dateB = new Date('1996-06-27');
|
|
487
|
+
|
|
488
|
+
tst.is(isDeepEqual(dateA, dateB), true, 'should be equal');
|
|
489
|
+
tst.end();
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
st.test('with functions', (tst) => {
|
|
493
|
+
const fn1 = fn;
|
|
494
|
+
const fn2 = () => {};
|
|
495
|
+
|
|
496
|
+
tst.is(isDeepEqual(fn1, fn), true, 'should be equal');
|
|
497
|
+
tst.is(isDeepEqual(fn2, fn), false, 'should not be equal');
|
|
498
|
+
tst.end();
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
st.test('with primitives', (tst) => {
|
|
502
|
+
tst.is(isDeepEqual(10%3, 1), true, 'should be equal');
|
|
503
|
+
tst.is(isDeepEqual('Bingo'[0], 'B'), true, 'should be equal');
|
|
504
|
+
tst.is(isDeepEqual(!true, false), true, 'should be equal');
|
|
505
|
+
tst.is(isDeepEqual(obj.e, null), true, 'should be equal');
|
|
506
|
+
tst.is(isDeepEqual(obj.d, undefined), true, 'should be equal');
|
|
507
|
+
tst.end();
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
st.test('with circular references', (tst) => {
|
|
511
|
+
const obj1 = {
|
|
512
|
+
a: 'a',
|
|
513
|
+
}
|
|
514
|
+
const obj2 = {
|
|
515
|
+
b: 'b',
|
|
516
|
+
}
|
|
517
|
+
obj1.child = obj1;
|
|
518
|
+
obj1.sibling = obj2;
|
|
519
|
+
obj2.sibling = obj1;
|
|
520
|
+
|
|
521
|
+
const objA = [obj1, obj2];
|
|
522
|
+
const objB = deepClone(objA);
|
|
523
|
+
|
|
524
|
+
tst.is(isDeepEqual(objA, objB), true, 'should be equal');
|
|
525
|
+
tst.end();
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
st.test('can ignore some attributes', (tst) => {
|
|
529
|
+
const noCompare1 = {
|
|
530
|
+
ref: 1,
|
|
531
|
+
};
|
|
532
|
+
const noCompare2 = new Set(['alpha', 'omega']);
|
|
533
|
+
const noCompare3 = new Map([[1, 'alpha'], [22, 'omega']]);
|
|
534
|
+
const deep1 = {
|
|
535
|
+
a: 'alpha',
|
|
536
|
+
noCompare: noCompare3,
|
|
537
|
+
};
|
|
538
|
+
const objA = {
|
|
539
|
+
id: 'ref',
|
|
540
|
+
noCopy: noCompare1,
|
|
541
|
+
nop: noCompare2,
|
|
542
|
+
not: 42,
|
|
543
|
+
deep: deep1,
|
|
544
|
+
};
|
|
545
|
+
const objB = deepClone(objA);
|
|
546
|
+
objB.not = 24;
|
|
547
|
+
|
|
548
|
+
const result1 = isDeepEqual(objA, objB, ['noCopy', 'nothing', 'nop', 'not']);
|
|
549
|
+
const result2 = isDeepEqual(objA, objB, ['noCopy', 'nothing', 'nop']);
|
|
550
|
+
|
|
551
|
+
tst.is(result1, true, 'should be equal');
|
|
552
|
+
tst.is(result2, false, 'should not be equal');
|
|
553
|
+
tst.end();
|
|
554
|
+
});
|
|
555
|
+
});
|
package/types/List.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export default class List extends Vue<Props> {
|
|
|
30
30
|
private onMouseOver;
|
|
31
31
|
onIndexChange(): void;
|
|
32
32
|
onOffsetChange(): void;
|
|
33
|
-
onFilteredOptionsChange(): void;
|
|
33
|
+
onFilteredOptionsChange(oldVal: OptionItem[], newVal: OptionItem[]): void;
|
|
34
34
|
onGroupIdChange(): void;
|
|
35
35
|
mounted(): void;
|
|
36
36
|
render(): h.JSX.Element;
|
package/types/Store.d.ts
CHANGED
|
@@ -247,7 +247,7 @@ export interface SelecticStoreState {
|
|
|
247
247
|
};
|
|
248
248
|
}
|
|
249
249
|
export declare type IconFamily = '' | 'selectic' | 'font-awesome-4' | 'font-awesome-5' | 'font-awesome-6' | 'raw' | `prefix:${string}`;
|
|
250
|
-
export declare type IconKey = 'caret-down' | 'caret-up' | 'check' | 'search' | 'spinner' | 'strikethrough' | 'times' | 'question' | 'spin';
|
|
250
|
+
export declare type IconKey = 'caret-down' | 'caret-up' | 'check' | 'dot' | 'search' | 'spinner' | 'strikethrough' | 'times' | 'question' | 'spin';
|
|
251
251
|
export declare type IconValue = `selectic:${IconKey}${'' | ':spin'}` | `raw:${string}` | `current:${IconKey}${'' | ':spin'}` | string;
|
|
252
252
|
export declare type Icons = Record<IconKey, IconValue>;
|
|
253
253
|
export declare type PartialIcons = {
|
package/types/tools.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { OptionValue } from './Store';
|
|
2
1
|
/**
|
|
3
2
|
* Clone the object and its inner properties.
|
|
4
3
|
* @param obj The object to be clone.
|
|
@@ -21,10 +20,17 @@ export declare function deepClone<T = any>(origObject: T, ignoreAttributes?: str
|
|
|
21
20
|
export declare function convertToRegExp(name: string, flag?: string): RegExp;
|
|
22
21
|
/** Does the same as Object.assign but does not replace if value is undefined */
|
|
23
22
|
export declare function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial<T>>): T;
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
23
|
+
/**
|
|
24
|
+
* Performs a deep comparison between two objects to determine if they
|
|
25
|
+
* should be considered equal.
|
|
26
|
+
*
|
|
27
|
+
* @param objA object to compare to objB.
|
|
28
|
+
* @param objB object to compare to objA.
|
|
29
|
+
* @param attributes list of attributes to not compare.
|
|
30
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
31
|
+
* @returns true if objA should be considered equal to objB.
|
|
26
32
|
*/
|
|
27
|
-
export declare function
|
|
33
|
+
export declare function isDeepEqual<T = any>(objA: T, objB: T, ignoreAttributes?: string[], refs?: WeakMap<any, any>): boolean;
|
|
28
34
|
export declare function debug(fName: string, step: string, ...args: any[]): void;
|
|
29
35
|
export declare namespace debug {
|
|
30
36
|
var enable: (display: boolean) => void;
|