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:
Joffrey JAFFEUX 2024-05-10 13:43:37 +02:00 committed by GitHub
parent 46371fe9e4
commit 47cabdc6d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 78 additions and 8 deletions

View File

@ -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();
});
}); });

View File

@ -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

View File

@ -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"

View File

@ -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",
}; };

View File

@ -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);
} }
} }
} }