mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user