@@ -26,6 +26,7 @@ import '@vaadin/button';
2626import '@vaadin/popover' ;
2727import '@vaadin/vertical-layout' ;
2828import { Popover } from '@vaadin/popover' ;
29+ import { Button } from '@vaadin/button' ;
2930
3031@customElement ( 'vcf-toolbar-layout' )
3132export class VcfToolbarLayout extends ResizeMixin (
@@ -56,27 +57,28 @@ export class VcfToolbarLayout extends ResizeMixin(
5657 gap: var(--vcf-toolbar-layout-gap););
5758 }
5859
59- /* Overflow button is hidden unless needed */
60- [slot='overflow-button'] {
60+ ::slotted([slot="overflow-button"]) {
6161 display: none;
6262 }
63- [slot='overflow-button'].visible {
63+
64+ ::slotted([slot="overflow-button"].visible) {
6465 display: initial;
6566 }
6667
67- :host([reverse-collapse]) [slot='overflow-button'] {
68+ :host([reverse-collapse]) ::slotted( [slot='overflow-button']) {
6869 order: -1;
6970 }
7071 ` ;
7172 }
7273
7374 // overflow container is attached to the popover overlay (different shadow root) so we need to inject styles globally
74- protected readonly _overflowContainerStyles : string = `
75+ protected readonly _globalStyles : string = `
7576 /* Hide label on icon buttons */
7677 vcf-toolbar-layout vaadin-button[theme~="icon"]::part(label) {
7778 display: none;
7879 }
79-
80+
81+ /* Overflow container styles */
8082 .overflow-container {
8183 --overflow-container-padding: var(--lumo-space-s);
8284 --overflow-container-item-gap: var(--lumo-space-xs);
@@ -271,20 +273,20 @@ export class VcfToolbarLayout extends ResizeMixin(
271273 return ;
272274 }
273275
274- // get the overflow button
275- this . _overflowButton = this . shadowRoot . querySelector ( '[slot="overflow-button"]' ) as HTMLElement ;
276+ // get the overflow button (or create it)
277+ this . _overflowButton = this . querySelector ( '[slot="overflow-button"]' ) as HTMLElement ;
278+ if ( ! this . _overflowButton ) {
279+ this . _overflowButton = this . _createDefaultOverflowButton ( ) ;
280+ this . appendChild ( this . _overflowButton ) ;
281+ }
276282
277283 // setup overflow container
278284 this . _overflowContainer = document . createElement ( 'vaadin-vertical-layout' ) ;
279285 this . _overflowContainer . classList . add ( 'overflow-container' ) ;
280286
281287 // setup the popover
282288 let popover : Popover = this . shadowRoot . querySelector ( 'vaadin-popover' ) as Popover ;
283- popover . setAttribute ( 'for' , 'overflow-button' ) ;
284- popover . setAttribute ( "overlay-role" , "menu" ) ;
285- popover . setAttribute ( 'accessible-name-ref' , "overflowed menu items" ) ;
286- popover . setAttribute ( 'position' , 'bottom-start' ) ;
287- popover . setAttribute ( 'modal' , 'true' ) ;
289+ popover . target = this . _overflowButton ;
288290 popover . renderer = ( root : Element ) => {
289291 // Ensure content is only added once
290292 if ( ! root . firstChild ) {
@@ -297,24 +299,29 @@ export class VcfToolbarLayout extends ResizeMixin(
297299 setTimeout ( ( ) => this . _updateOverflowingItems ( ) , 0 ) ;
298300 }
299301
302+ protected _createDefaultOverflowButton ( ) {
303+ let button = document . createElement ( 'vaadin-button' ) as Button ;
304+ button . setAttribute ( 'slot' , 'overflow-button' ) ;
305+ button . setAttribute ( 'part' , 'overflow-button' ) ;
306+ button . setAttribute ( 'theme' , 'icon' ) ;
307+ button . setAttribute ( 'aria-label' , 'open menu' ) ;
308+ button . innerHTML = '<vaadin-icon icon="vaadin:ellipsis-dots-v" slot="suffix"></vaadin-icon>' ;
309+ return button ;
310+ }
311+
300312 render ( ) {
301313 return html `
302314 < slot > </ slot >
303315 < slot name ="menu "> </ slot >
304316 < slot name ="overflow-button "> </ slot >
305317
306- <!-- todo: move this to be dynamically created so dev can provide their own button if desired -->
307- < vaadin-button
308- id ="overflow-button "
309- part ="overflow-button "
310- slot ="overflow-button "
311- theme ="icon "
312- >
313- < vaadin-icon icon ="vaadin:ellipsis-dots-v "> </ vaadin-icon >
314- </ vaadin-button >
315318 < vaadin-popover
316319 part ="popover "
317320 theme ="no-padding ${ this . theme } "
321+ modal ="true "
322+ position ="bottom-start "
323+ overlay-role ="menu "
324+ accessible-name-ref ="overflowed menu items "
318325 > </ vaadin-popover >
319326 ` ;
320327 }
@@ -410,7 +417,7 @@ export class VcfToolbarLayout extends ResizeMixin(
410417 }
411418
412419 protected _getVisibleItems ( ) : Element [ ] {
413- return Array . from ( this . querySelectorAll ( ':scope > *' ) ) ;
420+ return Array . from ( this . querySelectorAll ( ':scope > *:not([slot="overflow-button"]) ' ) ) ;
414421 }
415422
416423 protected _getOverflowedItems ( ) : Element [ ] {
@@ -466,7 +473,7 @@ export class VcfToolbarLayout extends ResizeMixin(
466473
467474 const style = document . createElement ( 'style' ) ;
468475 style . id = styleId ;
469- style . textContent = this . _overflowContainerStyles ;
476+ style . textContent = this . _globalStyles ;
470477 document . head . appendChild ( style ) ;
471478 }
472479
0 commit comments