Skip to content

Commit 5311a13

Browse files
committed
fix: use custom Lit directive to render item component
1 parent dd378c0 commit 5311a13

File tree

1 file changed

+41
-15
lines changed

1 file changed

+41
-15
lines changed

packages/menu-bar/src/vaadin-menu-bar-mixin.js

+41-15
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Copyright (c) 2019 - 2025 Vaadin Ltd.
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
6-
import { html, nothing, render } from 'lit';
6+
import { html, noChange, nothing, render } from 'lit';
7+
import { Directive, directive } from 'lit/directive.js';
78
import { ifDefined } from 'lit/directives/if-defined.js';
89
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
910
import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
@@ -14,6 +15,37 @@ import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
1415
import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
1516
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
1617

18+
class ItemComponentDirective extends Directive {
19+
update(part, [{ component, text }]) {
20+
const { parentNode, startNode } = part;
21+
22+
const newNode = component || document.createTextNode(text);
23+
const oldNode = this.getOldNode(part);
24+
25+
if (oldNode === newNode) {
26+
return noChange;
27+
} else if (oldNode && newNode) {
28+
parentNode.replaceChild(newNode, oldNode);
29+
} else if (oldNode) {
30+
parentNode.removeChild(oldNode);
31+
} else if (newNode) {
32+
startNode.after(newNode);
33+
}
34+
35+
return noChange;
36+
}
37+
38+
getOldNode(part) {
39+
const { startNode, endNode } = part;
40+
if (startNode.nextSibling === endNode) {
41+
return;
42+
}
43+
return startNode.nextSibling;
44+
}
45+
}
46+
47+
const componentDirective = directive(ItemComponentDirective);
48+
1749
const DEFAULT_I18N = {
1850
moreOptions: 'More options',
1951
};
@@ -598,24 +630,18 @@ export const MenuBarMixin = (superClass) =>
598630

599631
/** @private */
600632
__renderButtons(items = []) {
601-
const renderContent = (item) => {
602-
if (item.component) {
603-
const component = this.__getComponent(item);
604-
item.component = component;
605-
// Save item for overflow menu
606-
component.item = item;
607-
return component;
608-
} else if (item.text) {
609-
return item.text;
610-
}
611-
};
612-
613633
render(
614634
html`
615635
${items.map((item) => {
616636
const itemCopy = { ...item };
617637
const hasChildren = Boolean(item && item.children);
618638
639+
if (itemCopy.component) {
640+
const component = this.__getComponent(itemCopy);
641+
itemCopy.component = component;
642+
component.item = itemCopy;
643+
}
644+
619645
return html`
620646
<vaadin-menu-bar-button
621647
.item="${itemCopy}"
@@ -624,8 +650,8 @@ export const MenuBarMixin = (superClass) =>
624650
aria-haspopup="${ifDefined(hasChildren ? 'true' : nothing)}"
625651
aria-expanded="${ifDefined(hasChildren ? 'false' : nothing)}"
626652
class="${ifDefined(item.className)}"
627-
theme="${ifDefined(this.__getButtonTheme(itemCopy, this._theme) || nothing)}"
628-
>${renderContent(itemCopy)}</vaadin-menu-bar-button
653+
theme="${ifDefined(this.__getButtonTheme(item, this._theme) || nothing)}"
654+
>${componentDirective(itemCopy)}</vaadin-menu-bar-button
629655
>
630656
`;
631657
})}

0 commit comments

Comments
 (0)