DEV: select-kit 2 (#7998)

This new iteration of select-kit focuses on following best principales and disallowing mutations inside select-kit components. A best effort has been made to avoid breaking changes, however if you content was a flat array, eg: ["foo", "bar"] You will need to set valueProperty=null and nameProperty=null on the component.

Also almost every component should have an `onChange` handler now to decide what to do with the updated data. **select-kit will not mutate your data by itself anymore**
This commit is contained in:
Joffrey JAFFEUX
2020-02-03 14:22:14 +01:00
committed by GitHub
parent 0e2cbee339
commit 0431942f3d
278 changed files with 7566 additions and 6957 deletions

View File

@@ -6,7 +6,7 @@ export default SelectKitFilterComponent.extend({
layoutName: "select-kit/templates/components/select-kit/select-kit-filter",
classNames: ["multi-select-filter"],
@discourseComputed("placeholder", "hasSelection")
@discourseComputed("placeholder", "selectKit.hasSelection")
computedPlaceholder(placeholder, hasSelection) {
if (hasSelection) return "";
return isEmpty(placeholder) ? "" : I18n.t(placeholder);

View File

@@ -1,55 +1,24 @@
import { alias, or } from "@ember/object/computed";
import { makeArray } from "discourse-common/lib/helpers";
import { on } from "discourse-common/utils/decorators";
import discourseComputed from "discourse-common/utils/decorators";
import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header";
import { computed } from "@ember/object";
export default SelectKitHeaderComponent.extend({
attributeBindings: [
"label:title",
"label:aria-label",
"names:data-name",
"values:data-value"
],
classNames: "multi-select-header",
classNames: ["multi-select-header"],
layoutName:
"select-kit/templates/components/multi-select/multi-select-header",
selectedNameComponent: alias("options.selectedNameComponent"),
forceEscape: alias("options.forceEscape"),
selectedNames: computed("selectedContent", function() {
return Ember.makeArray(this.selectedContent).map(c => this.getName(c));
}),
ariaLabel: or("computedContent.ariaLabel", "title", "names"),
selectedValue: computed("selectedContent", function() {
return Ember.makeArray(this.selectedContent)
.map(c => {
if (this.getName(c) !== this.getName(this.selectKit.noneItem)) {
return this.getValue(c);
}
title: or("computedContent.title", "names"),
@on("didRender")
_positionFilter() {
if (!this.shouldDisplayFilter) return;
const $filter = $(this.element.querySelector(".filter"));
$filter.width(0);
const leftHeaderOffset = $(this.element).offset().left;
const leftFilterOffset = $filter.offset().left;
const offset = leftFilterOffset - leftHeaderOffset;
const width = $(this.element).outerWidth(false);
const availableSpace = width - offset;
const $choices = $filter.parent(".choices");
const parentRightPadding = parseInt($choices.css("padding-right"), 10);
$filter.width(availableSpace - parentRightPadding * 4);
},
@discourseComputed("computedContent.selection.[]")
names(selection) {
return makeArray(selection)
.map(s => s.name)
.join(",");
},
@discourseComputed("computedContent.selection.[]")
values(selection) {
return makeArray(selection)
.map(s => s.value)
.join(",");
}
return null;
})
.filter(Boolean);
})
});

View File

@@ -1,16 +1,15 @@
import SelectedNameComponent from "select-kit/components/multi-select/selected-name";
import discourseComputed from "discourse-common/utils/decorators";
import SelectedNameComponent from "select-kit/components/selected-name";
import { categoryBadgeHTML } from "discourse/helpers/category-link";
import { computed } from "@ember/object";
export default SelectedNameComponent.extend({
classNames: "selected-category",
classNames: ["selected-category"],
layoutName: "select-kit/templates/components/multi-select/selected-category",
@discourseComputed("computedContent.originalContent")
badge(category) {
return categoryBadgeHTML(category, {
badge: computed("item", function() {
return categoryBadgeHTML(this.item, {
allowUncategorized: true,
link: false
}).htmlSafe();
}
})
});

View File

@@ -1,8 +1,8 @@
import SelectedNameComponent from "select-kit/components/multi-select/selected-name";
import SelectedNameComponent from "select-kit/components/selected-name";
import discourseComputed from "discourse-common/utils/decorators";
export default SelectedNameComponent.extend({
classNames: "selected-color",
classNames: ["select-kit-selected-color"],
@discourseComputed("name")
footerContent(name) {

View File

@@ -1,56 +0,0 @@
import { or, alias } from "@ember/object/computed";
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
import { computed } from "@ember/object";
export default Component.extend({
attributeBindings: [
"tabindex",
"ariaLabel:aria-label",
"title",
"name:data-name",
"value:data-value",
"guid:data-guid"
],
classNames: ["selected-name", "choice"],
classNameBindings: ["isHighlighted", "isLocked"],
layoutName: "select-kit/templates/components/multi-select/selected-name",
tagName: "span",
tabindex: -1,
@discourseComputed("computedContent")
guid(computedContent) {
return Ember.guidFor(computedContent);
},
ariaLabel: or("computedContent.ariaLabel", "title"),
@discourseComputed("computedContent.title", "name")
title(computedContentTitle, name) {
if (computedContentTitle) return computedContentTitle;
if (name) return name;
return null;
},
label: or("computedContent.label", "title", "name"),
name: alias("computedContent.name"),
value: alias("computedContent.value"),
isLocked: computed("computedContent.locked", function() {
return this.getWithDefault("computedContent.locked", false);
}),
@discourseComputed("computedContent", "highlightedSelection.[]")
isHighlighted(computedContent, highlightedSelection) {
return highlightedSelection.includes(this.computedContent);
},
click() {
if (this.isLocked) return false;
this.onClickSelectionItem([this.computedContent]);
return false;
}
});