@eclipse-docks/core 0.7.126 → 0.7.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/api/index.js +4 -4
  2. package/dist/api/services.d.ts +2 -0
  3. package/dist/api/services.d.ts.map +1 -1
  4. package/dist/{api-B3RXoez_.js → api-Da9zQcfd.js} +186 -36
  5. package/dist/api-Da9zQcfd.js.map +1 -0
  6. package/dist/components/command.d.ts +4 -4
  7. package/dist/components/command.d.ts.map +1 -1
  8. package/dist/components/filebrowser.d.ts.map +1 -1
  9. package/dist/core/contribution-names.d.ts +0 -2
  10. package/dist/core/contribution-names.d.ts.map +1 -1
  11. package/dist/core/contributionregistry.d.ts +3 -0
  12. package/dist/core/contributionregistry.d.ts.map +1 -1
  13. package/dist/core/dropdown-item.d.ts +35 -0
  14. package/dist/core/dropdown-item.d.ts.map +1 -0
  15. package/dist/core/dropdown-menu-utils.d.ts +5 -0
  16. package/dist/core/dropdown-menu-utils.d.ts.map +1 -1
  17. package/dist/index.js +4 -4
  18. package/dist/parts/contextmenu.d.ts +5 -2
  19. package/dist/parts/contextmenu.d.ts.map +1 -1
  20. package/dist/parts/index.d.ts.map +1 -1
  21. package/dist/parts/index.js +1 -1
  22. package/dist/parts/part.d.ts +2 -0
  23. package/dist/parts/part.d.ts.map +1 -1
  24. package/dist/{parts-CsoNFVTw.js → parts-CRVxaDd-.js} +184 -262
  25. package/dist/parts-CRVxaDd-.js.map +1 -0
  26. package/dist/{widget-DbLusgAH.js → widget-BqQtioK1.js} +11 -5
  27. package/dist/widget-BqQtioK1.js.map +1 -0
  28. package/dist/widgets/index.js +1 -1
  29. package/dist/{widgets-DnnSZhsi.js → widgets-C9V42Mqq.js} +2 -2
  30. package/dist/{widgets-DnnSZhsi.js.map → widgets-C9V42Mqq.js.map} +1 -1
  31. package/package.json +1 -1
  32. package/src/api/services.ts +8 -0
  33. package/src/commands/filebrowser-contributions.ts +0 -16
  34. package/src/components/command.ts +45 -113
  35. package/src/components/filebrowser.ts +15 -12
  36. package/src/core/contribution-names.ts +0 -3
  37. package/src/core/contributionregistry.ts +19 -3
  38. package/src/core/dropdown-item.ts +152 -0
  39. package/src/core/dropdown-menu-utils.ts +59 -0
  40. package/src/parts/contextmenu.ts +38 -44
  41. package/src/parts/index.ts +4 -1
  42. package/src/parts/part.ts +2 -0
  43. package/dist/api-B3RXoez_.js.map +0 -1
  44. package/dist/parts-CsoNFVTw.js.map +0 -1
  45. package/dist/widget-DbLusgAH.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { n as defaultLogger, o as rootContext, s as uiContext, t as createLogger } from "./logger-DT0_NW3S.js";
2
- import { C as toastError, _ as getContributionDisabled, a as TOPIC_COMMAND_REGISTERED, b as contributionTargetMappingRegistry, f as activeTasksSignal, g as contributionRegistry, h as TOPIC_CONTRIBUTEIONS_CHANGED, l as activeEditorSignal, n as watchSignal, o as commandRegistry, p as partDirtySignal, t as DocksWidget, u as activePartSignal, v as getContributionVisible, w as toastInfo } from "./widget-DbLusgAH.js";
2
+ import { T as toastInfo, _ as getContributionDisabled, a as TOPIC_COMMAND_REGISTERED, f as activeTasksSignal, g as contributionRegistry, h as TOPIC_CONTRIBUTEIONS_CHANGED, l as activeEditorSignal, n as watchSignal, o as commandRegistry, p as partDirtySignal, t as DocksWidget, u as activePartSignal, v as getContributionVisible, w as toastError, x as contributionTargetMappingRegistry, y as readReactiveBoolean } from "./widget-BqQtioK1.js";
3
3
  import { n as subscribe, t as publish } from "./events-B_ZxkU_G.js";
