Skip to content

Commit 54dc4ca

Browse files
jjaffeuxmartin-brennan
authored andcommitted
DEV: adds matchTriggerWidth/matchTriggerMinWidth d-menu (#34128)
The `@matchTriggerWidth` and `@matchTriggerMinWidth` options have been added on `<DMenu />` to give more control on the size of the content. They will allow to respectively set the width and minWidth of the content. This is useful if you want your trigger to have the same width than your content for example. It defaults to false. Usage: ```gjs <DMenu @Label="a long label" @matchTriggerWidth={{true}}>content</DMenu> <DMenu @Label="a long label" @matchTriggerMinWidth={{true}}>content</DMenu> ``` Also changes `FilterNavigationMenu` to use this. --------- Co-authored-by: Martin Brennan <martin@discourse.org>
1 parent 08fbf05 commit 54dc4ca

File tree

4 files changed

+65
-36
lines changed

4 files changed

+65
-36
lines changed

app/assets/javascripts/discourse/app/components/discovery/filter-navigation-menu.gjs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { fn } from "@ember/helper";
44
import { on } from "@ember/modifier";
55
import { action } from "@ember/object";
66
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
7-
import { cancel, schedule } from "@ember/runloop";
7+
import { cancel } from "@ember/runloop";
88
import { service } from "@ember/service";
99
import { TrackedObject } from "@ember-compat/tracked-built-ins";
1010
import { eq } from "truth-helpers";
@@ -15,7 +15,6 @@ import concatClass from "discourse/helpers/concat-class";
1515
import icon from "discourse/helpers/d-icon";
1616
import withEventValue from "discourse/helpers/with-event-value";
1717
import discourseDebounce from "discourse/lib/debounce";
18-
import { bind } from "discourse/lib/decorators";
1918
import FilterSuggestions from "discourse/lib/filter-suggestions";
2019
import { resettableTracked } from "discourse/lib/tracked-tools";
2120
import { i18n } from "discourse-i18n";
@@ -86,16 +85,6 @@ export default class FilterNavigationMenu extends Component {
8685

8786
@tracked _selectedIndex = -1;
8887

89-
constructor() {
90-
super(...arguments);
91-
window.addEventListener("resize", this.resizeDMenu);
92-
}
93-
94-
willDestroy() {
95-
super.willDestroy(...arguments);
96-
window.removeEventListener("resize", this.resizeDMenu);
97-
}
98-
9988
get selectedIndex() {
10089
return this._selectedIndex;
10190
}
@@ -387,12 +376,6 @@ export default class FilterNavigationMenu extends Component {
387376
async openFilterMenu() {
388377
if (this.dMenuInstance) {
389378
this.dMenuInstance.show();
390-
391-
// HACK: We don't have a nice way for DMenu to be the same width as
392-
// the input element, so we set it manually.
393-
schedule("afterRender", () => {
394-
this.resizeDMenu();
395-
});
396379
return;
397380
}
398381

@@ -401,26 +384,9 @@ export default class FilterNavigationMenu extends Component {
401384
component: FilterNavigationMenuList,
402385
data: this.trackedMenuListData,
403386
maxWidth: 2000,
387+
matchTriggerWidth: true,
404388
visibilityOptimizer: VISIBILITY_OPTIMIZERS.AUTO_PLACEMENT,
405389
});
406-
407-
// HACK: We don't have a nice way for DMenu to be the same width as
408-
// the input element, so we set it manually.
409-
schedule("afterRender", () => {
410-
this.resizeDMenu();
411-
});
412-
}
413-
414-
@bind
415-
resizeDMenu() {
416-
if (!this.inputElement || !this.dMenuInstance) {
417-
return;
418-
}
419-
420-
if (this.dMenuInstance.content) {
421-
this.dMenuInstance.content.style.width =
422-
this.inputElement.offsetWidth + "px";
423-
}
424390
}
425391

426392
@action

app/assets/javascripts/discourse/tests/integration/components/float-kit/d-menu-test.gjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,4 +581,42 @@ module("Integration | Component | FloatKit | d-menu", function (hooks) {
581581

582582
assert.dom("span.fk-d-menu__trigger").exists();
583583
});
584+
585+
test("@matchTriggerWidth", async function (assert) {
586+
await render(
587+
<template>
588+
<DMenu
589+
@label="a long label"
590+
@inline={{true}}
591+
@matchTriggerWidth={{true}}
592+
style="width: 200px;"
593+
>1</DMenu>
594+
</template>
595+
);
596+
597+
await open();
598+
599+
assert.dom(".fk-d-menu.-content").hasStyle({
600+
width: "200px",
601+
});
602+
});
603+
604+
test("@matchTriggerMinWidth", async function (assert) {
605+
await render(
606+
<template>
607+
<DMenu
608+
@label="a long label"
609+
@inline={{true}}
610+
@matchTriggerMinWidth={{true}}
611+
style="width: 200px;"
612+
>1</DMenu>
613+
</template>
614+
);
615+
616+
await open();
617+
618+
assert.dom(".fk-d-menu.-content").hasStyle({
619+
minWidth: "200px",
620+
});
621+
});
584622
});

app/assets/javascripts/float-kit/addon/lib/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export const MENU = {
8484
contentClass: null,
8585
class: null,
8686
updateOnScroll: true,
87+
matchTriggerMinWidth: false,
88+
matchTriggerWidth: false,
8789
},
8890
portalOutletId: "d-menu-portal-outlet",
8991
};

app/assets/javascripts/float-kit/addon/lib/update-position.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
limitShift,
99
offset,
1010
shift,
11+
size,
1112
} from "@floating-ui/dom";
1213
import domFromString from "discourse/lib/dom-from-string";
1314
import { isTesting } from "discourse/lib/environment";
@@ -95,6 +96,28 @@ export async function updatePosition(trigger, content, options) {
9596
middleware.push(hide({ padding: detectOverflowOptions.padding }));
9697
}
9798

99+
if (options.matchTriggerWidth) {
100+
middleware.push(
101+
size({
102+
apply({ rects, elements }) {
103+
Object.assign(elements.floating.style, {
104+
width: `${rects.reference.width}px`,
105+
});
106+
},
107+
})
108+
);
109+
} else if (options.matchTriggerMinWidth) {
110+
middleware.push(
111+
size({
112+
apply({ rects, elements }) {
113+
Object.assign(elements.floating.style, {
114+
minWidth: `${rects.reference.width}px`,
115+
});
116+
},
117+
})
118+
);
119+
}
120+
98121
content.dataset.strategy = options.strategy || "absolute";
99122

100123
const { x, y, placement, middlewareData } = await computePosition(

0 commit comments

Comments
 (0)