mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 02:03:44 +08:00
DEV: Convert select-kit base classes to native class syntax (#28467)
This lays the groundwork for converting SelectKit subclasses to native class syntax. This commit is designed to be entirely backwards-compatible, so it should not affect any existing subclasses. Of interest: - Any properties which are designed to be overridden by subclasses are implemented using a local `@protoProp` decorator. That means they are applied to the prototype, so that they can be overridden in subclasses by both legacy `.extend()` prototype extensions, and by modern native-class fields. - New class decorators are introduced: `@selectKitOptions` and `@pluginApiIdentifiers`. These are native class versions of the legacy `concatenatedProperties` system. This follows the pattern Ember has introduced for `@className`, `@classNameBindings`, etc.
This commit is contained in:
parent
ebbe23e4d2
commit
3e3c051164
|
@ -1,41 +1,45 @@
|
|||
import { computed } from "@ember/object";
|
||||
import { next } from "@ember/runloop";
|
||||
import { isPresent } from "@ember/utils";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
import SelectKitComponent from "select-kit/components/select-kit";
|
||||
import SelectKitComponent, {
|
||||
pluginApiIdentifiers,
|
||||
selectKitOptions,
|
||||
} from "select-kit/components/select-kit";
|
||||
|
||||
export default SelectKitComponent.extend({
|
||||
pluginApiIdentifiers: ["multi-select"],
|
||||
classNames: ["multi-select"],
|
||||
multiSelect: true,
|
||||
@classNames("multi-select")
|
||||
@selectKitOptions({
|
||||
none: "select_kit.default_header_text",
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
filterIcon: null,
|
||||
closeOnChange: false,
|
||||
autoInsertNoneItem: false,
|
||||
headerComponent: "multi-select/multi-select-header",
|
||||
filterComponent: "multi-select/multi-select-filter",
|
||||
autoFilterable: true,
|
||||
caretDownIcon: "caretIcon",
|
||||
caretUpIcon: "caretIcon",
|
||||
useHeaderFilter: false,
|
||||
})
|
||||
@pluginApiIdentifiers(["multi-select"])
|
||||
export default class MultiSelect extends SelectKitComponent {
|
||||
multiSelect = true;
|
||||
|
||||
selectKitOptions: {
|
||||
none: "select_kit.default_header_text",
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
filterIcon: null,
|
||||
closeOnChange: false,
|
||||
autoInsertNoneItem: false,
|
||||
headerComponent: "multi-select/multi-select-header",
|
||||
filterComponent: "multi-select/multi-select-filter",
|
||||
autoFilterable: true,
|
||||
caretDownIcon: "caretIcon",
|
||||
caretUpIcon: "caretIcon",
|
||||
useHeaderFilter: false,
|
||||
},
|
||||
|
||||
caretIcon: computed("value.[]", function () {
|
||||
@computed("value.[]")
|
||||
get caretIcon() {
|
||||
const maximum = this.selectKit.options.maximum;
|
||||
return maximum && makeArray(this.value).length >= parseInt(maximum, 10)
|
||||
? null
|
||||
: "plus";
|
||||
}),
|
||||
}
|
||||
|
||||
search(filter) {
|
||||
return this._super(filter).filter(
|
||||
(content) => !makeArray(this.selectedContent).includes(content)
|
||||
);
|
||||
},
|
||||
return super
|
||||
.search(filter)
|
||||
.filter((content) => !makeArray(this.selectedContent).includes(content));
|
||||
}
|
||||
|
||||
append(values) {
|
||||
const existingItems = values
|
||||
|
@ -60,7 +64,7 @@ export default SelectKitComponent.extend({
|
|||
);
|
||||
|
||||
this.selectKit.change(newValues, newContent);
|
||||
},
|
||||
}
|
||||
|
||||
deselect(item) {
|
||||
this.clearErrors();
|
||||
|
@ -73,7 +77,7 @@ export default SelectKitComponent.extend({
|
|||
this.valueProperty ? newContent.mapBy(this.valueProperty) : newContent,
|
||||
newContent
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
select(value, item) {
|
||||
if (this.selectKit.hasSelection && this.selectKit.options.maximum === 1) {
|
||||
|
@ -122,42 +126,38 @@ export default SelectKitComponent.extend({
|
|||
: makeArray(this.defaultItem(value, value))
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
selectedContent: computed(
|
||||
"value.[]",
|
||||
"content.[]",
|
||||
"selectKit.noneItem",
|
||||
function () {
|
||||
const value = makeArray(this.value).map((v) =>
|
||||
this.selectKit.options.castInteger && this._isNumeric(v) ? Number(v) : v
|
||||
);
|
||||
@computed("value.[]", "content.[]", "selectKit.noneItem")
|
||||
get selectedContent() {
|
||||
const value = makeArray(this.value).map((v) =>
|
||||
this.selectKit.options.castInteger && this._isNumeric(v) ? Number(v) : v
|
||||
);
|
||||
|
||||
if (value.length) {
|
||||
let content = [];
|
||||
if (value.length) {
|
||||
let content = [];
|
||||
|
||||
value.forEach((v) => {
|
||||
if (this.selectKit.valueProperty) {
|
||||
const c = makeArray(this.content).findBy(
|
||||
this.selectKit.valueProperty,
|
||||
v
|
||||
);
|
||||
if (c) {
|
||||
content.push(c);
|
||||
}
|
||||
} else {
|
||||
if (makeArray(this.content).includes(v)) {
|
||||
content.push(v);
|
||||
}
|
||||
value.forEach((v) => {
|
||||
if (this.selectKit.valueProperty) {
|
||||
const c = makeArray(this.content).findBy(
|
||||
this.selectKit.valueProperty,
|
||||
v
|
||||
);
|
||||
if (c) {
|
||||
content.push(c);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (makeArray(this.content).includes(v)) {
|
||||
content.push(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this.selectKit.modifySelection(content);
|
||||
}
|
||||
|
||||
return null;
|
||||
return this.selectKit.modifySelection(content);
|
||||
}
|
||||
),
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_onKeydown(event) {
|
||||
if (
|
||||
|
@ -192,5 +192,5 @@ export default SelectKitComponent.extend({
|
|||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,46 +1,45 @@
|
|||
import { computed } from "@ember/object";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import SelectKitComponent from "select-kit/components/select-kit";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import SelectKitComponent, {
|
||||
pluginApiIdentifiers,
|
||||
selectKitOptions,
|
||||
} from "select-kit/components/select-kit";
|
||||
|
||||
export default SelectKitComponent.extend({
|
||||
pluginApiIdentifiers: ["single-select"],
|
||||
classNames: ["single-select"],
|
||||
singleSelect: true,
|
||||
@classNames("single-select")
|
||||
@selectKitOptions({
|
||||
headerComponent: "select-kit/single-select-header",
|
||||
})
|
||||
@pluginApiIdentifiers(["single-select"])
|
||||
export default class SingleSelect extends SelectKitComponent {
|
||||
singleSelect = true;
|
||||
|
||||
selectKitOptions: {
|
||||
headerComponent: "select-kit/single-select-header",
|
||||
},
|
||||
@computed("value", "content.[]", "selectKit.noneItem")
|
||||
get selectedContent() {
|
||||
if (!isEmpty(this.value)) {
|
||||
let content;
|
||||
|
||||
selectedContent: computed(
|
||||
"value",
|
||||
"content.[]",
|
||||
"selectKit.noneItem",
|
||||
function () {
|
||||
if (!isEmpty(this.value)) {
|
||||
let content;
|
||||
const value =
|
||||
this.selectKit.options.castInteger && this._isNumeric(this.value)
|
||||
? Number(this.value)
|
||||
: this.value;
|
||||
|
||||
const value =
|
||||
this.selectKit.options.castInteger && this._isNumeric(this.value)
|
||||
? Number(this.value)
|
||||
: this.value;
|
||||
if (this.selectKit.valueProperty) {
|
||||
content = (this.content || []).findBy(
|
||||
this.selectKit.valueProperty,
|
||||
value
|
||||
);
|
||||
|
||||
if (this.selectKit.valueProperty) {
|
||||
content = (this.content || []).findBy(
|
||||
this.selectKit.valueProperty,
|
||||
value
|
||||
);
|
||||
|
||||
return this.selectKit.modifySelection(
|
||||
content || this.defaultItem(value, value)
|
||||
);
|
||||
} else {
|
||||
return this.selectKit.modifySelection(
|
||||
(this.content || []).filter((c) => c === value)
|
||||
);
|
||||
}
|
||||
return this.selectKit.modifySelection(
|
||||
content || this.defaultItem(value, value)
|
||||
);
|
||||
} else {
|
||||
return this.selectKit.noneItem;
|
||||
return this.selectKit.modifySelection(
|
||||
(this.content || []).filter((c) => c === value)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return this.selectKit.noneItem;
|
||||
}
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import Mixin from "@ember/object/mixin";
|
||||
import { isNone } from "@ember/utils";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
|
||||
|
@ -97,9 +96,3 @@ export function clearCallbacks() {
|
|||
_onChangeCallbacks = {};
|
||||
_replaceContentCallbacks = {};
|
||||
}
|
||||
|
||||
const EMPTY_ARRAY = Object.freeze([]);
|
||||
export default Mixin.create({
|
||||
concatenatedProperties: ["pluginApiIdentifiers"],
|
||||
pluginApiIdentifiers: EMPTY_ARRAY,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user