4
4
  import { a as File, i as Directory, l as TOPIC_WORKSPACE_CHANGED, m as persistenceService, o as FileContentType, p as workspaceService } from "./fs-access-DTXPsV1W.js";
5
5
  import "./webawesome-Y1_HnKa_.js";
@@ -3040,6 +3040,74 @@ function versionInfoDialog() {
3040
3040
  return dialogService.open("version-info", { label: `About ${app?.name ?? ""} - ${app?.version ?? "0.0.0"}` });
3041
3041
  }
3042
3042
  //#endregion
3043
+ //#region src/core/dropdown-menu-utils.ts
3044
+ function isOpenDropdown(element) {
3045
+ if (element.localName !== "wa-dropdown") return false;
3046
+ const dropdown = element;
3047
+ return dropdown.open === true || dropdown.hasAttribute("open");
3048
+ }
3049
+ function elementsFromEventPath(event) {
3050
+ const fromComposedPath = event.composedPath().filter((node) => node instanceof Element);
3051
+ if (fromComposedPath.length > 0) return fromComposedPath;
3052
+ if (!(event.target instanceof Element)) return [];
3053
+ const path = [];
3054
+ let current = event.target;
3055
+ while (current) {
3056
+ path.push(current);
3057
+ const root = current.getRootNode();
3058
+ if (root instanceof ShadowRoot) {
3059
+ current = root.host;
3060
+ continue;
3061
+ }
3062
+ current = current.parentElement;
3063
+ }
3064
+ return path;
3065
+ }
3066
+ function elementTargetsOpenDropdown(element) {
3067
+ if (isOpenDropdown(element)) return true;
3068
+ if (element.localName !== "wa-dropdown-item") return false;
3069
+ const dropdown = element.closest("wa-dropdown");
3070
+ if (dropdown && isOpenDropdown(dropdown)) return true;
3071
+ const root = element.getRootNode();
3072
+ return root instanceof ShadowRoot && root.host instanceof Element && isOpenDropdown(root.host);
3073
+ }
3074
+ /** True when the event occurred inside a wa-dropdown that is currently open. */
3075
+ function eventTargetsOpenDropdown(event) {
3076
+ return elementsFromEventPath(event).some(elementTargetsOpenDropdown);
3077
+ }
3078
+ /** Prevents the browser context menu on open Docks popup lists (context menus, toolbar dropdowns). */
3079
+ function suppressNativeContextMenuInOpenDropdowns(event) {
3080
+ if (!event.cancelable || !eventTargetsOpenDropdown(event)) return;
3081
+ event.preventDefault();
3082
+ }
3083
+ var openDropdownContextMenuGuardInstalled = false;
3084
+ function installOpenDropdownNativeContextMenuGuard() {
3085
+ if (openDropdownContextMenuGuardInstalled || typeof document === "undefined") return;
3086
+ openDropdownContextMenuGuardInstalled = true;
3087
+ document.addEventListener("contextmenu", suppressNativeContextMenuInOpenDropdowns, { capture: true });
3088
+ }
3089
+ function visitElementTree(root, visit) {
3090
+ if (root instanceof Element) {
3091
+ visit(root);
3092
+ if (root.shadowRoot) visitElementTree(root.shadowRoot, visit);
3093
+ for (const child of root.children) visitElementTree(child, visit);
3094
+ } else if (root instanceof DocumentFragment) for (const child of root.children) visitElementTree(child, visit);
3095
+ }
3096
+ /** Collect wa-dropdown-item elements under a menu root, including shadow DOM. */
3097
+ function collectDropdownItems(root) {
3098
+ const items = [];
3099
+ visitElementTree(root, (element) => {
3100
+ if (element.localName === "wa-dropdown-item") items.push(element);
3101
+ });
3102
+ return items;
3103
+ }
3104
+ /** Close every open submenu except the one being activated. */
3105
+ function closeSiblingSubmenus(activeItem, menuRoot) {
3106
+ queueMicrotask(() => {
3107
+ for (const item of collectDropdownItems(menuRoot)) if (item !== activeItem && item.submenuOpen) item.submenuOpen = false;
3108
+ });
3109
+ }
3110
+ //#endregion
3043
3111
  //#region src/core/icon-utils.ts
