DEV: various improvements to d-menu (#26970)
- adds a `@groupIdentifier` property which will ensure that two menus of the same group are not expanded at the same time - adds a `@class` property which will be applied to the trigger and the content - adds a `@triggerClass` property which will be applied to the trigger - adds a `@contentClass` property which will be applied to the trigger - removes `extraClassName`
This commit is contained in:
parent
46371fe9e4
commit
47cabdc6d2
|
@ -278,4 +278,63 @@ module("Integration | Component | FloatKit | d-menu", function (hooks) {
|
||||||
|
|
||||||
assert.dom(".fk-d-menu__content.test-content").doesNotExist();
|
assert.dom(".fk-d-menu__content.test-content").doesNotExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("opening a menu with the same identifier", async function (assert) {
|
||||||
|
await render(
|
||||||
|
hbs`<DMenu @inline={{true}} @identifier="foo" @class="first">1</DMenu><DMenu @inline={{true}} @identifier="foo" @class="second">2</DMenu>`
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".first.fk-d-menu__trigger");
|
||||||
|
|
||||||
|
assert.dom(".foo-content.first").exists();
|
||||||
|
assert.dom(".foo-content.second").doesNotExist();
|
||||||
|
|
||||||
|
await click(".second.fk-d-menu__trigger");
|
||||||
|
|
||||||
|
assert.dom(".foo-content.first").doesNotExist();
|
||||||
|
assert.dom(".foo-content.second").exists();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("@groupIdentifier", async function (assert) {
|
||||||
|
await render(
|
||||||
|
hbs`<DMenu @inline={{true}} @groupIdentifier="foo" @class="first">1</DMenu><DMenu @inline={{true}} @groupIdentifier="foo" @class="second">2</DMenu>`
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".first.fk-d-menu__trigger");
|
||||||
|
|
||||||
|
assert.dom(".fk-d-menu__content.first").exists();
|
||||||
|
assert.dom(".fk-d-menu__content.second").doesNotExist();
|
||||||
|
|
||||||
|
await click(".second.fk-d-menu__trigger");
|
||||||
|
|
||||||
|
assert.dom(".fk-d-menu__content.first").doesNotExist();
|
||||||
|
assert.dom(".fk-d-menu__content.second").exists();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("@class", async function (assert) {
|
||||||
|
await render(hbs`<DMenu @inline={{true}} @class="first">1</DMenu>`);
|
||||||
|
|
||||||
|
await open();
|
||||||
|
|
||||||
|
assert.dom(".fk-d-menu__trigger.first").exists();
|
||||||
|
assert.dom(".fk-d-menu__content.first").exists();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("@triggerClass", async function (assert) {
|
||||||
|
await render(hbs`<DMenu @inline={{true}} @triggerClass="first">1</DMenu>`);
|
||||||
|
|
||||||
|
await open();
|
||||||
|
|
||||||
|
assert.dom(".fk-d-menu__trigger.first").exists();
|
||||||
|
assert.dom(".fk-d-menu__content.first").doesNotExist();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("@contentClass", async function (assert) {
|
||||||
|
await render(hbs`<DMenu @inline={{true}} @contentClass="first">1</DMenu>`);
|
||||||
|
|
||||||
|
await open();
|
||||||
|
|
||||||
|
assert.dom(".fk-d-menu__trigger.first").doesNotExist();
|
||||||
|
assert.dom(".fk-d-menu__content.first").exists();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,7 +59,6 @@ export default class DFloatBody extends Component {
|
||||||
@mainClass
|
@mainClass
|
||||||
(if this.options.animated "-animated")
|
(if this.options.animated "-animated")
|
||||||
(if @instance.expanded "-expanded")
|
(if @instance.expanded "-expanded")
|
||||||
this.options.extraClassName
|
|
||||||
}}
|
}}
|
||||||
data-identifier={{this.options.identifier}}
|
data-identifier={{this.options.identifier}}
|
||||||
data-content
|
data-content
|
||||||
|
|
|
@ -58,6 +58,7 @@ export default class DMenu extends Component {
|
||||||
(if this.menuInstance.expanded "-expanded")
|
(if this.menuInstance.expanded "-expanded")
|
||||||
(concat this.options.identifier "-trigger")
|
(concat this.options.identifier "-trigger")
|
||||||
@triggerClass
|
@triggerClass
|
||||||
|
@class
|
||||||
}}
|
}}
|
||||||
id={{this.menuInstance.id}}
|
id={{this.menuInstance.id}}
|
||||||
data-identifier={{this.options.identifier}}
|
data-identifier={{this.options.identifier}}
|
||||||
|
@ -83,6 +84,8 @@ export default class DMenu extends Component {
|
||||||
class={{concatClass
|
class={{concatClass
|
||||||
"fk-d-menu-modal"
|
"fk-d-menu-modal"
|
||||||
(concat this.options.identifier "-content")
|
(concat this.options.identifier "-content")
|
||||||
|
@contentClass
|
||||||
|
@class
|
||||||
}}
|
}}
|
||||||
@inline={{(isTesting)}}
|
@inline={{(isTesting)}}
|
||||||
data-identifier={{@instance.options.identifier}}
|
data-identifier={{@instance.options.identifier}}
|
||||||
|
@ -109,6 +112,8 @@ export default class DMenu extends Component {
|
||||||
"fk-d-menu"
|
"fk-d-menu"
|
||||||
"fk-d-menu__content"
|
"fk-d-menu__content"
|
||||||
(concat this.options.identifier "-content")
|
(concat this.options.identifier "-content")
|
||||||
|
@class
|
||||||
|
@contentClass
|
||||||
}}
|
}}
|
||||||
@innerClass="fk-d-menu__inner-content"
|
@innerClass="fk-d-menu__inner-content"
|
||||||
@role="dialog"
|
@role="dialog"
|
||||||
|
|
|
@ -65,12 +65,15 @@ export const MENU = {
|
||||||
fallbackPlacements: FLOAT_UI_PLACEMENTS,
|
fallbackPlacements: FLOAT_UI_PLACEMENTS,
|
||||||
autoUpdate: true,
|
autoUpdate: true,
|
||||||
trapTab: true,
|
trapTab: true,
|
||||||
extraClassName: null,
|
|
||||||
onClose: null,
|
onClose: null,
|
||||||
onShow: null,
|
onShow: null,
|
||||||
onRegisterApi: null,
|
onRegisterApi: null,
|
||||||
modalForMobile: false,
|
modalForMobile: false,
|
||||||
inline: null,
|
inline: null,
|
||||||
|
groupIdentifier: null,
|
||||||
|
triggerClass: null,
|
||||||
|
contentClass: null,
|
||||||
|
class: null,
|
||||||
},
|
},
|
||||||
portalOutletId: "d-menu-portal-outlet",
|
portalOutletId: "d-menu-portal-outlet",
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,9 @@ export default class Menu extends Service {
|
||||||
* @param {Object} [options.data] - An object which will be passed as the `@data` argument when content is a `Component`
|
* @param {Object} [options.data] - An object which will be passed as the `@data` argument when content is a `Component`
|
||||||
* @param {Boolean} [options.arrow] - Determines if the menu has an arrow
|
* @param {Boolean} [options.arrow] - Determines if the menu has an arrow
|
||||||
* @param {Boolean} [options.offset] - Displaces the content from its reference trigger in pixels
|
* @param {Boolean} [options.offset] - Displaces the content from its reference trigger in pixels
|
||||||
* @param {String} [options.identifier] - Add a data-identifier attribute to the trigger and the content
|
* @param {String} [options.identifier] - Add a data-identifier attribute to the trigger and the content, multiple menus can have the same identifier,
|
||||||
|
* only one menu with the same identifier can be open at a time
|
||||||
|
* @param {String} [options.groupIdentifier] - Only one menu with the same groupIdentifier can be open at a time
|
||||||
* @param {Boolean} [options.inline] - Improves positioning for trigger that spans over multiple lines
|
* @param {Boolean} [options.inline] - Improves positioning for trigger that spans over multiple lines
|
||||||
*
|
*
|
||||||
* @returns {Promise<DMenuInstance>}
|
* @returns {Promise<DMenuInstance>}
|
||||||
|
@ -47,13 +49,15 @@ export default class Menu extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.options.identifier) {
|
if (instance.options.identifier || instance.options.groupIdentifier) {
|
||||||
for (const menu of this.registeredMenus) {
|
for (const registeredMenu of this.registeredMenus) {
|
||||||
if (
|
if (
|
||||||
menu.options.identifier === instance.options.identifier &&
|
(registeredMenu.options.identifier === instance.options.identifier ||
|
||||||
menu !== instance
|
registeredMenu.options.groupIdentifier ===
|
||||||
|
instance.options.groupIdentifier) &&
|
||||||
|
registeredMenu !== instance
|
||||||
) {
|
) {
|
||||||
await this.close(menu);
|
await this.close(registeredMenu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue