discourse/app/assets/javascripts/select-kit/addon/components/select-kit.js
Roman Rizzi ba139b8c23
REFACTOR: Improve reusability by Decoupling flag modal from flag target. (#18251)
* REFACTOR: Improve reusability by Decoupling flag modal from flag target.

We want chat message's flags to have the same features as topic and posts' flags, but we prefer not having to duplicate core's logic. This PR moves target specific bits to different classes, allowing plugins to flag custom things by
providing their own.

* A couple of fixes for the flag modal:

- Make sure buttons are disabled until a flag type is selected.
- Don't throw an error when checking if the user can undo an action on a deleted topic.
- Disable flagging on deleted topics.
2022-09-29 11:57:36 -03:00

1143 lines
31 KiB
JavaScript

import { INPUT_DELAY } from "discourse-common/config/environment";
import EmberObject, { computed, get } from "@ember/object";
import PluginApiMixin, {
applyContentPluginApiCallbacks,
applyOnChangePluginApiCallbacks,
} from "select-kit/mixins/plugin-api";
import { bind, cancel, next, schedule, throttle } from "@ember/runloop";
import { isEmpty, isNone, isPresent } from "@ember/utils";
import Component from "@ember/component";
import I18n from "I18n";
import Mixin from "@ember/object/mixin";
import { Promise } from "rsvp";
import UtilsMixin from "select-kit/mixins/utils";
import { createPopper } from "@popperjs/core";
import deprecated from "discourse-common/lib/deprecated";
import discourseDebounce from "discourse-common/lib/debounce";
import { guidFor } from "@ember/object/internals";
import { makeArray } from "discourse-common/lib/helpers";
export const MAIN_COLLECTION = "MAIN_COLLECTION";
export const ERRORS_COLLECTION = "ERRORS_COLLECTION";
const EMPTY_OBJECT = Object.freeze({});
const SELECT_KIT_OPTIONS = Mixin.create({
concatenatedProperties: ["selectKitOptions"],
selectKitOptions: EMPTY_OBJECT,
});
function isDocumentRTL() {
return document.documentElement.classList.contains("rtl");
}
export default Component.extend(
SELECT_KIT_OPTIONS,
PluginApiMixin,
UtilsMixin,
{
tagName: "details",
pluginApiIdentifiers: ["select-kit"],
classNames: ["select-kit"],
classNameBindings: [
"selectKit.isLoading:is-loading",
"selectKit.isExpanded:is-expanded",
"selectKit.options.disabled:is-disabled",
"selectKit.isHidden:is-hidden",
"selectKit.hasSelection:has-selection",
],
tabindex: 0,
content: null,
value: null,
selectKit: null,
mainCollection: null,
errorsCollection: null,
options: null,
valueProperty: "id",
nameProperty: "name",
singleSelect: false,
multiSelect: false,
labelProperty: null,
titleProperty: null,
langProperty: null,
init() {
this._super(...arguments);
this._searchPromise = null;
this.set("errorsCollection", []);
this._collections = [ERRORS_COLLECTION, MAIN_COLLECTION];
!this.options && this.set("options", EmberObject.create({}));
this.handleDeprecations();
this.set(
"selectKit",
EmberObject.create({
uniqueID: this.attrs?.id?.value || this.attrs?.id || guidFor(this),
valueProperty: this.valueProperty,
nameProperty: this.nameProperty,
labelProperty: this.labelProperty,
titleProperty: this.titleProperty,
langProperty: this.langProperty,
options: EmberObject.create(),
isLoading: false,
isHidden: false,
isExpanded: false,
isFilterExpanded: false,
enterDisabled: false,
hasSelection: false,
hasNoContent: true,
highlighted: null,
noneItem: null,
newItem: null,
filter: null,
modifyContent: bind(this, this._modifyContentWrapper),
modifySelection: bind(this, this._modifySelectionWrapper),
modifyComponentForRow: bind(this, this._modifyComponentForRowWrapper),
modifyContentForCollection: bind(
this,
this._modifyContentForCollectionWrapper
),
modifyComponentForCollection: bind(
this,
this._modifyComponentForCollectionWrapper
),
toggle: bind(this, this._toggle),
close: bind(this, this._close),
open: bind(this, this._open),
highlightNext: bind(this, this._highlightNext),
highlightPrevious: bind(this, this._highlightPrevious),
highlightLast: bind(this, this._highlightLast),
highlightFirst: bind(this, this._highlightFirst),
change: bind(this, this._onChangeWrapper),
select: bind(this, this.select),
deselect: bind(this, this.deselect),
deselectByValue: bind(this, this.deselectByValue),
append: bind(this, this.append),
cancelSearch: bind(this, this._cancelSearch),
triggerSearch: bind(this, this.triggerSearch),
focusFilter: bind(this, this._focusFilter),
onOpen: bind(this, this._onOpenWrapper),
onClose: bind(this, this._onCloseWrapper),
onInput: bind(this, this._onInput),
onClearSelection: bind(this, this._onClearSelection),
onHover: bind(this, this._onHover),
onKeydown: bind(this, this._onKeydownWrapper),
mainElement: bind(this, this._mainElement),
headerElement: bind(this, this._headerElement),
bodyElement: bind(this, this._bodyElement),
})
);
},
_modifyComponentForRowWrapper(collection, item) {
let component = this.modifyComponentForRow(collection, item);
return component || "select-kit/select-kit-row";
},
modifyComponentForRow() {},
_modifyContentForCollectionWrapper(identifier) {
let collection = this.modifyContentForCollection(identifier);
if (!collection) {
switch (identifier) {
case ERRORS_COLLECTION:
collection = this.errorsCollection;
break;
default:
collection = this.mainCollection;
break;
}
}
return collection;
},
modifyContentForCollection() {},
_modifyComponentForCollectionWrapper(identifier) {
let component = this.modifyComponentForCollection(identifier);
if (!component) {
switch (identifier) {
case ERRORS_COLLECTION:
component = "select-kit/errors-collection";
break;
default:
component = "select-kit/select-kit-collection";
break;
}
}
return component;
},
modifyComponentForCollection() {},
didUpdateAttrs() {
this._super(...arguments);
this.handleDeprecations();
},
click(event) {
event.preventDefault();
event.stopPropagation();
},
willDestroyElement() {
this._super(...arguments);
this._cancelSearch();
if (this.popper) {
this.popper.destroy();
this.popper = null;
}
},
didReceiveAttrs() {
this._super(...arguments);
const mergedOptions = Object.assign({}, ...this.selectKitOptions);
Object.keys(mergedOptions).forEach((key) => {
if (isPresent(this.options[key])) {
this.selectKit.options.set(key, this.options[key]);
return;
}
const value = mergedOptions[key];
if (
key === "componentForRow" ||
key === "contentForCollection" ||
key === "componentForCollection"
) {
if (typeof value === "string") {
this.selectKit.options.set(key, () => value);
} else {
this.selectKit.options.set(key, bind(this, value));
}
return;
}
if (
typeof value === "string" &&
!value.includes(".") &&
value in this
) {
const computedValue = get(this, value);
if (typeof computedValue !== "function") {
this.selectKit.options.set(key, computedValue);
return;
}
}
this.selectKit.options.set(key, value);
});
this.selectKit.setProperties({
hasSelection: !isEmpty(this.value),
noneItem: this._modifyNoSelectionWrapper(),
newItem: null,
});
if (this.selectKit.isExpanded) {
this.triggerSearch();
}
if (this.computeContent) {
this._deprecated(
`The \`computeContent()\` function is deprecated pass a \`content\` attribute or define a \`content\` computed property in your component.`
);
this.set("content", this.computeContent());
}
},
selectKitOptions: {
allowAny: false,
showFullTitle: true,
none: null,
translatedNone: null,
filterable: false,
autoFilterable: "autoFilterable",
filterIcon: "search",
filterPlaceholder: null,
translatedFilterPlaceholder: null,
icon: null,
icons: null,
maximum: null,
maximumLabel: null,
minimum: null,
autoInsertNoneItem: true,
closeOnChange: true,
limitMatches: null,
placement: isDocumentRTL() ? "bottom-end" : "bottom-start",
filterComponent: "select-kit/select-kit-filter",
selectedNameComponent: "selected-name",
selectedChoiceComponent: "selected-choice",
castInteger: false,
focusAfterOnChange: true,
triggerOnChangeOnTab: true,
autofocus: false,
placementStrategy: null,
mobilePlacementStrategy: null,
desktopPlacementStrategy: null,
hiddenValues: null,
disabled: false,
},
autoFilterable: computed("content.[]", "selectKit.filter", function () {
return (
this.selectKit.filter &&
this.options.autoFilterable &&
this.content.length > 15
);
}),
collections: computed(
"selectedContent.[]",
"mainCollection.[]",
"errorsCollection.[]",
function () {
return this._collections.map((identifier) => {
return {
identifier,
content: this.selectKit.modifyContentForCollection(identifier),
};
});
}
),
createContentFromInput(input) {
return input;
},
validateCreate(filter, content) {
this.clearErrors();
return (
filter.length > 0 &&
content &&
!content.map((c) => this.getValue(c)).includes(filter) &&
!makeArray(this.value).includes(filter)
);
},
validateSelect() {
this.clearErrors();
const selection = makeArray(this.value);
const maximum = this.selectKit.options.maximum;
if (maximum && selection.length >= maximum) {
const key =
this.selectKit.options.maximumLabel ||
"select_kit.max_content_reached";
this.addError(I18n.t(key, { count: maximum }));
return false;
}
return true;
},
addError(error) {
this.errorsCollection.pushObject(error);
this._safeAfterRender(() => this.popper && this.popper.update());
},
clearErrors() {
if (!this.element || this.isDestroyed || this.isDestroying) {
return;
}
this.set("errorsCollection", []);
},
prependCollection(identifier) {
this._collections.unshift(identifier);
},
appendCollection(identifier) {
this._collections.push(identifier);
},
insertCollectionAtIndex(identifier, index) {
this._collections.insertAt(index, identifier);
},
insertBeforeCollection(identifier, insertedIdentifier) {
const index = this._collections.indexOf(identifier);
this.insertCollectionAtIndex(insertedIdentifier, index - 1);
},
insertAfterCollection(identifier, insertedIdentifier) {
const index = this._collections.indexOf(identifier);
this.insertCollectionAtIndex(insertedIdentifier, index + 1);
},
_onInput(event) {
this.popper && this.popper.update();
if (this._searchPromise) {
cancel(this._searchPromise);
}
this.selectKit.set("isLoading", true);
discourseDebounce(
this,
this._debouncedInput,
event.target.value,
INPUT_DELAY
);
},
_debouncedInput(filter) {
this.selectKit.set("filter", filter);
this.triggerSearch(filter);
},
_onChangeWrapper(value, items) {
this.selectKit.set("filter", null);
return new Promise((resolve) => {
if (
!this.selectKit.valueProperty &&
this.selectKit.noneItem === value
) {
value = null;
items = [];
}
value = makeArray(value);
items = makeArray(items);
if (this.multiSelect) {
items = items.filter(
(i) =>
i !== this.newItem &&
i !== this.noneItem &&
this.getValue(i) !== null
);
if (this.selectKit.options.maximum === 1) {
value = value.slice(0, 1);
items = items.slice(0, 1);
}
}
if (this.singleSelect) {
value = isPresent(value.firstObject) ? value.firstObject : null;
items = isPresent(items.firstObject) ? items.firstObject : null;
}
this._boundaryActionHandler("onChange", value, items);
applyOnChangePluginApiCallbacks(value, items, this);
resolve(items);
}).finally(() => {
if (!this.isDestroying && !this.isDestroyed) {
if (
this.selectKit.options.closeOnChange ||
(isPresent(value) && this.selectKit.options.maximum === 1)
) {
this.selectKit.close(event);
}
if (this.selectKit.options.focusAfterOnChange) {
this._safeAfterRender(() => {
this._focusFilter();
this.popper && this.popper.update();
});
}
}
});
},
_modifyContentWrapper(content) {
content = this.modifyContent(content);
return applyContentPluginApiCallbacks(content, this);
},
modifyContent(content) {
return content;
},
_modifyNoSelectionWrapper() {
return this.modifyNoSelection();
},
modifyNoSelection() {
if (this.selectKit.options.translatedNone) {
return this.defaultItem(null, this.selectKit.options.translatedNone);
}
let none = this.selectKit.options.none;
if (isNone(none) && !this.selectKit.options.allowAny) {
return null;
}
if (
isNone(none) &&
this.selectKit.options.allowAny &&
!this.selectKit.isExpanded
) {
return null;
}
let item;
switch (typeof none) {
case "string":
item = this.defaultItem(null, I18n.t(none));
break;
default:
item = none;
}
return item;
},
_modifySelectionWrapper(item) {
return this.modifySelection(item);
},
modifySelection(item) {
return item;
},
_onKeydownWrapper(event) {
return this._boundaryActionHandler("onKeydown", event);
},
_mainElement() {
return document.querySelector(`#${this.selectKit.uniqueID}`);
},
_headerElement() {
return this.selectKit.mainElement().querySelector("summary");
},
_bodyElement() {
return this.selectKit.mainElement().querySelector(".select-kit-body");
},
_onHover(value, item) {
throttle(this, this._highlight, item, 25, true);
},
_highlight(item) {
this.selectKit.set("highlighted", item);
},
_boundaryActionHandler(actionName, ...params) {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
let boundaryAction = true;
const privateActionName = `_${actionName}`;
const privateAction = get(this, privateActionName);
if (privateAction) {
boundaryAction = privateAction.call(this, ...params);
}
if (this.actions) {
const componentAction = get(this.actions, actionName);
if (boundaryAction && componentAction) {
boundaryAction = componentAction.call(this, ...params);
}
}
const action = get(this, actionName);
if (boundaryAction && action) {
boundaryAction = action.call(this, ...params);
}
return boundaryAction;
},
deselect() {
this.clearErrors();
this.selectKit.change(null, null);
},
deselectByValue(value) {
if (!value) {
return;
}
const item = this.itemForValue(value, this.selectedContent);
this.deselect(item);
},
append() {
// do nothing on general case
},
search(filter) {
let content = this.content || [];
if (filter) {
filter = this._normalize(filter);
content = content.filter((c) => {
const name = this._normalize(this.getName(c));
return name?.includes(filter);
});
}
return content;
},
triggerSearch(filter) {
this._searchPromise && cancel(this._searchPromise);
this._searchPromise = this._searchWrapper(
filter || this.selectKit.filter
);
},
_searchWrapper(filter) {
if (this.isDestroyed || this.isDestroying) {
return Promise.resolve([]);
}
this.clearErrors();
this.setProperties({
mainCollection: [],
"selectKit.isLoading": true,
"selectKit.enterDisabled": true,
});
this._safeAfterRender(() => this.popper && this.popper.update());
let content = [];
return Promise.resolve(this.search(filter))
.then((result) => {
if (this.isDestroyed || this.isDestroying) {
return [];
}
content = content.concat(makeArray(result));
content = this.selectKit.modifyContent(content).filter(Boolean);
if (this.selectKit.valueProperty) {
content = content.uniqBy(this.selectKit.valueProperty);
} else {
content = content.uniq();
}
if (this.selectKit.options.limitMatches) {
content = content.slice(0, this.selectKit.options.limitMatches);
}
const noneItem = this.selectKit.noneItem;
if (
this.selectKit.options.allowAny &&
filter &&
this.getName(noneItem) !== filter
) {
filter = this.createContentFromInput(filter);
if (this.validateCreate(filter, content)) {
this.selectKit.set("newItem", this.defaultItem(filter, filter));
content.unshift(this.selectKit.newItem);
}
}
const hasNoContent = isEmpty(content);
if (
this.selectKit.hasSelection &&
noneItem &&
this.selectKit.options.autoInsertNoneItem
) {
content.unshift(noneItem);
}
this.set("mainCollection", content);
this.selectKit.setProperties({
highlighted:
this.singleSelect && this.value
? this.itemForValue(this.value, this.mainCollection)
: isEmpty(this.selectKit.filter)
? null
: this.mainCollection.firstObject,
isLoading: false,
hasNoContent,
});
this._safeAfterRender(() => {
if (this.selectKit.isExpanded) {
this.popper && this.popper.update();
this._focusFilter();
}
});
})
.finally(() => {
if (this.isDestroyed || this.isDestroying) {
return;
}
this.set("selectKit.enterDisabled", false);
});
},
_safeAfterRender(fn) {
next(() => {
schedule("afterRender", () => {
if (!this.element || this.isDestroyed || this.isDestroying) {
return;
}
fn();
});
});
},
_scrollToRow(rowItem, preventScroll = true) {
const value = this.getValue(rowItem);
let rowContainer;
if (isPresent(value)) {
rowContainer = this.element.querySelector(
`.select-kit-row[data-value="${value}"]`
);
} else {
rowContainer = this.element.querySelector(".select-kit-row.is-none");
}
rowContainer?.focus({ preventScroll });
},
_highlightLast() {
const highlighted = this.mainCollection.objectAt(
this.mainCollection.length - 1
);
if (highlighted) {
this._scrollToRow(highlighted, false);
this.set("selectKit.highlighted", highlighted);
}
},
_highlightFirst() {
const highlighted = this.mainCollection.objectAt(0);
if (highlighted) {
this._scrollToRow(highlighted, false);
this.set("selectKit.highlighted", highlighted);
}
},
_highlightNext() {
let highlightedIndex = this.mainCollection.indexOf(
this.selectKit.highlighted
);
const count = this.mainCollection.length;
if (highlightedIndex < count - 1) {
highlightedIndex = highlightedIndex + 1;
} else {
if (this.selectKit.isFilterExpanded) {
this._focusFilter();
} else {
highlightedIndex = 0;
}
}
const highlighted = this.mainCollection.objectAt(highlightedIndex);
if (highlighted) {
this._scrollToRow(highlighted, false);
this.set("selectKit.highlighted", highlighted);
}
},
_highlightPrevious() {
let highlightedIndex = this.mainCollection.indexOf(
this.selectKit.highlighted
);
const count = this.mainCollection.length;
if (highlightedIndex > 0) {
highlightedIndex = highlightedIndex - 1;
} else {
if (this.selectKit.isFilterExpanded) {
this._focusFilter();
} else {
highlightedIndex = count - 1;
}
}
const highlighted = this.mainCollection.objectAt(highlightedIndex);
if (highlighted) {
this._scrollToRow(highlighted, false);
this.set("selectKit.highlighted", highlighted);
}
},
select(value, item) {
if (!isPresent(value)) {
this._onClearSelection();
} else {
const existingItem = this.findValue(this.mainCollection, item);
if (existingItem) {
if (!this.validateSelect(item)) {
return;
}
}
this.selectKit.change(value, item || this.defaultItem(value, value));
}
},
_onClearSelection() {
this.selectKit.change(null, null);
},
_onOpenWrapper() {
return this._boundaryActionHandler("onOpen");
},
_cancelSearch() {
this._searchPromise && cancel(this._searchPromise);
},
_onCloseWrapper() {
this._cancelSearch();
this.set("selectKit.highlighted", null);
return this._boundaryActionHandler("onClose");
},
_toggle(event) {
if (this.selectKit.isExpanded) {
this._close(event);
} else {
this._open(event);
}
},
_close(event) {
if (!this.selectKit.isExpanded) {
return;
}
this.selectKit.mainElement().open = false;
this.clearErrors();
const inModal = this.element.closest("#discourse-modal");
if (inModal && this?.site?.mobileView) {
const modalBody = inModal.querySelector(".modal-body");
modalBody.style = "";
}
this.selectKit.onClose(event);
this.selectKit.setProperties({
isExpanded: false,
filter: null,
});
},
_open(event) {
if (this.selectKit.isExpanded) {
return;
}
this.selectKit.mainElement().open = true;
this.clearErrors();
this.selectKit.onOpen(event);
if (!this.popper) {
const inModal = this.element.closest("#discourse-modal");
const anchor = document.querySelector(
`#${this.selectKit.uniqueID}-header`
);
const popper = document.querySelector(
`#${this.selectKit.uniqueID}-body`
);
const strategy = this._computePlacementStrategy();
this.popper = createPopper(anchor, popper, {
eventsEnabled: false,
strategy,
placement: this.selectKit.options.placement,
modifiers: [
{
name: "eventListeners",
options: {
resize: !this.site.mobileView,
scroll: !this.site.mobileView,
},
},
{
name: "flip",
enabled: !inModal,
options: {
padding: {
top:
parseInt(
document.documentElement.style.getPropertyValue(
"--header-offset"
),
10
) || 0,
},
},
},
{
name: "offset",
options: {
offset: [0, 3],
},
},
{
name: "applySmallScreenOffset",
enabled: window.innerWidth <= 450,
phase: "main",
fn({ state }) {
if (!inModal) {
let { x } = state.elements.reference.getBoundingClientRect();
if (strategy === "fixed") {
state.modifiersData.popperOffsets.x = 0 + 10;
} else {
state.modifiersData.popperOffsets.x = -x + 10;
}
}
},
},
{
name: "applySmallScreenMaxWidth",
enabled: window.innerWidth <= 450,
phase: "beforeWrite",
fn: ({ state }) => {
if (inModal) {
const innerModal = document.querySelector(
"#discourse-modal div.modal-inner-container"
);
if (innerModal) {
if (this.multiSelect) {
state.styles.popper.width = `${this.element.offsetWidth}px`;
} else {
state.styles.popper.width = `${
innerModal.clientWidth - 20
}px`;
}
}
} else {
state.styles.popper.width = `${window.innerWidth - 20}px`;
}
},
},
{
name: "minWidth",
enabled: window.innerWidth > 450,
phase: "beforeWrite",
requires: ["computeStyles"],
fn: ({ state }) => {
state.styles.popper.minWidth = `${Math.max(
state.rects.reference.width,
220
)}px`;
},
effect: ({ state }) => {
state.elements.popper.style.minWidth = `${Math.max(
state.elements.reference.offsetWidth,
220
)}px`;
},
},
{
name: "modalHeight",
enabled: !!(inModal && this.site.mobileView),
phase: "afterWrite",
fn: ({ state }) => {
const modalBody = inModal.querySelector(".modal-body");
modalBody.style = "";
modalBody.style.height =
modalBody.clientHeight + state.rects.popper.height + "px";
},
},
],
});
}
this.selectKit.setProperties({
isExpanded: true,
isFilterExpanded:
this.selectKit.options.filterable || this.selectKit.options.allowAny,
});
this.triggerSearch();
this._safeAfterRender(() => {
this._focusFilter();
this._scrollToCurrent();
this.popper && this.popper.update();
});
},
_scrollToCurrent() {
if (this.value && this.mainCollection) {
let highlighted;
if (this.valueProperty) {
highlighted = this.mainCollection.findBy(
this.valueProperty,
this.value
);
} else {
const index = this.mainCollection.indexOf(this.value);
highlighted = this.mainCollection.objectAt(index);
}
if (highlighted) {
this._scrollToRow(highlighted, false);
this.set("selectKit.highlighted", highlighted);
}
}
},
_focusFilter(forceHeader = false) {
if (!this.selectKit.mainElement()) {
return;
}
if (!this.selectKit.mainElement().open) {
const headerContainer = this.getHeader();
headerContainer && headerContainer.focus({ preventScroll: true });
return;
}
this._safeAfterRender(() => {
const input = this.getFilterInput();
if (!forceHeader && input) {
input.focus({ preventScroll: true });
if (typeof input.selectionStart === "number") {
input.selectionStart = input.selectionEnd = input.value.length;
}
} else if (!this.selectKit.options.preventHeaderFocus) {
const headerContainer = this.getHeader();
headerContainer && headerContainer.focus({ preventScroll: true });
}
});
},
getFilterInput() {
return document.querySelector(`#${this.selectKit.uniqueID}-filter input`);
},
getHeader() {
return document.querySelector(`#${this.selectKit.uniqueID}-header`);
},
handleDeprecations() {
this._deprecateValueAttribute();
this._deprecateMutations();
this._deprecateOptions();
},
_computePlacementStrategy() {
let placementStrategy = this.selectKit.options.placementStrategy;
if (placementStrategy) {
return placementStrategy;
}
if (this.capabilities?.isIpadOS || this.site?.mobileView) {
placementStrategy =
this.selectKit.options.mobilePlacementStrategy || "absolute";
} else {
placementStrategy =
this.selectKit.options.desktopPlacementStrategy || "fixed";
}
return placementStrategy;
},
_deprecated(text) {
const discourseSetup = document.getElementById("data-discourse-setup");
if (
discourseSetup &&
discourseSetup.getAttribute("data-environment") === "development"
) {
deprecated(text, { since: "v2.4.0", dropFrom: "2.9.0.beta1" });
}
},
_deprecateValueAttribute() {
if (this.valueAttribute || this.valueAttribute === null) {
this._deprecated(
"The `valueAttribute` is deprecated. Use `valueProperty` instead"
);
this.set("valueProperty", this.valueAttribute);
}
},
_deprecateMutations() {
this.actions = this.actions || {};
this.attrs = this.attrs || {};
if (!this.attrs.onChange && !this.actions.onChange) {
this._deprecated(
"Implicit mutation has been deprecated, please use `onChange` handler"
);
this.actions.onChange =
this.attrs.onSelect ||
this.actions.onSelect ||
((value) => this.set("value", value));
}
},
_deprecateOptions() {
const migrations = {
headerIcon: "icon",
onExpand: "onOpen",
onCollapse: "onClose",
allowAny: "options.allowAny",
allowCreate: "options.allowAny",
filterable: "options.filterable",
excludeCategoryId: "options.excludeCategoryId",
scopedCategoryId: "options.scopedCategoryId",
allowUncategorized: "options.allowUncategorized",
none: "options.none",
rootNone: "options.none",
disabled: "options.disabled",
isDisabled: "options.disabled",
rootNoneLabel: "options.none",
showFullTitle: "options.showFullTitle",
title: "options.translatedNone",
maximum: "options.maximum",
minimum: "options.minimum",
i18nPostfix: "options.i18nPostfix",
i18nPrefix: "options.i18nPrefix",
castInteger: "options.castInteger",
};
Object.keys(migrations).forEach((from) => {
const to = migrations[from];
if (this.get(from) && !this.get(to)) {
this._deprecated(
`The \`${from}\` attribute is deprecated. Use \`${to}\` instead`
);
this.set(to, this.get(from));
}
});
},
}
);