3044
3112
  /**
3045
3113
  * Parses an icon spec string into `{ library, name }` for use with `wa-icon`.
@@ -3276,236 +3344,99 @@ _decorate([state()], DocksToolbar.prototype, "contributions", void 0);
3276
3344
  _decorate([state()], DocksToolbar.prototype, "compact", void 0);
3277
3345
  DocksToolbar = _decorate([customElement("docks-toolbar")], DocksToolbar);
3278
3346
  //#endregion
3279
- //#region src/core/dropdown-menu-utils.ts
3280
- function visitElementTree(root, visit) {
3281
- if (root instanceof Element) {
3282
- visit(root);
3283
- if (root.shadowRoot) visitElementTree(root.shadowRoot, visit);
3284
- for (const child of root.children) visitElementTree(child, visit);
3285
- } else if (root instanceof DocumentFragment) for (const child of root.children) visitElementTree(child, visit);
3347
+ //#region src/core/dropdown-item.ts
3348
+ /**
3349
+ * Shared render helpers for {@link https://webawesome.com/docs/components/dropdown-item | wa-dropdown-item}
3350
+ * rows inside any Docks popup list.
3351
+ *
3352
+ * **Docks surfaces** (distinct UX and contribution targets):
3353
+ * - **Toolbar dropdown** — anchored to a toolbar control (`docks-command`, `docks-toolbar`).
3354
+ * Part-level registry targets use the `toolbar:` prefix (e.g. `toolbar:view.filebrowser`).
3355
+ * - **Context menu** — opened at the pointer (`docks-contextmenu`).
3356
+ * Part-level registry targets use the `contextmenu:` prefix (e.g. `contextmenu:view.filebrowser`).
3357
+ *
3358
+ * A part can expose both surfaces with the same part id but different prefixes, registering
3359
+ * different contributions on each. Feature-scoped targets (e.g. `filebrowser.create`) may also
3360
+ * be referenced explicitly from either surface when several controls share the same item set.
3361
+ */
3362
+ function closeParentDropdown(event) {
3363
+ const dropdown = event.target?.closest("wa-dropdown");
3364
+ if (dropdown && dropdown.open !== void 0) dropdown.open = false;
3286
3365
  }
