select-kit refactoring

* improve events naming/handling
* do not explicitly check for true/Fasle
* make sure header is re-computed on toggle
This commit is contained in:
Joffrey JAFFEUX 2018-01-11 09:39:51 +01:00 committed by GitHub
parent 2509bef2c0
commit 3ec2024466
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 140 additions and 153 deletions

View File

@ -85,7 +85,6 @@ export default SelectKitComponent.extend({
Ember.run.next(() => {
this.mutateContent(this.get("computedContent"));
this.mutateValues(this.get("computedValues"));
applyOnSelectPluginApiCallbacks(this.get("pluginApiIdentifiers"), this.get("computedValues"), this);
this._setHeaderComputedContent();
});
},
@ -107,7 +106,7 @@ export default SelectKitComponent.extend({
return !computedValues.includes(get(c, "value"));
});
if (this.get("shouldFilter") === true) {
if (this.get("shouldFilter")) {
computedContent = this.filterComputedContent(computedContent, computedValues, filter);
}
@ -162,7 +161,7 @@ export default SelectKitComponent.extend({
const computedContent = this._findComputedContentItemByGuid($(el).attr("data-guid"));
if (!Ember.isNone(computedContent)) { highlightedComputedContents.push(computedContent); }
});
this.send("onDeselect", highlightedComputedContents);
this.send("deselect", highlightedComputedContents);
return;
}
@ -208,18 +207,18 @@ export default SelectKitComponent.extend({
autoHighlight() {
Ember.run.schedule("afterRender", () => {
if (this.get("isExpanded") === false) { return; }
if (this.get("renderedBodyOnce") === false) { return; }
if (!isNone(this.get("highlightedValue"))) { return; }
if (!this.get("isExpanded")) return;
if (!this.get("renderedBodyOnce")) return;
if (!isNone(this.get("highlightedValue"))) return;
if (isEmpty(this.get("filteredComputedContent"))) {
if (this.get("createRowComputedContent")) {
this.send("onHighlight", this.get("createRowComputedContent"));
} else if (this.get("noneRowComputedContent") && this.get("hasSelection") === true) {
this.send("onHighlight", this.get("noneRowComputedContent"));
this.send("highlight", this.get("createRowComputedContent"));
} else if (this.get("noneRowComputedContent") && this.get("hasSelection")) {
this.send("highlight", this.get("noneRowComputedContent"));
}
} else {
this.send("onHighlight", this.get("filteredComputedContent.firstObject"));
this.send("highlight", this.get("filteredComputedContent.firstObject"));
}
});
},
@ -227,6 +226,19 @@ export default SelectKitComponent.extend({
didSelect() {
this.focusFilterOrHeader();
this.autoHighlight();
applyOnSelectPluginApiCallbacks(
this.get("pluginApiIdentifiers"),
this.get("computedValue"),
this
);
this._boundaryActionHandler("onSelect", this.get("computedValue"));
},
willDeselect() {
this.clearFilter();
this.set("highlightedValue", null);
},
didDeselect() {
@ -239,27 +251,29 @@ export default SelectKitComponent.extend({
},
actions: {
onClear() {
this.get("selectedComputedContents").forEach(selectedComputedContent => {
this.send("onDeselect", selectedComputedContent);
});
clearSelection() {
this.send("deselect", this.get("selectedComputedContents"));
this._boundaryActionHandler("onClearSelection");
},
onCreate(computedContentItem) {
create(computedContentItem) {
if (this.validateComputedContentItem(computedContentItem)) {
this.get("computedContent").pushObject(computedContentItem);
this.send("onSelect", computedContentItem);
this._boundaryActionHandler("onCreate");
this.send("select", computedContentItem);
} else {
this._boundaryActionHandler("onCreateFailure");
}
},
onSelect(computedContentItem) {
select(computedContentItem) {
this.willSelect(computedContentItem);
this.get("computedValues").pushObject(computedContentItem.value);
Ember.run.next(() => this.mutateAttributes());
Ember.run.schedule("afterRender", () => this.didSelect(computedContentItem));
},
onDeselect(rowComputedContentItems) {
deselect(rowComputedContentItems) {
rowComputedContentItems = Ember.makeArray(rowComputedContentItems);
const generatedComputedContents = this._filterRemovableComputedContents(makeArray(rowComputedContentItems));
this.willDeselect(rowComputedContentItems);

View File

@ -5,6 +5,6 @@ export default CategoryRowComponent.extend({
classNames: "none category-row",
click() {
this.sendAction("onClear");
this.sendAction("clearSelection");
}
});

View File

@ -44,13 +44,15 @@ export default DropdownSelectBoxComponent.extend({
]);
},
mutateValue(value) {
const topic = this.get("topic");
actions: {
onSelect() {
const topic = this.get("topic");
if (value === "unpinned") {
topic.clearPin();
} else {
topic.rePin();
if (this.get("computedValue") === "unpinned") {
topic.clearPin();
} else {
topic.rePin();
}
}
}
});

View File

@ -6,7 +6,8 @@ import EventsMixin from "select-kit/mixins/events";
import PluginApiMixin from "select-kit/mixins/plugin-api";
import {
applyContentPluginApiCallbacks,
applyHeaderContentPluginApiCallbacks
applyHeaderContentPluginApiCallbacks,
applyOnSelectPluginApiCallbacks
} from "select-kit/mixins/plugin-api";
export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixin, EventsMixin, {
@ -138,8 +139,8 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi
@computed("shouldFilter", "allowAny", "filter")
shouldDisplayFilter(shouldFilter, allowAny, filter) {
if (shouldFilter === true) return true;
if (allowAny === true && filter.length > 0) return true;
if (shouldFilter) return true;
if (allowAny && filter.length > 0) return true;
return false;
},
@ -150,22 +151,22 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi
@computed("filter", "filterable", "autoFilterable", "renderedFilterOnce")
shouldFilter(filter, filterable, autoFilterable, renderedFilterOnce) {
if (renderedFilterOnce === true && filterable === true) return true;
if (filterable === true) return true;
if (autoFilterable === true && filter.length > 0) return true;
if (renderedFilterOnce && filterable) return true;
if (filterable) return true;
if (autoFilterable && filter.length > 0) return true;
return false;
},
@computed("filter", "computedContent")
shouldDisplayCreateRow(filter, computedContent) {
if (computedContent.map(c => c.value).includes(filter)) return false;
if (this.get("allowAny") === true && filter.length > 0) return true;
if (this.get("allowAny") && filter.length > 0) return true;
return false;
},
@computed("filter", "shouldDisplayCreateRow")
createRowComputedContent(filter, shouldDisplayCreateRow) {
if (shouldDisplayCreateRow === true) {
if (shouldDisplayCreateRow) {
let content = this.createContentFromInput(filter);
return this.computeContentItem(content, { created: true });
}
@ -209,15 +210,24 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi
didSelect() {
this.collapse();
this.focus();
applyOnSelectPluginApiCallbacks(
this.get("pluginApiIdentifiers"),
this.get("computedValue"),
this
);
this._boundaryActionHandler("onSelect", this.get("computedValue"));
},
willDeselect() {
this.clearFilter();
this.set("highlightedValue", null);
},
didDeselect() {
didDeselect(rowComputedContentItem) {
this.collapse();
this.focus();
this._boundaryActionHandler("onDeselect", rowComputedContentItem);
},
clearFilter() {
@ -234,28 +244,40 @@ export default Ember.Component.extend(UtilsMixin, PluginApiMixin, DomHelpersMixi
this.set("headerComputedContent", headerComputedContent);
},
_boundaryActionHandler(actionName, ...params) {
if (Ember.get(this.actions, actionName)) {
this.send(actionName, ...params);
} else if (this.get(actionName)) {
this.get(actionName)();
}
},
actions: {
onToggle() {
if (this.get("onToggle")) this.sendAction("onToggle");
if (this.get("onCollapse") && this.get("isExpanded") === true) this.sendAction("onCollapse");
if (this.get("onExpand") && this.get("isExpanded") === false) this.sendAction("onExpand");
toggle() {
this._boundaryActionHandler("onToggle", this);
this.get("isExpanded") === true ? this.collapse() : this.expand();
this._setHeaderComputedContent();
if (this.get("isExpanded")) {
this._boundaryActionHandler("onCollapse", this);
this.collapse();
} else {
this._boundaryActionHandler("onExpand", this);
this.expand();
}
},
onHighlight(rowComputedContent) {
highlight(rowComputedContent) {
this.set("highlightedValue", rowComputedContent.value);
this._boundaryActionHandler("onHighlight", rowComputedContent);
},
onFilter(filter) {
filterComputedContent(filter) {
this.setProperties({
highlightedValue: null,
renderedFilterOnce: true,
filter
});
this.autoHighlight();
this._boundaryActionHandler("onFilter", filter);
}
}
});

View File

@ -2,9 +2,5 @@ import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-r
export default SelectKitRowComponent.extend({
layoutName: "select-kit/templates/components/select-kit/select-kit-row",
classNames: "create",
click() {
this.sendAction("onCreate", this.get("computedContent"));
},
classNames: "create"
});

View File

@ -37,6 +37,6 @@ export default Ember.Component.extend({
},
click() {
this.sendAction("onToggle");
this.sendAction("toggle");
}
});

View File

@ -5,6 +5,6 @@ export default SelectKitRowComponent.extend({
classNames: "none",
click() {
this.sendAction("onClear");
this.sendAction("clearSelection");
}
});

View File

@ -57,14 +57,14 @@ export default Ember.Component.extend(UtilsMixin, {
},
mouseEnter() {
this.set("hoverDebounce", run.debounce(this, this._sendOnHighlightAction, 32));
this.set("hoverDebounce", run.debounce(this, this._sendHighlightAction, 32));
},
click() {
this.sendAction("onSelect", this.get("computedContent"));
this.sendAction("select", this.get("computedContent"));
},
_sendOnHighlightAction() {
this.sendAction("onHighlight", this.get("computedContent"));
_sendHighlightAction() {
this.sendAction("highlight", this.get("computedContent"));
}
});

View File

@ -2,9 +2,6 @@ import SelectKitComponent from "select-kit/components/select-kit";
import { on } from "ember-addons/ember-computed-decorators";
import computed from "ember-addons/ember-computed-decorators";
const { get, isNone, isEmpty, isPresent, run } = Ember;
import {
applyOnSelectPluginApiCallbacks
} from "select-kit/mixins/plugin-api";
export default SelectKitComponent.extend({
pluginApiIdentifiers: ["single-select"],
@ -26,10 +23,11 @@ export default SelectKitComponent.extend({
value = this._beforeDidComputeValue(value);
this.didComputeContent(content);
this.didComputeValue(value);
this._setHeaderComputedContent();
this.didComputeAttributes();
if (this.get("allowInitialValueMutation")) this.mutateAttributes();
this._setHeaderComputedContent();
});
},
@ -39,7 +37,6 @@ export default SelectKitComponent.extend({
run.next(() => {
this.mutateContent(this.get("computedContent"));
this.mutateValue(this.get("computedValue"));
applyOnSelectPluginApiCallbacks(this.get("pluginApiIdentifiers"), this.get("computedValue"), this);
this._setHeaderComputedContent();
});
},
@ -119,23 +116,23 @@ export default SelectKitComponent.extend({
const none = this.get("noneRowComputedContent");
if (this.get("hasSelection") && isEmpty(this.get("filter"))) {
this.send("onHighlight", this.get("selectedComputedContent"));
this.send("highlight", this.get("selectedComputedContent"));
return;
}
if (isNone(this.get("highlightedValue")) && !isEmpty(filteredComputedContent)) {
this.send("onHighlight", get(filteredComputedContent, "firstObject"));
this.send("highlight", get(filteredComputedContent, "firstObject"));
return;
}
if (displayCreateRow === true && isEmpty(filteredComputedContent)) {
this.send("onHighlight", this.get("createRowComputedContent"));
this.send("highlight", this.get("createRowComputedContent"));
}
else if (!isEmpty(filteredComputedContent)) {
this.send("onHighlight", get(filteredComputedContent, "firstObject"));
this.send("highlight", get(filteredComputedContent, "firstObject"));
}
else if (isEmpty(filteredComputedContent) && isPresent(none) && displayCreateRow === false) {
this.send("onHighlight", none);
this.send("highlight", none);
}
});
},
@ -145,25 +142,29 @@ export default SelectKitComponent.extend({
},
actions: {
onClear() {
this.send("onDeselect", this.get("selectedComputedContent"));
clearSelection() {
this.send("deselect", this.get("selectedComputedContent"));
this._boundaryActionHandler("onClearSelection");
},
onCreate(computedContentItem) {
create(computedContentItem) {
if (this.validateComputedContentItem(computedContentItem)) {
this.get("computedContent").pushObject(computedContentItem);
this.send("onSelect", computedContentItem);
this._boundaryActionHandler("onCreate");
this.send("select", computedContentItem);
} else {
this._boundaryActionHandler("onCreateFailure");
}
},
onSelect(rowComputedContentItem) {
select(rowComputedContentItem) {
this.willSelect(rowComputedContentItem);
this.set("computedValue", rowComputedContentItem.value);
this.mutateAttributes();
run.schedule("afterRender", () => this.didSelect(rowComputedContentItem));
},
onDeselect(rowComputedContentItem) {
deselect(rowComputedContentItem) {
this.willDeselect(rowComputedContentItem);
this.set("computedValue", null);
this.mutateAttributes();

View File

@ -45,7 +45,7 @@ export default ComboBoxComponent.extend({
return;
}
const refresh = () => this.send("onDeselect", value);
const refresh = () => this.send("deselect", value);
switch(value) {
case "invite":

View File

@ -80,11 +80,13 @@ export default Ember.Mixin.create({
this.setProperties({ isExpanded: true, renderedBodyOnce: true, isFocused: true });
this.focusFilterOrHeader();
this.autoHighlight();
this._setHeaderComputedContent();
},
collapse() {
this.set("isExpanded", false);
Ember.run.schedule("afterRender", () => this._removeFixedPosition() );
this._setHeaderComputedContent();
},
// lose focus of the component in two steps

View File

@ -95,7 +95,7 @@ export default Ember.Mixin.create({
this.$filterInput()
.on("change.select-kit", (event) => {
this.send("onFilter", $(event.target).val());
this.send("filterComputedContent", $(event.target).val());
})
.on("keypress.select-kit", (event) => {
event.stopPropagation();

View File

@ -5,7 +5,7 @@
</span>
{{#if shouldDisplayClearableButton}}
<button class="btn-clear" {{action onClear bubbles=false}}>
<button class="btn-clear" {{action clearSelection bubbles=false}}>
{{d-icon 'times'}}
</button>
{{/if}}

View File

@ -15,7 +15,7 @@
{{/if}}
{{#if shouldDisplayClearableButton}}
<button class="btn-clear" {{action onClear bubbles=false}}>
<button class="btn-clear" {{action clearSelection bubbles=false}}>
{{d-icon 'times'}}
</button>
{{/if}}

View File

@ -1,10 +1,12 @@
<div class="choices">
{{#each computedContent.selectedComputedContents as |selectedComputedContent|}}
{{component selectedNameComponent onDeselect=onDeselect computedContent=selectedComputedContent}}
{{component selectedNameComponent
deselect=deselect
computedContent=selectedComputedContent}}
{{/each}}
<span class="filter choice" tabindex="-1">
{{component "select-kit/select-kit-filter"
onFilter=onFilter
filterComputedContent=filterComputedContent
shouldDisplayFilter=shouldDisplayFilter
isFocused=isFocused
filter=filter

View File

@ -1,5 +1,5 @@
<span class="name">
<span class="delete-icon" {{action onDeselect computedContent bubbles=false}}>
<span class="delete-icon" {{action deselect computedContent bubbles=false}}>
{{d-icon "times"}}
</span>

View File

@ -1,7 +1,7 @@
<div class="selected-color-wrapper">
<span class="name">
{{#unless isLocked}}
<span class="delete-icon" {{action onDeselect computedContent bubbles=false}}>
<span class="delete-icon" {{action deselect computedContent bubbles=false}}>
{{d-icon "times"}}
</span>
{{/unless}}

View File

@ -3,7 +3,7 @@
{{d-icon "lock"}}
</span>
{{else}}
<span class="locked-icon" {{action onDeselect computedContent bubbles=false}}>
<span class="locked-icon" {{action deselect computedContent bubbles=false}}>
{{d-icon "times"}}
</span>
{{/if}}

View File

@ -1,24 +1,24 @@
{{component headerComponent
tabindex=tabindex
shouldDisplayFilter=shouldDisplayFilter
isFocused=isFocused
isExpanded=isExpanded
computedContent=headerComputedContent
onDeselect=(action "onDeselect")
onToggle=(action "onToggle")
onFilter=(action "onFilter")
onClear=(action "onClear")
deselect=(action "deselect")
toggle=(action "toggle")
filterComputedContent=(action "filterComputedContent")
clearSelection=(action "clearSelection")
options=headerComponentOptions
shouldDisplayFilter=shouldDisplayFilter
}}
<div class="select-kit-body">
{{component filterComponent
onFilter=(action "onFilter")
filter=filter
icon=filterIcon
shouldDisplayFilter=shouldDisplayFilter
isFocused=isFocused
placeholder=(i18n filterPlaceholder)
filter=filter
isFocused=isFocused
filterComputedContent=(action "filterComputedContent")
}}
{{#if renderedBodyOnce}}
@ -34,10 +34,10 @@
templateForRow=templateForRow
templateForNoneRow=templateForNoneRow
templateForCreateRow=templateForCreateRow
onClear=(action "onClear")
onSelect=(action "onSelect")
onHighlight=(action "onHighlight")
onCreate=(action "onCreate")
clearSelection=(action "clearSelection")
select=(action "select")
highlight=(action "highlight")
create=(action "create")
noContentLabel=noContentLabel
highlightedValue=highlightedValue
computedValue=computedValue

View File

@ -10,8 +10,8 @@
computedContent=noneRowComputedContent
templateForRow=templateForNoneRow
highlightedValue=highlightedValue
onClear=onClear
onHighlight=onHighlight
clearSelection=clearSelection
highlight=highlight
computedValue=computedValue
options=rowComponentOptions
}}
@ -21,11 +21,11 @@
{{#if createRowComputedContent}}
{{component createRowComponent
computedContent=createRowComputedContent
templateForRow=templateForCreateRow
highlightedValue=highlightedValue
onHighlight=onHighlight
onCreate=onCreate
computedValue=computedValue
templateForRow=templateForCreateRow
highlight=highlight
select=create
options=rowComponentOptions
}}
{{/if}}
@ -33,11 +33,11 @@
{{#each filteredComputedContent as |computedContent|}}
{{component rowComponent
computedContent=computedContent
templateForRow=templateForRow
highlightedValue=highlightedValue
onSelect=onSelect
onHighlight=onHighlight
computedValue=computedValue
templateForRow=templateForRow
select=select
highlight=highlight
options=rowComponentOptions
}}
{{/each}}

View File

@ -2,7 +2,7 @@
tabindex=-1
class="filter-input"
placeholder=placeholder
key-up=onFilter
key-up=filterComputedContent
autocomplete="off"
autocorrect="off"
autocapitalize="off"

View File

@ -469,58 +469,6 @@ componentTest('with collection header', {
}
});
componentTest('with onToggle', {
template: '{{single-select onToggle=onToggle}}',
beforeEach() {
this.set("onToggle", () => $(".select-kit").append("<span class='onToggleTest'></span>"));
},
test(assert) {
andThen(() => assert.notOk(exists(".onToggleTest")));
this.get('subject').expand();
andThen(() => assert.ok(exists(".onToggleTest")));
}
});
componentTest('with onExpand', {
template: '{{single-select onExpand=onExpand}}',
beforeEach() {
this.set("onExpand", () => $(".select-kit").append("<span class='onExpandTest'></span>"));
},
test(assert) {
andThen(() => assert.notOk(exists(".onExpandTest")));
this.get('subject').expand();
andThen(() => assert.ok(exists(".onExpandTest")));
}
});
componentTest('with onCollapse', {
template: '{{single-select onCollapse=onCollapse}}',
beforeEach() {
this.set("onCollapse", () => $(".select-kit").append("<span class='onCollapseTest'></span>"));
},
test(assert) {
andThen(() => assert.notOk(exists(".onCollapseTest")));
this.get('subject').expand();
andThen(() => assert.notOk(exists(".onCollapseTest")));
this.get('subject').collapse();
andThen(() => assert.ok(exists(".onCollapseTest")));
}
});
componentTest('with title', {
template: '{{single-select title=(i18n "test.title")}}',

View File

@ -87,7 +87,7 @@ function selectKit(selector) { // eslint-disable-line no-unused-vars
var type = options.type || 'keydown';
var event = jQuery.Event(type);
event.keyCode = keyCode;
if (options && options.metaKey === true) { event.metaKey = true; }
if (options && options.metaKey) { event.metaKey = true; }
find(eventSelector).trigger(event);
});
}