context-menu: render toggle/selected menu items, rename internal dispatcher

- actions gain optional toggle + selected fields: items render in the shared
  tp-popup-menu-item checkmark style (icon faded unless selected/hovered)
- rename the private _onCtxAction dispatcher to _ctxItemClicked so a host
  method named _onCtxAction (the natural name for a ctx-action listener)
  no longer shadows it and breaks item clicks
This commit is contained in:
pk
2026-08-21 12:39:26 +02:00
parent 4158f88ae3
commit b9adc87306
2 changed files with 12 additions and 4 deletions
+11 -3
View File
@@ -19,7 +19,9 @@ import { html } from 'lit';
* 2. Call `this._openContextMenu(e, actions, context)` from a * 2. Call `this._openContextMenu(e, actions, context)` from a
* `contextmenu` event handler, where: * `contextmenu` event handler, where:
* - e: the original MouseEvent * - e: the original MouseEvent
* - actions: array of { label, action, icon?, disabled? } * - actions: array of { label, action, icon?, disabled?, toggle?, selected? }
* (`toggle: true` + `selected: boolean` renders the item in the
* shared checkmark style — icon faded unless selected/hovered)
* - context: arbitrary data passed through to the event detail * - context: arbitrary data passed through to the event detail
* 3. Include `${this._renderCtxMenu()}` somewhere in your render(). * 3. Include `${this._renderCtxMenu()}` somewhere in your render().
* 4. Listen for the `ctx-action` event on the host to handle actions: * 4. Listen for the `ctx-action` event on the host to handle actions:
@@ -27,6 +29,10 @@ import { html } from 'lit';
* *
* The mixin also dispatches a cancelable `ctx-open` event before showing * The mixin also dispatches a cancelable `ctx-open` event before showing
* the menu. Calling `e.preventDefault()` on it suppresses the menu. * the menu. Calling `e.preventDefault()` on it suppresses the menu.
*
* NOTE: name your event handler anything except `_onCtxAction` (or other
* mixin-internal names) — a method by that name on the host would shadow
* the mixin's own internals.
*/ */
export const ContextMenu = (superClass) => class ContextMenuHost extends superClass { export const ContextMenu = (superClass) => class ContextMenuHost extends superClass {
@@ -116,9 +122,11 @@ export const ContextMenu = (superClass) => class ContextMenuHost extends superCl
: html` : html`
<tp-popup-menu-item <tp-popup-menu-item
part="ctx-menu-item" part="ctx-menu-item"
class=${a.toggle ? 'toggle' : ''}
.icon=${a.icon || null} .icon=${a.icon || null}
?selected=${!!a.selected}
?disabled=${a.disabled} ?disabled=${a.disabled}
@click=${(e) => this._onCtxAction(a, context, e)}> @click=${(e) => this._ctxItemClicked(a, context, e)}>
${a.label} ${a.label}
</tp-popup-menu-item> </tp-popup-menu-item>
` `
@@ -132,7 +140,7 @@ export const ContextMenu = (superClass) => class ContextMenuHost extends superCl
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @private */ /** @private */
_onCtxAction(action, context, e) { _ctxItemClicked(action, context, e) {
e.stopPropagation(); e.stopPropagation();
this.dispatchEvent(new CustomEvent('ctx-action', { this.dispatchEvent(new CustomEvent('ctx-action', {
detail: { action: action.action, context, originalEvent: e }, detail: { action: action.action, context, originalEvent: e },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@tp/helpers", "name": "@tp/helpers",
"version": "2.13.0", "version": "2.14.0",
"description": "", "description": "",
"main": "closest.js", "main": "closest.js",
"scripts": { "scripts": {