3287
- /** Collect wa-dropdown-item elements under a menu root, including shadow DOM. */
3288
- function collectDropdownItems(root) {
3289
- const items = [];
3290
- visitElementTree(root, (element) => {
3291
- if (element.localName === "wa-dropdown-item") items.push(element);
3292
- });
3293
- return items;
3366
+ function onDropdownItemClick(options) {
3367
+ return (event) => {
3368
+ if (readReactiveBoolean(options.disabled, false)) return;
3369
+ event.stopPropagation();
3370
+ closeParentDropdown(event);
3371
+ if (options.action) {
3372
+ options.action(event);
3373
+ return;
3374
+ }
3375
+ if (options.cmd) commandRegistry.execute(options.cmd, commandRegistry.createExecutionContext(options.params ?? {}));
3376
+ };
3294
3377
  }
3295
- /** Close every open submenu except the one being activated. */
3296
- function closeSiblingSubmenus(activeItem, menuRoot) {
3297
- queueMicrotask(() => {
3298
- for (const item of collectDropdownItems(menuRoot)) if (item !== activeItem && item.submenuOpen) item.submenuOpen = false;
3378
+ function keybindingDetails(cmd) {
3379
+ if (!cmd) return nothing;
3380
+ const bindings = keyBindingManager.getKeyBindingsForCommand(cmd);
3381
+ if (bindings.length === 0) return nothing;
3382
+ return html`<span slot="details">${bindings[0]}</span>`;
3383
+ }
3384
+ /** Renders a native {@link https://webawesome.com/docs/components/dropdown-item | wa-dropdown-item}. */
3385
+ function renderDropdownItem(options) {
3386
+ const iconSpec = options.icon ?? "";
3387
+ return html`
3388
+ <wa-dropdown-item
3389
+ slot=${options.slot ?? nothing}
3390
+ variant=${options.variant ?? "default"}
3391
+ ?disabled=${readReactiveBoolean(options.disabled, false)}
3392
+ @click=${onDropdownItemClick(options)}>
3393
+ ${iconSpec ? icon(iconSpec, {
3394
+ label: options.title ?? options.label,
3395
+ slot: "icon"
3396
+ }) : nothing}
3397
+ ${options.label}
3398
+ ${keybindingDetails(options.cmd)}
3399
+ </wa-dropdown-item>
3400
+ `;
3401
+ }
3402
+ function renderCommandContribution(contribution, options) {
3403
+ if (!getContributionVisible(contribution)) return nothing;
3404
+ return renderDropdownItem({
3405
+ cmd: contribution.command,
3406
+ icon: contribution.icon,
3407
+ label: contribution.label,
3408
+ params: contribution.params,
3409
+ disabled: contribution.disabled,
3410
+ slot: options?.slot
3299
3411
  });
3300
3412
  }
3301
- //#endregion
3302
- //#region src/components/command.ts
3303
- var DocksCommand = class DocksCommand extends DocksWidget {
3304
- constructor(..._args) {
3305
- super(..._args);
3306
- this.cmd = "";
3307
- this.title = "";
3308
- this.label = false;
3309
- this.disabled = false;
3310
- this.appearance = "plain";
3311
- this.variant = "neutral";
3312
- this.size = "s";
3313
- this.params = {};
3314
- this.withCaret = true;
3315
- this.placement = "bottom-start";
3316
- this.dropdownContributions = [];
3317
- }
3318
- closeDropdown(dropdown) {
3319
- if (dropdown && dropdown.open !== void 0) dropdown.open = false;
3320
- }
3321
- closeParentDropdown() {
3322
- this.closeDropdown(this.closest("wa-dropdown"));
3323
- }
3324
- handleClick(event) {
3325
- if (this.disabled) return;
3326
- if (event) event.stopPropagation();
3327
- this.closeParentDropdown();
3328
- if (this.action) {
3329
- this.action(event);
3330
- return;
3331
- }
3332
- if (this.cmd) this.executeCommand(this.cmd, this.params);
3333
- }
3334
- handleSelect(event) {
3335
- this.closeDropdown(event.target);
3336
- }
3337
- isInDropdown() {
3338
- return !!this.closest("wa-dropdown, wa-dropdown-menu");
3339
- }
3340
- getKeybinding() {
3341
- if (!this.cmd || this.action) return null;
3342
- const keybindings = keyBindingManager.getKeyBindingsForCommand(this.cmd);
3343
- return keybindings.length > 0 ? keybindings[0] : null;
3344
- }
3345
- doBeforeUI() {
3346
- if (this.dropdown) {
3347
- this.dropdownContributions = contributionRegistry.getContributions(this.dropdown);
3348
- subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event) => {
3349
- if (this.dropdown && event.target === this.dropdown) this.dropdownContributions = event.contributions;
3350
- });
3351
- }
3352
- }
3353
- willUpdate(changedProperties) {
3354
- super.willUpdate?.(changedProperties);
3355
- if (this.dropdown && changedProperties.has("dropdown")) this.dropdownContributions = contributionRegistry.getContributions(this.dropdown);
3356
- }
3357
- renderContribution(contribution, slot) {
3358
- if ("command" in contribution) {
3359
- const commandContribution = contribution;
3360
- if (!getContributionVisible(commandContribution)) return nothing;
3361
- const disabled = getContributionDisabled(commandContribution);
3362
- return html`
3363
- <docks-command
3364
- slot=${slot ?? nothing}
3365
- cmd="${commandContribution.command}"
3366
- icon="${commandContribution.icon || ""}"
3367
- .params=${commandContribution.params || {}}
3368
- ?disabled="${disabled}">
3369
- ${commandContribution.label}
3370
- </docks-command>
3371
- `;
3372
- }
3373
- if ("component" in contribution) {
3374
- const contents = contribution.component;
3375
- if (contents instanceof Function) return contents();
3376
- return unsafeHTML(contents);
3377
- }
3378
- return nothing;
3379
- }
3380
- render() {
3381
- const keybinding = this.getKeybinding();
3382
- if (this.isInDropdown() && this.dropdown) return html`
3383
- <wa-dropdown-item ?disabled=${this.disabled}>
3384
- ${icon(this.icon, {
3385
- label: this.title,
3386
- slot: "icon"
3387
- })}
3388
- <slot></slot>
3389
- ${this.dropdownContributions.map((c) => this.renderContribution(c, "submenu"))}
3390
- </wa-dropdown-item>
3391
- `;
3392
- if (this.isInDropdown()) return html`
3393
- <wa-dropdown-item
3394
- ?disabled=${this.disabled}
3395
- @click=${(e) => this.handleClick(e)}>
3396
- ${icon(this.icon, {
3397
- label: this.title,
3398
- slot: "icon"
3399
- })}
3400
- <slot></slot>
3401
- ${keybinding ? html`<span class="keybinding">${keybinding}</span>` : ""}
3402
- </wa-dropdown-item>
3403
- `;
3404
- if (this.dropdown) return html`
3405
- <wa-dropdown
3406
- placement=${this.placement}
3407
- @wa-select=${(e) => this.handleSelect(e)}>
3408
- <wa-button
3409
- slot="trigger"
3410
- appearance=${this.appearance}
3411
- variant=${this.variant}
3412
- size=${this.size}
3413
- ?disabled=${this.disabled}
3414
- ?with-caret=${this.withCaret}
3415
- title=${keybinding ? `${this.title} (${keybinding})` : this.title}>
3416
- ${icon(this.icon, {
3417
- label: this.title,
3418
- slot: "start"
3419
- })}
3420
- <slot></slot>
3421
- ${this.label ? this.title : nothing}
3422
- </wa-button>
3423
-
3424
- ${this.title ? html`
3425
- <h6 style="padding: var(--wa-space-xs) var(--wa-space-s); margin: 0; color: var(--wa-color-neutral-50); font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;">
3426
- ${this.title}
3427
- </h6>
3428
- ` : nothing}
3429
-
3430
- ${this.dropdownContributions.map((c) => this.renderContribution(c))}
3431
-
3432
- ${this.cmd ? html`
3433
- <wa-divider></wa-divider>
3434
- <docks-command
3435
- cmd="${this.cmd}"
3436
- icon="${this.icon || ""}"
3437
- .params=${this.params}
3438
- ?disabled=${this.disabled}>
3439
- <slot></slot>
3440
- ${this.title}
3441
- </docks-command>
3442
- ` : nothing}
3443
- </wa-dropdown>
3444
- `;
3445
- return html`
3446
- <wa-button
3447
- appearance=${this.appearance}
3448
- variant=${this.variant}
3449
- size=${this.size}
3450
- ?disabled=${this.disabled}
3451
- title=${keybinding ? `${this.title} (${keybinding})` : this.title}
3452
- @click=${(e) => this.handleClick(e)}>
3453
- ${icon(this.icon, {
3454
- label: this.title,
3455
- slot: "start"
3456
- })}
3457
- <slot></slot>
3458
- </wa-button>
3459
- `;
3460
- }
3461
- static {
3462
- this.styles = css`
3463
- :host {
3464
- display: inline-block;
3465
- }
3466
-
3467
- .keybinding {
3468
- margin-left: auto;
3469
- padding: 2px 6px;
3470
- background: var(--wa-color-neutral-15);
3471
- border: 1px solid var(--wa-color-neutral-25);
3472
- border-radius: 3px;
3473
- font-size: 10px;
3474
- font-family: monospace;
3475
- opacity: 0.7;
3476
- }
3477
-
3478
- :host-context(.wa-light) .keybinding {
3479
- background: var(--wa-color-neutral-85);
3480
- border: 1px solid var(--wa-color-neutral-75);
3481
- }
3413
+ function renderDropdownContribution(contribution, options) {
3414
+ if ("command" in contribution) return renderCommandContribution(contribution, options);
3415
+ if ("component" in contribution) {
3416
+ if (!getContributionVisible(contribution)) return nothing;
3417
+ const contents = contribution.component;
3418
+ if (contents instanceof Function) return contents();
3419
+ return html`${unsafeHTML(contents)}`;
3420
+ }
3421
+ return nothing;
3422
+ }
3423
+ /** Renders all visible contributions registered for a contribution target. */
3424
+ function renderDropdownContributions(target, options) {
3425
+ return html`${contributionRegistry.getContributions(target).map((c) => renderDropdownContribution(c, options)).filter((item) => item !== nothing)}`;
3426
+ }
3427
+ /** Renders a {@link wa-dropdown-item} with nested items from a contribution target in {@code slot="submenu"}. */
3428
+ function renderDropdownSubmenu(options) {
3429
+ return html`
3430
+ <wa-dropdown-item ?disabled=${readReactiveBoolean(options.disabled, false)}>
3431
+ ${options.icon ? icon(options.icon, {
3432
+ label: options.title ?? options.label,
3433
+ slot: "icon"
3434
+ }) : nothing}
3435
+ ${options.label}
3436
+ ${renderDropdownContributions(options.contributionTarget, { slot: "submenu" })}
3437
+ </wa-dropdown-item>
3482
3438
  `;
3483
- }
3484
- };
3485
- _decorate([property()], DocksCommand.prototype, "cmd", void 0);
3486
- _decorate([property({
3487
- type: Object,
3488
- attribute: false
3489
- })], DocksCommand.prototype, "action", void 0);
3490
- _decorate([property()], DocksCommand.prototype, "title", void 0);
3491
- _decorate([property()], DocksCommand.prototype, "label", void 0);
3492
- _decorate([property()], DocksCommand.prototype, "icon", void 0);
3493
- _decorate([property({ type: Boolean })], DocksCommand.prototype, "disabled", void 0);
3494
- _decorate([property()], DocksCommand.prototype, "appearance", void 0);
3495
- _decorate([property()], DocksCommand.prototype, "variant", void 0);
3496
- _decorate([property()], DocksCommand.prototype, "size", void 0);
3497
- _decorate([property({
3498
- type: Object,
3499
- attribute: false
3500
- })], DocksCommand.prototype, "params", void 0);
3501
- _decorate([property()], DocksCommand.prototype, "dropdown", void 0);
3502
- _decorate([property({
3503
- type: Boolean,
3504
- attribute: "with-caret"
3505
- })], DocksCommand.prototype, "withCaret", void 0);
3506
- _decorate([property()], DocksCommand.prototype, "placement", void 0);
3507
- _decorate([state()], DocksCommand.prototype, "dropdownContributions", void 0);
3508
- DocksCommand = _decorate([customElement("docks-command")], DocksCommand);
3439
+ }
3509
3440
  //#endregion
3510
3441
  //#region src/parts/contextmenu.ts
3511
3442
  var DocksContextMenu = class DocksContextMenu extends DocksElement {
@@ -3515,11 +3446,14 @@ var DocksContextMenu = class DocksContextMenu extends DocksElement {
3515
3446
  this.partContextMenuRenderer = void 0;
3516
3447
  this.contributions = [];
3517
3448
  this.isOpen = false;
3518
- this.position = {
3449
+ this.menuPosition = {
3519
3450
  x: 0,
3520
3451
  y: 0
3521
3452
  };
3522
- this.anchorRef = createRef();
3453
+ this.virtualAnchor = { getBoundingClientRect: () => {
3454
+ const { x, y } = this.menuPosition;
3455
+ return new DOMRect(x, y, 0, 0);
3456
+ } };
3523
3457
  this.dropdownRef = createRef();
3524
3458
  this.boundHandleDocumentPointerDown = this.handleDocumentPointerDown.bind(this);
3525
3459
  this.handleSubmenuOpening = (event) => {
@@ -3671,37 +3605,31 @@ var DocksContextMenu = class DocksContextMenu extends DocksElement {
3671
3605
  this.isOpen = false;
3672
3606
  await this.updateComplete;
3673
3607
  }
3674
- this.position = position;
3608
+ this.menuPosition = position;
3675
3609
  this.isOpen = true;
3676
3610
  await this.updateComplete;
3611
+ this.syncVirtualPopupAnchor();
3677
3612
  document.addEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
3678
3613
  return true;
3679
3614
  }
3615
+ /** Points wa-dropdown's internal wa-popup at the pointer via a VirtualElement anchor. */
3616
+ syncVirtualPopupAnchor() {
3617
+ const popup = this.dropdownRef.value?.shadowRoot?.querySelector("wa-popup");
3618
+ if (!popup) return;
3619
+ popup.anchor = this.virtualAnchor;
3620
+ popup.reposition();
3621
+ }
3680
3622
  onClose() {
3681
3623
  if (!this.isOpen) return;
3682
3624
  this.isOpen = false;
3683
3625
  document.removeEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
3684
3626
  }
3627
+ updated(changedProperties) {
3628
+ super.updated(changedProperties);
3629
+ if (changedProperties.has("isOpen") && this.isOpen) this.syncVirtualPopupAnchor();
3630
+ }
3685
3631
  renderContribution(contribution) {
3686
- if ("command" in contribution) {
3687
- const commandContribution = contribution;
3688
- if (!getContributionVisible(commandContribution)) return nothing;
3689
- const disabled = getContributionDisabled(commandContribution);
3690
- return html`
3691
- <docks-command
3692
- cmd="${commandContribution.command}"
3693
- icon="${commandContribution.icon ?? ""}"
3694
- .params=${commandContribution.params ?? {}}
3695
- ?disabled="${disabled}">
3696
- ${commandContribution.label}
3697
- </docks-command>
3698
- `;
3699
- } else if ("component" in contribution) {
3700
- const contents = contribution.component;
3701
- if (contents instanceof Function) return contents();
3702
- return unsafeHTML(contents);
3703
- }
3704
- return nothing;
3632
+ return renderDropdownContribution(contribution);
3705
3633
  }
3706
3634
  render() {
3707
3635
  const partContent = this.partContextMenuRenderer ? this.partContextMenuRenderer() : nothing;
@@ -3711,17 +3639,7 @@ var DocksContextMenu = class DocksContextMenu extends DocksElement {
3711
3639
  ?open=${this.isOpen}
3712
3640
  @submenu-opening=${this.handleSubmenuOpening}
3713
3641
  @wa-after-hide=${this.onClose}>
3714
-
3715
- <div
3716
- slot="trigger"
3717
- ${ref(this.anchorRef)}
3718
- style="position: fixed;
3719
- left: ${this.position.x}px;
3720
- top: ${this.position.y}px;
3721
- width: 1px;
3722
- height: 1px;
3723
- pointer-events: none;">
3724
- </div>
3642
+ <span slot="trigger" hidden aria-hidden="true"></span>
3725
3643
 
3726
3644
  ${partContent}
3727
3645
  ${this.contributions.map((c) => this.renderContribution(c))}
@@ -3759,7 +3677,6 @@ _decorate([property({ attribute: false })], DocksContextMenu.prototype, "scopeTo
3759
3677
  _decorate([property({ attribute: false })], DocksContextMenu.prototype, "partContextMenuRenderer", void 0);
3760
3678
  _decorate([state()], DocksContextMenu.prototype, "contributions", void 0);
3761
3679
  _decorate([state()], DocksContextMenu.prototype, "isOpen", void 0);
3762
- _decorate([state()], DocksContextMenu.prototype, "position", void 0);
3763
3680
  DocksContextMenu = _decorate([customElement("docks-contextmenu")], DocksContextMenu);
3764
3681
  //#endregion
3765
3682
  //#region src/parts/container.ts
@@ -3883,10 +3800,12 @@ var DocksPart = class DocksPart extends DocksContainer {
3883
3800
  renderContent() {
3884
3801
  return nothing;
3885
3802
  }
3803
+ /** Part-level toolbar contributions (`toolbar:${partId}`). */
3886
3804
  getToolbarTarget() {
3887
3805
  const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
3888
3806
  return contributionKey ? `toolbar:${contributionKey}` : void 0;
3889
3807
  }
3808
+ /** Part-level context-menu contributions (`contextmenu:${partId}`). */
3890
3809
  getContextMenuTarget() {
3891
3810
  const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
3892
3811
  return contributionKey ? `contextmenu:${contributionKey}` : void 0;
@@ -4843,6 +4762,9 @@ _decorate([state()], DocksResizableGrid.prototype, "gridSizes", void 0);
4843
4762
  _decorate([state()], DocksResizableGrid.prototype, "gridChildren", void 0);
4844
4763
  DocksResizableGrid = _DocksResizableGrid = _decorate([customElement("docks-resizable-grid")], DocksResizableGrid);
4845
4764
  //#endregion
4846
- export { constants_exports as A, SYSTEM_VIEWS as B, esmShService as C, COMMAND_SAVE as D, appSettings as E, SIDEBAR_MAIN as F, TOOLBAR_MAIN_CENTER as G, TOOLBAR_BOTTOM_CENTER as H, SIDEBAR_MAIN_BOTTOM as I, TOOLBAR_MAIN_RIGHT as K, SIDEBAR_MAIN_TOOLBAR as L, EDITOR_AREA_MAIN as M, PANEL_BOTTOM as N, HIDE_DOT_RESOURCE as O, SIDEBAR_AUXILIARY as P, SYSTEM_ATTRIBUTIONS as R, extensionRegistry as S, TOPIC_SETTINGS_CHANGED as T, TOOLBAR_BOTTOM_END as U, TOOLBAR_BOTTOM as V, TOOLBAR_MAIN as W, DocksDialogContent as _, versionInfoDialog as a, sanitizeHtml as b, confirmDialog as c, formDialogRequired as d, validateFormDialogFields as f, dialogService as g, deleteIndexedDbWorkspaceData as h, parseIconSpec as i, ABOUT_TABS as j, MouseButton as k, infoDialog as l, appLoaderService as m, DocksContainer as n, filebrowserDialog as o, promptDialog as p, icon as r, navigableInfoDialog as s, DocksPart as t, formDialog as u, DocksElement as v, taskService as w, TOPIC_EXTENSIONS_CHANGED as x, parseMarkdownHtml as y, SYSTEM_LAYOUTS as z };
4765
+ //#region src/parts/index.ts
4766
+ installOpenDropdownNativeContextMenuGuard();
4767
+ //#endregion
4768
+ export { taskService as A, SIDEBAR_AUXILIARY as B, DocksElement as C, TOPIC_EXTENSIONS_CHANGED as D, keyBindingManager as E, MouseButton as F, SYSTEM_LAYOUTS as G, SIDEBAR_MAIN_BOTTOM as H, constants_exports as I, TOOLBAR_BOTTOM_CENTER as J, SYSTEM_VIEWS as K, ABOUT_TABS as L, appSettings as M, COMMAND_SAVE as N, extensionRegistry as O, HIDE_DOT_RESOURCE as P, TOOLBAR_MAIN_RIGHT as Q, EDITOR_AREA_MAIN as R, DocksDialogContent as S, sanitizeHtml as T, SIDEBAR_MAIN_TOOLBAR as U, SIDEBAR_MAIN as V, SYSTEM_ATTRIBUTIONS as W, TOOLBAR_MAIN as X, TOOLBAR_BOTTOM_END as Y, TOOLBAR_MAIN_CENTER as Z, validateFormDialogFields as _, renderDropdownContributions as a, deleteIndexedDbWorkspaceData as b, icon as c, filebrowserDialog as d, navigableInfoDialog as f, formDialogRequired as g, formDialog as h, renderDropdownContribution as i, TOPIC_SETTINGS_CHANGED as j, esmShService as k, parseIconSpec as l, infoDialog as m, DocksContainer as n, renderDropdownItem as o, confirmDialog as p, TOOLBAR_BOTTOM as q, renderCommandContribution as r, renderDropdownSubmenu as s, DocksPart as t, versionInfoDialog as u, promptDialog as v, parseMarkdownHtml as w, dialogService as x, appLoaderService as y, PANEL_BOTTOM as z };
4847
4769
 
4848
- //# sourceMappingURL=parts-CsoNFVTw.js.map
4770
+ //# sourceMappingURL=parts-CRVxaDd-.js.map