FEATURE: extend widget-dropdown to accept disabled option (#13020)

The widget should accept the disabled option.
In that case, CSS class "disabled".
In addition, after click dropdown will not be shown.

Also, the option to disable a specific value in a dropdown is included
This commit is contained in:
Krzysztof Kotlarek
2021-06-01 09:49:11 +10:00
committed by GitHub
parent 9ecd17b083
commit 73f11d568d
2 changed files with 46 additions and 5 deletions

View File

@@ -52,6 +52,7 @@ import { schedule } from "@ember/runloop";
- headerClass: adds css class to the dropdown header - headerClass: adds css class to the dropdown header
- bodyClass: adds css class to the dropdown header - bodyClass: adds css class to the dropdown header
- caret: adds a caret to visually enforce this is a dropdown - caret: adds a caret to visually enforce this is a dropdown
- disabled: adds disabled css class and lock dropdown
*/ */
export const WidgetDropdownHeaderClass = { export const WidgetDropdownHeaderClass = {
@@ -122,10 +123,12 @@ export const WidgetDropdownItemClass = {
}, },
buildClasses(attrs) { buildClasses(attrs) {
return [ const classes = [
"widget-dropdown-item", "widget-dropdown-item",
attrs.item === "separator" ? "separator" : `item-${attrs.item.id}`, attrs.item === "separator" ? "separator" : `item-${attrs.item.id}`,
].join(" "); ];
classes.push(attrs.item.disabled ? "disabled" : "");
return classes.join(" ");
}, },
keyDown(event) { keyDown(event) {
@@ -199,21 +202,24 @@ export const WidgetDropdownClass = {
return { id: attrs.id }; return { id: attrs.id };
}, },
defaultState() { defaultState(attrs) {
return { return {
opened: false, opened: false,
disabled: (attrs.options && attrs.options.disabled) || false,
}; };
}, },
buildClasses(attrs) { buildClasses(attrs) {
const classes = ["widget-dropdown"]; const classes = ["widget-dropdown"];
classes.push(this.state.opened ? "opened" : "closed"); classes.push(this.state.opened ? "opened" : "closed");
classes.push(this.state.disabled ? "disabled" : "");
return classes.join(" ") + " " + (attrs.class || ""); return classes.join(" ") + " " + (attrs.class || "");
}, },
transform(attrs) { transform(attrs) {
return { return {
options: attrs.options || {}, options: attrs.options || {},
isDropdownVisible: !this.state.disabled && this.state.opened,
}; };
}, },
@@ -222,6 +228,9 @@ export const WidgetDropdownClass = {
}, },
_onChange(params) { _onChange(params) {
if (params.disabled) {
return;
}
this.state.opened = false; this.state.opened = false;
if (this.attrs.onChange) { if (this.attrs.onChange) {
@@ -264,7 +273,7 @@ export const WidgetDropdownClass = {
} }
this._popper = createPopper(dropdownHeader, dropdownBody, { this._popper = createPopper(dropdownHeader, dropdownBody, {
strategy: "fixed", strategy: "absolute",
placement: "bottom-start", placement: "bottom-start",
modifiers: [ modifiers: [
{ {
@@ -299,7 +308,7 @@ export const WidgetDropdownClass = {
) )
}} }}
{{#if this.state.opened}} {{#if this.transformed.isDropdownVisible}}
{{attach {{attach
widget="widget-dropdown-body" widget="widget-dropdown-body"
attrs=(hash attrs=(hash

View File

@@ -17,6 +17,7 @@ const DEFAULT_CONTENT = {
"separator", "separator",
{ id: 3, translatedLabel: "With icon", icon: "times" }, { id: 3, translatedLabel: "With icon", icon: "times" },
{ id: 4, html: "<b>baz</b>" }, { id: 4, html: "<b>baz</b>" },
{ id: 5, translatedLabel: "Disabled", disabled: true },
], ],
label: "foo", label: "foo",
}; };
@@ -346,5 +347,36 @@ discourseModule(
); );
}, },
}); });
componentTest("disabled widget", {
template: TEMPLATE,
beforeEach() {
this.setProperties(DEFAULT_CONTENT);
this.set("options", { disabled: true });
},
test(assert) {
assert.ok(exists("#my-dropdown.disabled"));
},
async test(assert) {
await toggle();
assert.equal(rowById(1), undefined, "it does not display options");
},
});
componentTest("disabled item", {
template: TEMPLATE,
beforeEach() {
this.setProperties(DEFAULT_CONTENT);
},
async test(assert) {
await toggle();
assert.ok(exists(".widget-dropdown-item.item-5.disabled"));
},
});
} }
); );