From 6c16eb9a112e7d0e6edaf328ebdd32e61d632ca1 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Sat, 8 Aug 2020 15:45:32 -0400 Subject: [PATCH] Add slActivate/slDeactivate events to menu item --- src/components.d.ts | 8 ++++++++ src/components/dropdown/dropdown.tsx | 18 ++++++++---------- src/components/menu-item/menu-item.tsx | 13 ++++++++++++- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/components.d.ts b/src/components.d.ts index de22ee0e..57348b4f 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -1745,6 +1745,14 @@ declare namespace LocalJSX { * Set to true to draw the menu item in a disabled state. */ "disabled"?: boolean; + /** + * Emitted when the menu item becomes active. + */ + "onSlActivate"?: (event: CustomEvent) => void; + /** + * Emitted when the menu item becomes inactive. + */ + "onSlDeactivate"?: (event: CustomEvent) => void; /** * A unique value to store in the menu item. */ diff --git a/src/components/dropdown/dropdown.tsx b/src/components/dropdown/dropdown.tsx index ada93504..4920cce1 100644 --- a/src/components/dropdown/dropdown.tsx +++ b/src/components/dropdown/dropdown.tsx @@ -94,6 +94,7 @@ export class Dropdown { connectedCallback() { this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this); this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this); + this.handleMenuItemActivate = this.handleMenuItemActivate.bind(this); this.handlePanelSelect = this.handlePanelSelect.bind(this); this.handleTriggerKeyDown = this.handleTriggerKeyDown.bind(this); this.togglePanel = this.togglePanel.bind(this); @@ -141,6 +142,7 @@ export class Dropdown { this.popover.show(); this.ignoreOpenWatcher = false; + this.panel.addEventListener('slActivate', this.handleMenuItemActivate); this.panel.addEventListener('slSelect', this.handlePanelSelect); document.addEventListener('mousedown', this.handleDocumentMouseDown); document.addEventListener('keydown', this.handleDocumentKeyDown); @@ -163,6 +165,7 @@ export class Dropdown { this.popover.hide(); this.ignoreOpenWatcher = false; + this.panel.removeEventListener('slActivate', this.handleMenuItemActivate); this.panel.removeEventListener('slSelect', this.handlePanelSelect); document.removeEventListener('mousedown', this.handleDocumentMouseDown); document.removeEventListener('keydown', this.handleDocumentKeyDown); @@ -220,16 +223,6 @@ export class Dropdown { event.preventDefault(); menu.setFocus(); } - - // If a menu is present, ensure the active menu item stays in view when the selection changes - if (menu && ['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) { - const menuItems = [...menu.querySelectorAll('sl-menu-item')]; - const activeItem = menuItems.find(item => item.active); - - if (activeItem) { - scrollIntoView(activeItem, this.panel); - } - } } handleDocumentMouseDown(event: MouseEvent) { @@ -241,6 +234,11 @@ export class Dropdown { } } + handleMenuItemActivate(event: CustomEvent) { + const item = event.target as HTMLSlMenuItemElement; + scrollIntoView(item, this.panel); + } + handlePanelSelect(event: CustomEvent) { const target = event.target as HTMLElement; diff --git a/src/components/menu-item/menu-item.tsx b/src/components/menu-item/menu-item.tsx index f8aa613e..03da6ece 100644 --- a/src/components/menu-item/menu-item.tsx +++ b/src/components/menu-item/menu-item.tsx @@ -1,4 +1,4 @@ -import { Component, Prop, h } from '@stencil/core'; +import { Component, Event, EventEmitter, Prop, Watch, h } from '@stencil/core'; /** * @since 2.0 @@ -33,6 +33,17 @@ export class MenuItem { /** Set to true to draw the menu item in a disabled state. */ @Prop() disabled = false; + @Watch('active') + handleActiveChange() { + this.active ? this.slActivate.emit() : this.slDeactivate.emit(); + } + + /** Emitted when the menu item becomes active. */ + @Event() slActivate: EventEmitter; + + /** Emitted when the menu item becomes inactive. */ + @Event() slDeactivate: EventEmitter; + render() { return (