@nvidia-elements/core 2.9.0 → 2.11.0
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.
- package/CHANGELOG.md +23 -0
- package/README.md +3 -7
- package/dist/accordion/accordion.d.ts +4 -4
- package/dist/accordion/accordion2.js +4 -4
- package/dist/alert/alert-group.d.ts +1 -1
- package/dist/alert/alert-group2.js +1 -1
- package/dist/alert/alert.d.ts +1 -1
- package/dist/alert/alert2.js +1 -1
- package/dist/avatar/avatar-group.d.ts +1 -1
- package/dist/avatar/avatar-group2.js +1 -1
- package/dist/avatar/avatar.d.ts +1 -1
- package/dist/avatar/avatar2.js +1 -1
- package/dist/badge/badge.d.ts +1 -1
- package/dist/badge/badge2.js +1 -1
- package/dist/breadcrumb/breadcrumb.d.ts +2 -1
- package/dist/breadcrumb/breadcrumb2.js +1 -1
- package/dist/breadcrumb/breadcrumb2.js.map +1 -1
- package/dist/bundles/index.d.ts +183 -44
- package/dist/bundles/index.js +6 -6
- package/dist/button/button.d.ts +1 -1
- package/dist/button/button2.js +1 -1
- package/dist/button-group/button-group.d.ts +1 -1
- package/dist/button-group/button-group2.js +1 -1
- package/dist/card/card.d.ts +4 -4
- package/dist/card/card2.js +4 -4
- package/dist/chat-message/chat-message.d.ts +1 -1
- package/dist/chat-message/chat-message2.js +1 -1
- package/dist/checkbox/checkbox-group2.js +1 -1
- package/dist/checkbox/checkbox2.js +1 -1
- package/dist/color/color.d.ts +1 -1
- package/dist/color/color2.js +1 -1
- package/dist/combobox/combobox.d.ts +2 -2
- package/dist/combobox/combobox2.js +1 -1
- package/dist/copy-button/copy-button.d.ts +1 -1
- package/dist/copy-button/copy-button2.js +1 -1
- package/dist/custom-elements-jsx.d.ts +117 -25
- package/dist/custom-elements-vue.d.ts +115 -25
- package/dist/custom-elements.json +1075 -916
- package/dist/data.html.json +55 -7
- package/dist/data.snippets.json +45 -45
- package/dist/date/date.d.ts +1 -1
- package/dist/date/date2.js +1 -1
- package/dist/datetime/datetime.d.ts +1 -1
- package/dist/datetime/datetime2.js +1 -1
- package/dist/dialog/dialog-footer.d.ts +1 -1
- package/dist/dialog/dialog-footer2.js +1 -1
- package/dist/dialog/dialog-header.d.ts +1 -1
- package/dist/dialog/dialog-header2.js +1 -1
- package/dist/dialog/dialog.d.ts +1 -1
- package/dist/dialog/dialog2.js +1 -1
- package/dist/divider/divider.d.ts +1 -1
- package/dist/divider/divider2.js +1 -1
- package/dist/dot/dot.d.ts +1 -1
- package/dist/dot/dot2.js +1 -1
- package/dist/drawer/drawer-content.d.ts +1 -1
- package/dist/drawer/drawer-content2.js +1 -1
- package/dist/drawer/drawer-footer.d.ts +1 -1
- package/dist/drawer/drawer-footer2.js +1 -1
- package/dist/drawer/drawer-header.d.ts +1 -1
- package/dist/drawer/drawer-header2.js +1 -1
- package/dist/drawer/drawer.d.ts +1 -1
- package/dist/drawer/drawer2.js +1 -1
- package/dist/dropdown/dropdown-footer.d.ts +1 -1
- package/dist/dropdown/dropdown-footer2.js +1 -1
- package/dist/dropdown/dropdown-header.d.ts +1 -1
- package/dist/dropdown/dropdown-header2.js +1 -1
- package/dist/dropdown/dropdown.d.ts +1 -1
- package/dist/dropdown/dropdown2.js +1 -1
- package/dist/dropdown-group/dropdown-group.d.ts +1 -1
- package/dist/dropdown-group/dropdown-group.js +1 -1
- package/dist/dropzone/dropzone.d.ts +1 -1
- package/dist/dropzone/dropzone2.js +1 -1
- package/dist/file/file2.js +1 -1
- package/dist/format-bytes/format-bytes.d.ts +1 -1
- package/dist/format-bytes/format-bytes2.js +1 -1
- package/dist/format-datetime/format-datetime.d.ts +1 -1
- package/dist/format-datetime/format-datetime2.js +1 -1
- package/dist/format-number/format-number.d.ts +1 -1
- package/dist/format-number/format-number2.js +1 -1
- package/dist/format-relative-time/format-relative-time.d.ts +1 -1
- package/dist/format-relative-time/format-relative-time2.js +1 -1
- package/dist/format-truncate/format-truncate2.js +1 -1
- package/dist/forms/control/control2.js +1 -1
- package/dist/forms/control-group/control-group.d.ts +3 -1
- package/dist/forms/control-group/control-group2.js +1 -1
- package/dist/forms/control-group/control-group2.js.map +1 -1
- package/dist/forms/control-message/control-message.d.ts +1 -1
- package/dist/forms/control-message/control-message2.js +1 -1
- package/dist/gauge/gauge.d.ts +1 -1
- package/dist/gauge/gauge2.js +1 -1
- package/dist/grid/cell/cell.d.ts +1 -1
- package/dist/grid/cell/cell2.js +1 -1
- package/dist/grid/column/column.d.ts +1 -1
- package/dist/grid/column/column2.js +1 -1
- package/dist/grid/footer/footer.d.ts +1 -1
- package/dist/grid/footer/footer2.js +1 -1
- package/dist/grid/grid.d.ts +3 -1
- package/dist/grid/grid2.js +1 -1
- package/dist/grid/grid2.js.map +1 -1
- package/dist/grid/header/header.d.ts +1 -1
- package/dist/grid/header/header2.js +1 -1
- package/dist/grid/placeholder/placeholder.d.ts +1 -1
- package/dist/grid/placeholder/placeholder2.js +1 -1
- package/dist/grid/row/row.d.ts +1 -1
- package/dist/grid/row/row2.js +1 -1
- package/dist/icon/icon.d.ts +1 -1
- package/dist/icon/icon2.js +2 -2
- package/dist/icon-button/icon-button.d.ts +1 -1
- package/dist/icon-button/icon-button2.js +1 -1
- package/dist/index.js +1 -1
- package/dist/input/input-group2.js +1 -1
- package/dist/input/input2.js +1 -1
- package/dist/internal/controllers/keynav-list.controller.js.map +1 -1
- package/dist/internal/services/global.service.js +1 -1
- package/dist/internal/types/index.d.ts +6 -2
- package/dist/internal/types/index.js.map +1 -1
- package/dist/internal/utils/audit.js +1 -1
- package/dist/internal/utils/audit.js.map +1 -1
- package/dist/internal/utils/dom.d.ts +3 -1
- package/dist/internal/utils/dom.js.map +1 -1
- package/dist/logo/logo.d.ts +1 -1
- package/dist/logo/logo2.js +1 -1
- package/dist/menu/define.d.ts +2 -1
- package/dist/menu/define.js +3 -2
- package/dist/menu/define.js.map +1 -1
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +3 -2
- package/dist/menu/menu-group.d.ts +50 -0
- package/dist/menu/menu-group.js +6 -0
- package/dist/menu/menu-group.js.map +1 -0
- package/dist/menu/menu-group2.js +53 -0
- package/dist/menu/menu-group2.js.map +1 -0
- package/dist/menu/menu-item.d.ts +2 -1
- package/dist/menu/menu-item.js +1 -1
- package/dist/menu/menu-item.js.map +1 -1
- package/dist/menu/menu-item2.js +2 -2
- package/dist/menu/menu-item2.js.map +1 -1
- package/dist/menu/menu.d.ts +7 -2
- package/dist/menu/menu.examples.js.map +1 -1
- package/dist/menu/menu.examples.json +53 -13
- package/dist/menu/menu.global.js +1 -1
- package/dist/menu/menu.global.js.map +1 -1
- package/dist/menu/menu2.js +16 -8
- package/dist/menu/menu2.js.map +1 -1
- package/dist/month/month.d.ts +1 -1
- package/dist/month/month2.js +1 -1
- package/dist/notification/notification-group.d.ts +1 -1
- package/dist/notification/notification-group2.js +1 -1
- package/dist/notification/notification.d.ts +1 -1
- package/dist/notification/notification2.js +1 -1
- package/dist/page/page-panel/page-panel-content.d.ts +1 -1
- package/dist/page/page-panel/page-panel-content2.js +1 -1
- package/dist/page/page-panel/page-panel-footer.d.ts +1 -1
- package/dist/page/page-panel/page-panel-footer2.js +1 -1
- package/dist/page/page-panel/page-panel-header.d.ts +1 -1
- package/dist/page/page-panel/page-panel-header2.js +1 -1
- package/dist/page/page-panel/page-panel.d.ts +1 -1
- package/dist/page/page-panel/page-panel2.js +1 -1
- package/dist/page/page.d.ts +1 -1
- package/dist/page/page2.js +1 -1
- package/dist/page-header/page-header.d.ts +1 -1
- package/dist/page-header/page-header2.js +1 -1
- package/dist/page-loader/page-loader.d.ts +1 -1
- package/dist/page-loader/page-loader2.js +1 -1
- package/dist/pagination/pagination.d.ts +1 -1
- package/dist/pagination/pagination2.js +1 -1
- package/dist/panel/panel.d.ts +4 -4
- package/dist/panel/panel2.js +4 -4
- package/dist/password/password.d.ts +1 -1
- package/dist/password/password2.js +1 -1
- package/dist/preferences-input/preferences-input.d.ts +1 -1
- package/dist/preferences-input/preferences-input2.js +1 -1
- package/dist/progress-bar/progress-bar.d.ts +1 -1
- package/dist/progress-bar/progress-bar2.js +1 -1
- package/dist/progress-ring/progress-ring.d.ts +1 -1
- package/dist/progress-ring/progress-ring2.js +1 -1
- package/dist/progressive-filter-chip/progressive-filter-chip.d.ts +1 -1
- package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
- package/dist/pulse/pulse.d.ts +1 -1
- package/dist/pulse/pulse2.js +1 -1
- package/dist/radio/radio-group2.js +1 -1
- package/dist/radio/radio2.js +1 -1
- package/dist/range/range.d.ts +1 -1
- package/dist/range/range2.js +1 -1
- package/dist/resize-handle/resize-handle.d.ts +1 -1
- package/dist/resize-handle/resize-handle2.js +1 -1
- package/dist/search/search.d.ts +1 -1
- package/dist/search/search2.js +1 -1
- package/dist/select/select.d.ts +2 -2
- package/dist/select/select2.js +1 -1
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton2.js +1 -1
- package/dist/sort-button/sort-button.d.ts +1 -1
- package/dist/sort-button/sort-button2.js +1 -1
- package/dist/sparkline/sparkline.d.ts +1 -1
- package/dist/sparkline/sparkline2.js +1 -1
- package/dist/star-rating/star-rating.d.ts +1 -1
- package/dist/star-rating/star-rating2.js +1 -1
- package/dist/steps/steps.d.ts +5 -5
- package/dist/steps/steps2.js +2 -2
- package/dist/steps/steps2.js.map +1 -1
- package/dist/switch/switch-group2.js +1 -1
- package/dist/switch/switch2.js +1 -1
- package/dist/tabs/tabs-group.d.ts +1 -1
- package/dist/tabs/tabs-group2.js +1 -1
- package/dist/tabs/tabs.d.ts +2 -2
- package/dist/tabs/tabs2.js +2 -2
- package/dist/tag/tag.d.ts +1 -1
- package/dist/tag/tag2.js +1 -1
- package/dist/textarea/textarea.d.ts +2 -2
- package/dist/textarea/textarea2.js +1 -1
- package/dist/time/time.d.ts +1 -1
- package/dist/time/time2.js +1 -1
- package/dist/toast/toast.d.ts +1 -1
- package/dist/toast/toast2.js +1 -1
- package/dist/toggletip/toggletip-footer.d.ts +1 -1
- package/dist/toggletip/toggletip-footer2.js +1 -1
- package/dist/toggletip/toggletip-header.d.ts +1 -1
- package/dist/toggletip/toggletip-header2.js +1 -1
- package/dist/toggletip/toggletip.d.ts +1 -1
- package/dist/toggletip/toggletip2.js +1 -1
- package/dist/toolbar/toolbar.d.ts +1 -1
- package/dist/toolbar/toolbar2.js +1 -1
- package/dist/tooltip/tooltip.d.ts +1 -1
- package/dist/tooltip/tooltip2.js +1 -1
- package/dist/tree/tree-node.d.ts +2 -2
- package/dist/tree/tree-node2.js +1 -1
- package/dist/tree/tree-node2.js.map +1 -1
- package/dist/tree/tree.d.ts +2 -1
- package/dist/tree/tree2.js +1 -1
- package/dist/tree/tree2.js.map +1 -1
- package/dist/viewport/define.d.ts +2 -1
- package/dist/viewport/define.js +2 -1
- package/dist/viewport/define.js.map +1 -1
- package/dist/viewport/index.d.ts +2 -1
- package/dist/viewport/index.js +2 -1
- package/dist/viewport/viewport-gesture-navigation.controller.d.ts +8 -10
- package/dist/viewport/viewport-gesture-navigation.controller.js +73 -66
- package/dist/viewport/viewport-gesture-navigation.controller.js.map +1 -1
- package/dist/viewport/viewport-gridlines.d.ts +1 -1
- package/dist/viewport/viewport-gridlines2.js +3 -3
- package/dist/viewport/viewport-gridlines2.js.map +1 -1
- package/dist/viewport/viewport-minimap.d.ts +36 -0
- package/dist/viewport/viewport-minimap.js +6 -0
- package/dist/viewport/viewport-minimap.js.map +1 -0
- package/dist/viewport/viewport-minimap.utils.d.ts +13 -0
- package/dist/viewport/viewport-minimap.utils.js +49 -0
- package/dist/viewport/viewport-minimap.utils.js.map +1 -0
- package/dist/viewport/viewport-minimap2.js +309 -0
- package/dist/viewport/viewport-minimap2.js.map +1 -0
- package/dist/viewport/viewport-navigation.controller.d.ts +7 -13
- package/dist/viewport/viewport-navigation.controller.js +14 -20
- package/dist/viewport/viewport-navigation.controller.js.map +1 -1
- package/dist/viewport/viewport-navigation.types.d.ts +0 -8
- package/dist/viewport/viewport.d.ts +31 -6
- package/dist/viewport/viewport.examples.js.map +1 -1
- package/dist/viewport/viewport.examples.json +13 -4
- package/dist/viewport/viewport.js +1 -1
- package/dist/viewport/viewport.js.map +1 -1
- package/dist/viewport/viewport.types.d.ts +50 -23
- package/dist/viewport/viewport2.js +173 -118
- package/dist/viewport/viewport2.js.map +1 -1
- package/dist/week/week.d.ts +1 -1
- package/dist/week/week2.js +1 -1
- package/package.json +7 -4
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { GestureController as e } from "../internal/controllers/gesture.controller.js";
|
|
2
|
+
import { isImmediateRootActiveElement as t } from "../internal/utils/focus.js";
|
|
3
|
+
import { attachInternals as n } from "../internal/utils/a11y.js";
|
|
4
|
+
import { hostAttr as r } from "../internal/decorators/host-attr.js";
|
|
5
|
+
import { useStyles as i } from "../internal/styles/index.js";
|
|
6
|
+
import a from "../_virtual/_@oxc-project_runtime@0.147.0/helpers/esm/decorate.js";
|
|
7
|
+
import { anchoredTransform as o } from "./viewport-projection.utils.js";
|
|
8
|
+
import { Viewport as s } from "./viewport2.js";
|
|
9
|
+
import c from "./viewport-minimap.js";
|
|
10
|
+
import { createViewportMinimapProjection as l, projectViewportMinimapRect as u, unprojectViewportMinimapPoint as d } from "./viewport-minimap.utils.js";
|
|
11
|
+
import { LitElement as f, html as p, nothing as m, svg as h } from "lit";
|
|
12
|
+
import { styleMap as g } from "lit/directives/style-map.js";
|
|
13
|
+
//#region src/viewport/viewport-minimap.ts
|
|
14
|
+
var _ = 3, v = class extends f {
|
|
15
|
+
static {
|
|
16
|
+
this.styles = i([c]);
|
|
17
|
+
}
|
|
18
|
+
static {
|
|
19
|
+
this.metadata = {
|
|
20
|
+
tag: "nve-viewport-minimap",
|
|
21
|
+
version: "2.11.0"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
#e;
|
|
25
|
+
#t;
|
|
26
|
+
#n;
|
|
27
|
+
#r;
|
|
28
|
+
#i;
|
|
29
|
+
#a;
|
|
30
|
+
#o;
|
|
31
|
+
#s;
|
|
32
|
+
#c;
|
|
33
|
+
#l;
|
|
34
|
+
#u;
|
|
35
|
+
#d;
|
|
36
|
+
#f;
|
|
37
|
+
get #p() {
|
|
38
|
+
return Array.from(this.children).filter((e) => e.slot === "preview");
|
|
39
|
+
}
|
|
40
|
+
get #m() {
|
|
41
|
+
let e = this.#r;
|
|
42
|
+
return e ? Array.from(e.children).filter((e) => !e.slot) : [];
|
|
43
|
+
}
|
|
44
|
+
constructor() {
|
|
45
|
+
super(), this.slot = "overlay", this.accessibilityHidden = "true", this.#t = /* @__PURE__ */ new WeakMap(), this.#n = 0, this.#s = [], this.#c = [], this.#f = !1, this.#E = () => {
|
|
46
|
+
this.#D(), this.#j({ measureRoots: !0 });
|
|
47
|
+
}, this.#O = () => {
|
|
48
|
+
let e = this.#r?.getTransform(), t = this.#u;
|
|
49
|
+
t?.active && e && (t.transformStart = e, t.transformStartDisplacementX = t.lastTotalDisplacementX, t.transformStartDisplacementY = t.lastTotalDisplacementY), this.#j({ measureRoots: !1 });
|
|
50
|
+
}, this.#k = () => {
|
|
51
|
+
this.#A(), this.requestUpdate();
|
|
52
|
+
}, this.#I = (e) => {
|
|
53
|
+
let t = e.detail;
|
|
54
|
+
t.kind === "pointerdown" ? this.#R(t) : t.kind === "pointerend" ? this.#U(t) : this.#L(t);
|
|
55
|
+
}, this.#z = (e) => {
|
|
56
|
+
let t = e.detail;
|
|
57
|
+
t.kind === "drag" && this.#B(t);
|
|
58
|
+
}, this.#e = new e(this, {
|
|
59
|
+
claimPriority: "self-first",
|
|
60
|
+
suppressNativeDrag: !0,
|
|
61
|
+
touchAction: () => this.#u || this.#r?.pannable ? "none" : void 0
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
connectedCallback() {
|
|
65
|
+
super.connectedCallback(), n(this);
|
|
66
|
+
let e = this.parentElement;
|
|
67
|
+
e instanceof s && (this.#r = e, this.#r.addEventListener("viewportchange", this.#O), this.#r.addEventListener("capabilitieschange", this.#k), this.#h(e), this.requestUpdate());
|
|
68
|
+
}
|
|
69
|
+
#h(e) {
|
|
70
|
+
this.#e.target = this, this.addEventListener("nve-gesture-input", this.#I), this.addEventListener("nve-gesture", this.#z), this.#T(), e.updateComplete.then(() => {
|
|
71
|
+
this.#r === e && (this.#i = e.shadowRoot?.querySelector("slot:not([name])") ?? void 0, this.#i?.addEventListener("slotchange", this.#E), this.#D(), this.#j({ measureRoots: !0 }));
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
disconnectedCallback() {
|
|
75
|
+
this.#K(), this.#r?.removeEventListener("viewportchange", this.#O), this.#r?.removeEventListener("capabilitieschange", this.#k), this.#g(), this.#_(), this.#v(), super.disconnectedCallback();
|
|
76
|
+
}
|
|
77
|
+
#g() {
|
|
78
|
+
this.removeEventListener("nve-gesture-input", this.#I), this.removeEventListener("nve-gesture", this.#z), this.#i?.removeEventListener("slotchange", this.#E);
|
|
79
|
+
}
|
|
80
|
+
#_() {
|
|
81
|
+
this.#a?.disconnect(), this.#o?.disconnect(), this.#d !== void 0 && cancelAnimationFrame(this.#d);
|
|
82
|
+
}
|
|
83
|
+
#v() {
|
|
84
|
+
this.#d = void 0, this.#f = !1, this.#e.target = void 0, this.#u = void 0, this.#r = void 0, this.#i = void 0, this.#l = void 0, this.#s = [], this.#c = [], this._internals.states.delete("pan-eligible"), this._internals.states.delete("panning");
|
|
85
|
+
}
|
|
86
|
+
refresh() {
|
|
87
|
+
this.#j({ measureRoots: !0 });
|
|
88
|
+
}
|
|
89
|
+
render() {
|
|
90
|
+
let e = this.#l, t = this.#r, n = t && e ? u(t.getVisibleRect(), e) : void 0;
|
|
91
|
+
return p`<div internal-host class="surface">${this.#y()} ${this.#b(e)} ${this.#x(e, n)}</div>`;
|
|
92
|
+
}
|
|
93
|
+
#y() {
|
|
94
|
+
return p`<svg class="background-layer" aria-hidden="true" focusable="false"><rect class="background" data-minimap-background width="100%" height="100%"></rect></svg>`;
|
|
95
|
+
}
|
|
96
|
+
#b(e) {
|
|
97
|
+
return p`<div class="preview" style="${g({ transform: e ? `translate(${e.offsetX}px, ${e.offsetY}px) scale(${e.scale})` : "none" })}"><slot name="preview" @slotchange="${this.#E}"></slot></div>`;
|
|
98
|
+
}
|
|
99
|
+
#x(e, t) {
|
|
100
|
+
return p`<svg class="foreground-layer" aria-hidden="true" focusable="false" viewBox="0 0 ${this.clientWidth} ${this.clientHeight}" preserveAspectRatio="none">${this.#S(e)} ${this.#C(t)}</svg>`;
|
|
101
|
+
}
|
|
102
|
+
#S(e) {
|
|
103
|
+
return !e || this.#p.length ? m : this.#c.map((t) => this.#w(t, e));
|
|
104
|
+
}
|
|
105
|
+
#C(e) {
|
|
106
|
+
return e ? h`<rect class="visible-region" data-visible-region x="${e.x}" y="${e.y}" width="${e.width}" height="${e.height}" rx="2"></rect>` : m;
|
|
107
|
+
}
|
|
108
|
+
#w(e, t) {
|
|
109
|
+
let n = u(e, t);
|
|
110
|
+
return h`<rect class="item" data-item-key="${e.id}" x="${n.x}" y="${n.y}" width="${n.width}" height="${n.height}" rx="2"></rect>`;
|
|
111
|
+
}
|
|
112
|
+
#T() {
|
|
113
|
+
let e = this.#r;
|
|
114
|
+
!e || typeof ResizeObserver > "u" || (this.#a = new ResizeObserver((t) => {
|
|
115
|
+
this.#j({ measureRoots: t.some((t) => t.target === e || t.target === this) });
|
|
116
|
+
}), this.#a.observe(e), this.#a.observe(this), this.#o = new ResizeObserver(() => this.#j({ measureRoots: !0 })));
|
|
117
|
+
}
|
|
118
|
+
#E;
|
|
119
|
+
#D() {
|
|
120
|
+
let e = this.#r;
|
|
121
|
+
if (this.#o?.disconnect(), !e) return;
|
|
122
|
+
let t = this.#p, n = t.length ? t : this.#m;
|
|
123
|
+
for (let e of n) this.#o?.observe(e);
|
|
124
|
+
}
|
|
125
|
+
#O;
|
|
126
|
+
#k;
|
|
127
|
+
#A() {
|
|
128
|
+
let e = !!(this.#r?.pannable && this.#l);
|
|
129
|
+
this._internals.states.has("pan-eligible") !== e && (e ? this._internals.states.add("pan-eligible") : this._internals.states.delete("pan-eligible"));
|
|
130
|
+
}
|
|
131
|
+
#j({ measureRoots: e }) {
|
|
132
|
+
this.#f ||= e, this.#d === void 0 && (this.#d = requestAnimationFrame(() => {
|
|
133
|
+
this.#d = void 0;
|
|
134
|
+
let e = this.#f;
|
|
135
|
+
this.#f = !1, this.#M({ measureRoots: e });
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
#M({ measureRoots: e }) {
|
|
139
|
+
let t = this.#r;
|
|
140
|
+
if (t) {
|
|
141
|
+
if (e) {
|
|
142
|
+
let e = this.#p;
|
|
143
|
+
e.length ? (this.#c = [], this.#s = this.#N(e)) : (this.#c = this.#P(t, this.#m), this.#s = this.#c);
|
|
144
|
+
}
|
|
145
|
+
this.#l = l(this.#s, t.getVisibleRect(), {
|
|
146
|
+
height: this.clientHeight,
|
|
147
|
+
width: this.clientWidth
|
|
148
|
+
}), this.#A(), this.requestUpdate();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
#N(e) {
|
|
152
|
+
let t = this.renderRoot.querySelector(".preview");
|
|
153
|
+
if (!t) return [];
|
|
154
|
+
let n = t.getBoundingClientRect(), r = getComputedStyle(t).transform, i = new DOMMatrixReadOnly(r === "none" ? void 0 : r), a = [];
|
|
155
|
+
for (let t of e) {
|
|
156
|
+
let e = t.getBoundingClientRect();
|
|
157
|
+
e.width <= 0 || e.height <= 0 || a.push({
|
|
158
|
+
x: (e.left - n.left) / i.m11,
|
|
159
|
+
y: (e.top - n.top) / i.m11,
|
|
160
|
+
width: e.width / i.m11,
|
|
161
|
+
height: e.height / i.m11
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return a;
|
|
165
|
+
}
|
|
166
|
+
#P(e, t) {
|
|
167
|
+
let n = e.getBoundingClientRect(), r = e.getTransform(), i = [];
|
|
168
|
+
for (let e of t) {
|
|
169
|
+
let t = e.getBoundingClientRect();
|
|
170
|
+
t.width <= 0 || t.height <= 0 || i.push({
|
|
171
|
+
id: this.#F(e),
|
|
172
|
+
x: r.x + (t.left - n.left) / r.scale,
|
|
173
|
+
y: r.y + (t.top - n.top) / r.scale,
|
|
174
|
+
width: t.width / r.scale,
|
|
175
|
+
height: t.height / r.scale
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return i;
|
|
179
|
+
}
|
|
180
|
+
#F(e) {
|
|
181
|
+
let t = e.id.trim();
|
|
182
|
+
if (t) return t;
|
|
183
|
+
let n = this.#t.get(e);
|
|
184
|
+
if (n) return n;
|
|
185
|
+
let r = `root-${this.#n}`;
|
|
186
|
+
return this.#n += 1, this.#t.set(e, r), r;
|
|
187
|
+
}
|
|
188
|
+
#I;
|
|
189
|
+
#L(e) {
|
|
190
|
+
let n = this.#r;
|
|
191
|
+
if (e.deltaY === 0 || !n || !n.zoomable || !t(n) || !e.claim()) return;
|
|
192
|
+
let r = n.getTransform(), i = n.getVisibleRect(), a = {
|
|
193
|
+
x: i.x + i.width / 2,
|
|
194
|
+
y: i.y + i.height / 2
|
|
195
|
+
}, s = this.#e.getWheelZoomFactor(e), c = {
|
|
196
|
+
x: n.clientWidth / 2,
|
|
197
|
+
y: n.clientHeight / 2
|
|
198
|
+
};
|
|
199
|
+
n.requestZoom({
|
|
200
|
+
anchor: a,
|
|
201
|
+
event: e.event,
|
|
202
|
+
factor: s,
|
|
203
|
+
next: o(a, c, Math.min(n.maxScale, Math.max(n.minScale, r.scale * s))),
|
|
204
|
+
source: "minimap"
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
#R(e) {
|
|
208
|
+
let t = e.event, n = this.#r, r = this.#l;
|
|
209
|
+
if (!n || t.button !== 0 || !t.isPrimary || !n.pannable && !n.zoomable || (n.focus({ preventScroll: !0 }), !r || !n.pannable || !e.claim({ kind: "drag" }))) return;
|
|
210
|
+
let i = n.getTransform(), a = t.composedPath().some((e) => e instanceof Element && e.hasAttribute("data-visible-region"));
|
|
211
|
+
this.#u = {
|
|
212
|
+
active: !1,
|
|
213
|
+
activating: !1,
|
|
214
|
+
exceededThreshold: !1,
|
|
215
|
+
indicator: a,
|
|
216
|
+
lastTotalDisplacementX: 0,
|
|
217
|
+
lastTotalDisplacementY: 0,
|
|
218
|
+
pointerId: t.pointerId,
|
|
219
|
+
dragProjection: r,
|
|
220
|
+
transformStart: i,
|
|
221
|
+
transformStartDisplacementX: 0,
|
|
222
|
+
transformStartDisplacementY: 0
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
#z;
|
|
226
|
+
#B(e) {
|
|
227
|
+
let t = this.#u;
|
|
228
|
+
if (!t || t.pointerId !== e.event.pointerId || (t.lastTotalDisplacementX = e.totalDisplacementX, t.lastTotalDisplacementY = e.totalDisplacementY, e.totalDisplacementX ** 2 + e.totalDisplacementY ** 2 < _ ** 2) || (t.exceededThreshold = !0, !t.indicator)) return;
|
|
229
|
+
let n = this.#H(e, t);
|
|
230
|
+
t.active ? t.navigation?.update(n) : this.#V(t, n);
|
|
231
|
+
}
|
|
232
|
+
#V(e, t) {
|
|
233
|
+
e.activating = !0;
|
|
234
|
+
let n = this.#r?.startPan({
|
|
235
|
+
...t,
|
|
236
|
+
source: "minimap"
|
|
237
|
+
});
|
|
238
|
+
if (e.activating = !1, n) {
|
|
239
|
+
if (this.#u !== e) {
|
|
240
|
+
e.pendingEnd && n.end(e.pendingEnd);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
e.navigation = n, e.active = !0, this._internals.states.add("panning");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
#H(e, t) {
|
|
247
|
+
let n = e.totalDisplacementX - t.transformStartDisplacementX, r = e.totalDisplacementY - t.transformStartDisplacementY;
|
|
248
|
+
return {
|
|
249
|
+
clientX: e.clientX,
|
|
250
|
+
clientY: e.clientY,
|
|
251
|
+
event: e.event,
|
|
252
|
+
next: {
|
|
253
|
+
scale: t.transformStart.scale,
|
|
254
|
+
x: t.transformStart.x + n / t.dragProjection.scale,
|
|
255
|
+
y: t.transformStart.y + r / t.dragProjection.scale
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
#U(e) {
|
|
260
|
+
let t = this.#u;
|
|
261
|
+
!t || t.pointerId !== e.event.pointerId || (t.lastTotalDisplacementX = e.totalDisplacementX, t.lastTotalDisplacementY = e.totalDisplacementY, t.active ? t.navigation?.end({
|
|
262
|
+
event: e.event,
|
|
263
|
+
interrupted: e.interrupted,
|
|
264
|
+
reason: e.reason
|
|
265
|
+
}) : t.activating ? t.pendingEnd = {
|
|
266
|
+
event: e.event,
|
|
267
|
+
interrupted: e.interrupted,
|
|
268
|
+
reason: e.reason
|
|
269
|
+
} : e.reason === "up" && !t.exceededThreshold && this.#W(e.event, t), this.#G(t));
|
|
270
|
+
}
|
|
271
|
+
#W(e, t) {
|
|
272
|
+
let n = this.#r;
|
|
273
|
+
if (!n) return;
|
|
274
|
+
let r = this.getBoundingClientRect(), i = d({
|
|
275
|
+
x: e.clientX - r.left,
|
|
276
|
+
y: e.clientY - r.top
|
|
277
|
+
}, t.dragProjection), a = n.getTransform(), o = n.getVisibleRect();
|
|
278
|
+
n.requestPan({
|
|
279
|
+
clientX: e.clientX,
|
|
280
|
+
clientY: e.clientY,
|
|
281
|
+
event: e,
|
|
282
|
+
next: {
|
|
283
|
+
scale: a.scale,
|
|
284
|
+
x: i.x - o.width / 2,
|
|
285
|
+
y: i.y - o.height / 2
|
|
286
|
+
},
|
|
287
|
+
source: "minimap"
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
#G(e) {
|
|
291
|
+
this.#u === e && (this.#u = void 0, this._internals.states.delete("panning"), this.requestUpdate());
|
|
292
|
+
}
|
|
293
|
+
#K() {
|
|
294
|
+
let e = this.#u;
|
|
295
|
+
if (!e) return;
|
|
296
|
+
this.#G(e);
|
|
297
|
+
let t = {
|
|
298
|
+
event: new Event("disconnect"),
|
|
299
|
+
interrupted: !0,
|
|
300
|
+
reason: "cancel"
|
|
301
|
+
};
|
|
302
|
+
e.active ? e.navigation?.end(t) : e.activating && (e.pendingEnd = t);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
a([r()], v.prototype, "slot", void 0), a([r({ attribute: "aria-hidden" })], v.prototype, "accessibilityHidden", void 0);
|
|
306
|
+
//#endregion
|
|
307
|
+
export { v as ViewportMinimap };
|
|
308
|
+
|
|
309
|
+
//# sourceMappingURL=viewport-minimap2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewport-minimap2.js","names":[],"sources":["../../src/viewport/viewport-minimap.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html, LitElement, nothing, svg } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport {\n GestureController,\n attachInternals,\n hostAttr,\n isImmediateRootActiveElement,\n type Gesture,\n type GestureInput,\n type PointerEndGesture,\n type PointerMovementGesture,\n type WheelGestureInput,\n useStyles\n} from '@nvidia-elements/core/internal';\nimport styles from './viewport-minimap.css?inline';\nimport {\n createViewportMinimapProjection,\n projectViewportMinimapRect,\n unprojectViewportMinimapPoint,\n type ViewportMinimapProjection\n} from './viewport-minimap.utils.js';\nimport { anchoredTransform } from './viewport-projection.utils.js';\nimport { Viewport } from './viewport.js';\nimport type {\n ViewportPanEndRequest,\n ViewportPanUpdateProposal,\n ViewportPanSession,\n ViewportRect,\n ViewportTransform\n} from './viewport.types.js';\n\nconst DRAG_THRESHOLD = 3;\n\ninterface MinimapPointerSession {\n readonly pointerId: number;\n readonly dragProjection: ViewportMinimapProjection;\n readonly indicator: boolean;\n active: boolean;\n activating: boolean;\n navigation?: ViewportPanSession;\n pendingEnd?: ViewportPanEndRequest;\n exceededThreshold: boolean;\n transformStart: ViewportTransform;\n transformStartDisplacementX: number;\n transformStartDisplacementY: number;\n lastTotalDisplacementX: number;\n lastTotalDisplacementY: number;\n}\n\ninterface ProjectionUpdate {\n readonly measureRoots: boolean;\n}\n\ninterface AutomaticPreviewItem extends ViewportRect {\n readonly id: string;\n}\n\n/**\n * @element nve-viewport-minimap\n * @description Provides a simplified overview and direct navigation for its parent viewport.\n * @documentation https://nvidia.github.io/elements/docs/elements/viewport/\n * @since 0.0.0\n * @entrypoint \\@nvidia-elements/core/viewport\n * @cssprop --background - Color of the surface behind preview geometry.\n * @cssprop --color - Color of automatically drawn root rectangles.\n * @cssprop --indicator-color - Color of the current visible-region indicator.\n * @cssprop --border-radius - Corner radius of the minimap.\n * @cssprop --recenter-cursor - Cursor for clicking the background to center the viewport.\n * @cssprop --pan-cursor - Cursor over a draggable visible region.\n * @cssprop --panning-cursor - Cursor during a visible-region drag.\n * @slot preview - Optional simplified content drawn in viewport content coordinates. Replaces automatic root rectangles.\n */\nexport class ViewportMinimap extends LitElement {\n static styles = useStyles([styles]);\n\n static readonly metadata = {\n tag: 'nve-viewport-minimap',\n version: '0.0.0'\n };\n\n /** @private */\n declare _internals: ElementInternals;\n\n /** @private */\n @hostAttr() slot = 'overlay';\n\n /** @private */\n @hostAttr({ attribute: 'aria-hidden' }) protected accessibilityHidden = 'true';\n\n readonly #gestureController: GestureController;\n readonly #rootKeys = new WeakMap<Element, string>();\n #nextRootKey = 0;\n #viewport?: Viewport;\n #defaultSlot?: HTMLSlotElement;\n #layoutResizeObserver?: ResizeObserver;\n #rootResizeObserver?: ResizeObserver;\n #contentBounds: readonly ViewportRect[] = [];\n #automaticItems: readonly AutomaticPreviewItem[] = [];\n #projection?: ViewportMinimapProjection;\n #pointerSession?: MinimapPointerSession;\n #animationFrame?: number;\n #measureRootsOnFrame = false;\n\n get #previewRoots(): Element[] {\n return Array.from(this.children).filter(child => child.slot === 'preview');\n }\n\n get #viewportRoots(): Element[] {\n const viewport = this.#viewport;\n if (!viewport) return [];\n return Array.from(viewport.children).filter(child => !child.slot);\n }\n\n constructor() {\n super();\n this.#gestureController = new GestureController(this, {\n claimPriority: 'self-first',\n suppressNativeDrag: true,\n touchAction: () => (this.#pointerSession || this.#viewport?.pannable ? 'none' : undefined)\n });\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n attachInternals(this);\n const viewport = this.parentElement;\n if (!(viewport instanceof Viewport)) return;\n this.#viewport = viewport;\n this.#viewport.addEventListener('viewportchange', this.#handleTransformCommitted);\n this.#viewport.addEventListener('capabilitieschange', this.#handleCapabilitiesChange);\n this.#connectViewport(viewport);\n this.requestUpdate();\n }\n\n #connectViewport(viewport: Viewport): void {\n this.#gestureController.target = this;\n this.addEventListener('nve-gesture-input', this.#handleGestureInput as EventListener);\n this.addEventListener('nve-gesture', this.#handleGesture as EventListener);\n this.#connectResizeObservers();\n void viewport.updateComplete.then(() => {\n if (this.#viewport !== viewport) return;\n this.#defaultSlot = viewport.shadowRoot?.querySelector('slot:not([name])') ?? undefined;\n this.#defaultSlot?.addEventListener('slotchange', this.#handleSlotChange);\n this.#syncObservedRoots();\n this.#scheduleProjectionUpdate({ measureRoots: true });\n });\n }\n\n disconnectedCallback(): void {\n this.#interruptPointerSession();\n this.#viewport?.removeEventListener('viewportchange', this.#handleTransformCommitted);\n this.#viewport?.removeEventListener('capabilitieschange', this.#handleCapabilitiesChange);\n this.#disconnectViewport();\n this.#disconnectObservers();\n this.#resetConnectionState();\n super.disconnectedCallback();\n }\n\n #disconnectViewport(): void {\n this.removeEventListener('nve-gesture-input', this.#handleGestureInput as EventListener);\n this.removeEventListener('nve-gesture', this.#handleGesture as EventListener);\n this.#defaultSlot?.removeEventListener('slotchange', this.#handleSlotChange);\n }\n\n #disconnectObservers(): void {\n this.#layoutResizeObserver?.disconnect();\n this.#rootResizeObserver?.disconnect();\n if (this.#animationFrame !== undefined) cancelAnimationFrame(this.#animationFrame);\n }\n\n #resetConnectionState(): void {\n this.#animationFrame = undefined;\n this.#measureRootsOnFrame = false;\n this.#gestureController.target = undefined;\n this.#pointerSession = undefined;\n this.#viewport = undefined;\n this.#defaultSlot = undefined;\n this.#projection = undefined;\n this.#contentBounds = [];\n this.#automaticItems = [];\n this._internals.states.delete('pan-eligible');\n this._internals.states.delete('panning');\n }\n\n /** Remeasures content bounds after preview or viewport roots move without resizing. */\n refresh(): void {\n this.#scheduleProjectionUpdate({ measureRoots: true });\n }\n\n render() {\n const projection = this.#projection;\n const viewport = this.#viewport;\n const visible =\n viewport && projection ? projectViewportMinimapRect(viewport.getVisibleRect(), projection) : undefined;\n return html`\n <div internal-host class=\"surface\">\n ${this.#renderBackground()}\n ${this.#renderPreview(projection)}\n ${this.#renderForeground(projection, visible)}\n </div>\n `;\n }\n\n #renderBackground() {\n return html`<svg class=\"background-layer\" aria-hidden=\"true\" focusable=\"false\">\n <rect class=\"background\" data-minimap-background width=\"100%\" height=\"100%\"></rect>\n </svg>`;\n }\n\n #renderPreview(projection?: ViewportMinimapProjection) {\n return html`<div\n class=\"preview\"\n style=${styleMap({\n transform: projection\n ? `translate(${projection.offsetX}px, ${projection.offsetY}px) scale(${projection.scale})`\n : 'none'\n })}\n >\n <slot name=\"preview\" @slotchange=${this.#handleSlotChange}></slot>\n </div>`;\n }\n\n #renderForeground(projection?: ViewportMinimapProjection, visible?: ViewportRect) {\n return html`<svg\n class=\"foreground-layer\"\n aria-hidden=\"true\"\n focusable=\"false\"\n viewBox=\"0 0 ${this.clientWidth} ${this.clientHeight}\"\n preserveAspectRatio=\"none\"\n >\n ${this.#renderAutomaticItems(projection)}\n ${this.#renderVisibleRegion(visible)}\n </svg>`;\n }\n\n #renderAutomaticItems(projection?: ViewportMinimapProjection) {\n if (!projection || this.#previewRoots.length) return nothing;\n return this.#automaticItems.map(item => this.#renderItem(item, projection));\n }\n\n #renderVisibleRegion(visible?: ViewportRect) {\n if (!visible) return nothing;\n return svg`<rect\n class=\"visible-region\"\n data-visible-region\n x=${visible.x}\n y=${visible.y}\n width=${visible.width}\n height=${visible.height}\n rx=\"2\"\n ></rect>`;\n }\n\n #renderItem(item: AutomaticPreviewItem, projection: ViewportMinimapProjection) {\n const rect = projectViewportMinimapRect(item, projection);\n return svg`<rect\n class=\"item\"\n data-item-key=${item.id}\n x=${rect.x}\n y=${rect.y}\n width=${rect.width}\n height=${rect.height}\n rx=\"2\"\n ></rect>`;\n }\n\n #connectResizeObservers(): void {\n const viewport = this.#viewport;\n if (!viewport || typeof ResizeObserver === 'undefined') return;\n this.#layoutResizeObserver = new ResizeObserver(entries => {\n this.#scheduleProjectionUpdate({\n measureRoots: entries.some(entry => entry.target === viewport || entry.target === this)\n });\n });\n this.#layoutResizeObserver.observe(viewport);\n this.#layoutResizeObserver.observe(this);\n this.#rootResizeObserver = new ResizeObserver(() => this.#scheduleProjectionUpdate({ measureRoots: true }));\n }\n\n #handleSlotChange = (): void => {\n this.#syncObservedRoots();\n this.#scheduleProjectionUpdate({ measureRoots: true });\n };\n\n #syncObservedRoots(): void {\n const viewport = this.#viewport;\n this.#rootResizeObserver?.disconnect();\n if (!viewport) return;\n const previewRoots = this.#previewRoots;\n const roots = previewRoots.length ? previewRoots : this.#viewportRoots;\n for (const root of roots) this.#rootResizeObserver?.observe(root);\n }\n\n #handleTransformCommitted = (): void => {\n const transform = this.#viewport?.getTransform();\n const session = this.#pointerSession;\n if (session?.active && transform) {\n session.transformStart = transform;\n session.transformStartDisplacementX = session.lastTotalDisplacementX;\n session.transformStartDisplacementY = session.lastTotalDisplacementY;\n }\n this.#scheduleProjectionUpdate({ measureRoots: false });\n };\n\n #handleCapabilitiesChange = (): void => {\n this.#syncPanEligibleState();\n this.requestUpdate();\n };\n\n #syncPanEligibleState(): void {\n const eligible = Boolean(this.#viewport?.pannable && this.#projection);\n if (this._internals.states.has('pan-eligible') === eligible) return;\n if (eligible) this._internals.states.add('pan-eligible');\n else this._internals.states.delete('pan-eligible');\n }\n\n #scheduleProjectionUpdate({ measureRoots }: ProjectionUpdate): void {\n this.#measureRootsOnFrame ||= measureRoots;\n if (this.#animationFrame !== undefined) return;\n this.#animationFrame = requestAnimationFrame(() => {\n this.#animationFrame = undefined;\n const shouldMeasureRoots = this.#measureRootsOnFrame;\n this.#measureRootsOnFrame = false;\n this.#updateProjection({ measureRoots: shouldMeasureRoots });\n });\n }\n\n #updateProjection({ measureRoots }: ProjectionUpdate): void {\n const viewport = this.#viewport;\n if (!viewport) return;\n if (measureRoots) {\n const previewRoots = this.#previewRoots;\n if (previewRoots.length) {\n this.#automaticItems = [];\n this.#contentBounds = this.#measureCustomContent(previewRoots);\n } else {\n this.#automaticItems = this.#measureAutomaticItems(viewport, this.#viewportRoots);\n this.#contentBounds = this.#automaticItems;\n }\n }\n this.#projection = createViewportMinimapProjection(this.#contentBounds, viewport.getVisibleRect(), {\n height: this.clientHeight,\n width: this.clientWidth\n });\n this.#syncPanEligibleState();\n this.requestUpdate();\n }\n\n #measureCustomContent(roots: readonly Element[]): readonly ViewportRect[] {\n const wrapper = this.renderRoot.querySelector<HTMLElement>('.preview');\n if (!wrapper) return [];\n const frame = wrapper.getBoundingClientRect();\n const transform = getComputedStyle(wrapper).transform;\n const matrix = new DOMMatrixReadOnly(transform === 'none' ? undefined : transform);\n const bounds: ViewportRect[] = [];\n for (const root of roots) {\n const rect = root.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) continue;\n bounds.push({\n x: (rect.left - frame.left) / matrix.m11,\n y: (rect.top - frame.top) / matrix.m11,\n width: rect.width / matrix.m11,\n height: rect.height / matrix.m11\n });\n }\n return bounds;\n }\n\n #measureAutomaticItems(viewport: Viewport, roots: readonly Element[]): readonly AutomaticPreviewItem[] {\n const frame = viewport.getBoundingClientRect();\n const transform = viewport.getTransform();\n const items: AutomaticPreviewItem[] = [];\n for (const root of roots) {\n const rect = root.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) continue;\n items.push({\n id: this.#keyForRoot(root),\n x: transform.x + (rect.left - frame.left) / transform.scale,\n y: transform.y + (rect.top - frame.top) / transform.scale,\n width: rect.width / transform.scale,\n height: rect.height / transform.scale\n });\n }\n return items;\n }\n\n #keyForRoot(root: Element): string {\n const id = root.id.trim();\n if (id) return id;\n const current = this.#rootKeys.get(root);\n if (current) return current;\n const key = `root-${this.#nextRootKey}`;\n this.#nextRootKey += 1;\n this.#rootKeys.set(root, key);\n return key;\n }\n\n #handleGestureInput = (event: CustomEvent<GestureInput>): void => {\n const input = event.detail;\n if (input.kind === 'pointerdown') this.#handlePointerDown(input);\n else if (input.kind === 'pointerend') this.#handlePointerEnd(input);\n else this.#handleWheel(input);\n };\n\n #handleWheel(input: WheelGestureInput): void {\n const viewport = this.#viewport;\n if (\n input.deltaY === 0 ||\n !viewport ||\n !viewport.zoomable ||\n !isImmediateRootActiveElement(viewport) ||\n !input.claim()\n ) {\n return;\n }\n const start = viewport.getTransform();\n const visible = viewport.getVisibleRect();\n const anchor = { x: visible.x + visible.width / 2, y: visible.y + visible.height / 2 };\n const factor = this.#gestureController.getWheelZoomFactor(input);\n const viewportCenter = { x: viewport.clientWidth / 2, y: viewport.clientHeight / 2 };\n viewport.requestZoom({\n anchor,\n event: input.event,\n factor,\n next: anchoredTransform(\n anchor,\n viewportCenter,\n Math.min(viewport.maxScale, Math.max(viewport.minScale, start.scale * factor))\n ),\n source: 'minimap'\n });\n }\n\n #handlePointerDown(input: Extract<GestureInput, { kind: 'pointerdown' }>): void {\n const nativeEvent = input.event;\n const viewport = this.#viewport;\n const projection = this.#projection;\n if (!viewport || nativeEvent.button !== 0 || !nativeEvent.isPrimary || (!viewport.pannable && !viewport.zoomable)) {\n return;\n }\n viewport.focus({ preventScroll: true });\n if (!projection || !viewport.pannable || !input.claim({ kind: 'drag' })) return;\n const start = viewport.getTransform();\n const indicator = nativeEvent\n .composedPath()\n .some(target => target instanceof Element && target.hasAttribute('data-visible-region'));\n this.#pointerSession = {\n active: false,\n activating: false,\n exceededThreshold: false,\n indicator,\n lastTotalDisplacementX: 0,\n lastTotalDisplacementY: 0,\n pointerId: nativeEvent.pointerId,\n dragProjection: projection,\n transformStart: start,\n transformStartDisplacementX: 0,\n transformStartDisplacementY: 0\n };\n }\n\n #handleGesture = (event: CustomEvent<Gesture<undefined>>): void => {\n const gesture = event.detail;\n if (gesture.kind === 'drag') this.#handlePointerDrag(gesture);\n };\n\n #handlePointerDrag(gesture: PointerMovementGesture): void {\n const session = this.#pointerSession;\n if (!session || session.pointerId !== gesture.event.pointerId) return;\n session.lastTotalDisplacementX = gesture.totalDisplacementX;\n session.lastTotalDisplacementY = gesture.totalDisplacementY;\n const distanceSquared = gesture.totalDisplacementX ** 2 + gesture.totalDisplacementY ** 2;\n if (distanceSquared < DRAG_THRESHOLD ** 2) return;\n session.exceededThreshold = true;\n if (!session.indicator) return;\n const proposal = this.#dragProposal(gesture, session);\n if (!session.active) this.#activateDrag(session, proposal);\n else session.navigation?.update(proposal);\n }\n\n #activateDrag(session: MinimapPointerSession, proposal: ViewportPanUpdateProposal): void {\n session.activating = true;\n const navigation = this.#viewport?.startPan({ ...proposal, source: 'minimap' });\n session.activating = false;\n if (!navigation) return;\n if (this.#pointerSession !== session) {\n if (session.pendingEnd) navigation.end(session.pendingEnd);\n return;\n }\n session.navigation = navigation;\n session.active = true;\n this._internals.states.add('panning');\n }\n\n #dragProposal(gesture: PointerMovementGesture, session: MinimapPointerSession): ViewportPanUpdateProposal {\n const displacementX = gesture.totalDisplacementX - session.transformStartDisplacementX;\n const displacementY = gesture.totalDisplacementY - session.transformStartDisplacementY;\n return {\n clientX: gesture.clientX,\n clientY: gesture.clientY,\n event: gesture.event,\n next: {\n scale: session.transformStart.scale,\n x: session.transformStart.x + displacementX / session.dragProjection.scale,\n y: session.transformStart.y + displacementY / session.dragProjection.scale\n }\n };\n }\n\n #handlePointerEnd(input: PointerEndGesture): void {\n const session = this.#pointerSession;\n if (!session || session.pointerId !== input.event.pointerId) return;\n session.lastTotalDisplacementX = input.totalDisplacementX;\n session.lastTotalDisplacementY = input.totalDisplacementY;\n if (session.active) {\n session.navigation?.end({ event: input.event, interrupted: input.interrupted, reason: input.reason });\n } else if (session.activating) {\n session.pendingEnd = { event: input.event, interrupted: input.interrupted, reason: input.reason };\n } else if (input.reason === 'up' && !session.exceededThreshold) {\n this.#requestClickPan(input.event, session);\n }\n this.#endPointerSession(session);\n }\n\n #requestClickPan(event: PointerEvent, session: MinimapPointerSession): void {\n const viewport = this.#viewport;\n if (!viewport) return;\n const frame = this.getBoundingClientRect();\n const point = unprojectViewportMinimapPoint(\n { x: event.clientX - frame.left, y: event.clientY - frame.top },\n session.dragProjection\n );\n const current = viewport.getTransform();\n const visible = viewport.getVisibleRect();\n viewport.requestPan({\n clientX: event.clientX,\n clientY: event.clientY,\n event,\n next: {\n scale: current.scale,\n x: point.x - visible.width / 2,\n y: point.y - visible.height / 2\n },\n source: 'minimap'\n });\n }\n\n #endPointerSession(session: MinimapPointerSession): void {\n if (this.#pointerSession !== session) return;\n this.#pointerSession = undefined;\n this._internals.states.delete('panning');\n this.requestUpdate();\n }\n\n #interruptPointerSession(): void {\n const session = this.#pointerSession;\n if (!session) return;\n this.#endPointerSession(session);\n const end: ViewportPanEndRequest = { event: new Event('disconnect'), interrupted: true, reason: 'cancel' };\n if (session.active) session.navigation?.end(end);\n else if (session.activating) session.pendingEnd = end;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { ViewportPanProposal, ViewportZoomProposal, ViewportZoomRequestOptions, ViewportTransform } from './viewport.types.js';
|
|
3
|
+
import type { ViewportZoomAction } from './viewport-navigation.types.js';
|
|
4
4
|
type ViewportNavigationHost = HTMLElement & ReactiveControllerHost & {
|
|
5
|
-
readonly
|
|
6
|
-
readonly
|
|
5
|
+
readonly pannable: boolean;
|
|
6
|
+
readonly zoomable: boolean;
|
|
7
|
+
requestPan(proposal: ViewportPanProposal): boolean;
|
|
8
|
+
requestZoom(proposal: ViewportZoomProposal, options?: ViewportZoomRequestOptions): boolean;
|
|
7
9
|
};
|
|
8
|
-
|
|
9
|
-
readonly animateTo: (target: Partial<ViewportTransform>, options?: ViewportAnimationOptions) => void;
|
|
10
|
-
readonly commitTransform: (next: ViewportTransform) => boolean;
|
|
11
|
-
readonly cancelAnimation: () => void;
|
|
12
|
-
readonly consumeAutoFit: () => void;
|
|
13
|
-
readonly events: ViewportNavigationEventDelegate;
|
|
10
|
+
interface ViewportNavigationDelegate {
|
|
14
11
|
readonly getTransform: () => ViewportTransform;
|
|
15
12
|
readonly getZoomTarget: (action: ViewportZoomAction) => ViewportTransform | undefined;
|
|
16
|
-
readonly rebasePointerSessions: () => void;
|
|
17
|
-
readonly viewportToClient: (viewportX: number, viewportY: number) => ViewportPoint;
|
|
18
13
|
}
|
|
19
|
-
/** Coordinates the viewport's opt-in keyboard and Invoker navigation behavior. */
|
|
20
14
|
export declare class ViewportNavigationController implements ReactiveController {
|
|
21
15
|
#private;
|
|
22
16
|
constructor(host: ViewportNavigationHost, delegate: ViewportNavigationDelegate);
|
|
@@ -7,19 +7,19 @@ var r = 20, i = 100, a = class {
|
|
|
7
7
|
#t;
|
|
8
8
|
#n = !1;
|
|
9
9
|
constructor(e, n) {
|
|
10
|
-
this.#e = e, this.#t = n, e.addController(this), new t(e, { isEnabled: () =>
|
|
10
|
+
this.#e = e, this.#t = n, e.addController(this), new t(e, { isEnabled: () => e.pannable || e.zoomable });
|
|
11
11
|
}
|
|
12
12
|
hostConnected() {
|
|
13
|
-
this.#e.addEventListener("nve-key", this.#i), this.#e.addEventListener("command", this.#r), this.#e.addEventListener("keydown", this.#o), this.#u(
|
|
13
|
+
this.#e.addEventListener("nve-key", this.#i), this.#e.addEventListener("command", this.#r), this.#e.addEventListener("keydown", this.#o), this.#u(this.#e.pannable || this.#e.zoomable);
|
|
14
14
|
}
|
|
15
15
|
hostDisconnected() {
|
|
16
16
|
this.#e.removeEventListener("nve-key", this.#i), this.#e.removeEventListener("command", this.#r), this.#e.removeEventListener("keydown", this.#o);
|
|
17
17
|
}
|
|
18
18
|
hostUpdated() {
|
|
19
|
-
this.#u(
|
|
19
|
+
this.#u(this.#e.pannable || this.#e.zoomable);
|
|
20
20
|
}
|
|
21
21
|
#r = (e) => {
|
|
22
|
-
let t = this.#e.
|
|
22
|
+
let t = this.#e.pannable ? o(e.command) : void 0;
|
|
23
23
|
if (t) {
|
|
24
24
|
this.#a(e, {
|
|
25
25
|
direction: t,
|
|
@@ -28,7 +28,7 @@ var r = 20, i = 100, a = class {
|
|
|
28
28
|
});
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
if (!this.#e.
|
|
31
|
+
if (!this.#e.zoomable) return;
|
|
32
32
|
let n = s(e.command);
|
|
33
33
|
if (!n) return;
|
|
34
34
|
let i = this.#t.getZoomTarget(n);
|
|
@@ -50,18 +50,16 @@ var r = 20, i = 100, a = class {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
#a(e, t) {
|
|
53
|
-
this.#t.consumeAutoFit(), this.#t.cancelAnimation();
|
|
54
53
|
let n = this.#t.getTransform(), r = t.viewportPixelStep / n.scale, i = {
|
|
55
54
|
scale: n.scale,
|
|
56
55
|
x: n.x + t.direction.horizontal * r,
|
|
57
56
|
y: n.y + t.direction.vertical * r
|
|
58
|
-
}
|
|
57
|
+
};
|
|
58
|
+
this.#e.requestPan({
|
|
59
59
|
event: e,
|
|
60
60
|
next: i,
|
|
61
|
-
source: t.source
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
this.#t.events.dispatchPan(a) && this.#t.commitTransform(i) && this.#t.rebasePointerSessions();
|
|
61
|
+
source: t.source
|
|
62
|
+
});
|
|
65
63
|
}
|
|
66
64
|
#o = (e) => {
|
|
67
65
|
if (!this.#c(e) || !e.ctrlKey && !e.metaKey) return;
|
|
@@ -71,27 +69,23 @@ var r = 20, i = 100, a = class {
|
|
|
71
69
|
n && (e.preventDefault(), this.#s(e, n, "keyboard"));
|
|
72
70
|
};
|
|
73
71
|
#s(e, t, r) {
|
|
74
|
-
this.#t.consumeAutoFit();
|
|
75
72
|
let i = this.#t.getTransform(), a = {
|
|
76
73
|
x: this.#e.clientWidth / 2,
|
|
77
74
|
y: this.#e.clientHeight / 2
|
|
78
|
-
}, o =
|
|
75
|
+
}, o = {
|
|
79
76
|
anchor: n(a.x, a.y, i),
|
|
80
|
-
clientX: o.x,
|
|
81
|
-
clientY: o.y,
|
|
82
77
|
event: e,
|
|
83
78
|
factor: t.scale / i.scale,
|
|
84
79
|
next: t,
|
|
85
|
-
source: r
|
|
86
|
-
start: i
|
|
80
|
+
source: r
|
|
87
81
|
};
|
|
88
|
-
this.#
|
|
82
|
+
this.#e.requestZoom(o, { animated: !0 });
|
|
89
83
|
}
|
|
90
84
|
#c(t) {
|
|
91
|
-
return this.#e.
|
|
85
|
+
return this.#e.zoomable && e(this.#e) && t.composedPath()[0] === this.#e;
|
|
92
86
|
}
|
|
93
87
|
#l(t) {
|
|
94
|
-
return
|
|
88
|
+
return this.#e.pannable && e(this.#e) && t.composedPath()[0] === this.#e && !t.ctrlKey && !t.metaKey && !t.altKey;
|
|
95
89
|
}
|
|
96
90
|
#u(e) {
|
|
97
91
|
e ? this.#e.hasAttribute("tabindex") || (this.#e.tabIndex = 0, this.#n = !0) : (this.#n && this.#e.getAttribute("tabindex") === "0" && this.#e.removeAttribute("tabindex"), this.#n = !1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewport-navigation.controller.js","names":[],"sources":["../../src/viewport/viewport-navigation.controller.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport {\n isImmediateRootActiveElement,\n KeyNavigationSpatialController,\n type SpatialKeyCommand\n} from '@nvidia-elements/core/internal';\nimport type {\n ViewportAnimationOptions,\n ViewportDiscretePanDetail,\n ViewportPanBehavior,\n ViewportPoint,\n ViewportTransform,\n ViewportZoomDetail\n} from './viewport.types.js';\nimport type { ViewportNavigationEventDelegate, ViewportZoomAction } from './viewport-navigation.types.js';\nimport { contentPointFromViewport } from './viewport-projection.utils.js';\n\nconst KEYBOARD_PAN_STEP = 20;\nconst KEYBOARD_PAN_LARGE_STEP = 100;\n\ninterface PanDirection {\n readonly horizontal: -1 | 0 | 1;\n readonly vertical: -1 | 0 | 1;\n}\n\ninterface DiscretePanRequest {\n readonly direction: PanDirection;\n readonly source: 'command' | 'keyboard';\n readonly viewportPixelStep: number;\n}\n\ntype ViewportNavigationHost = HTMLElement &\n ReactiveControllerHost & {\n readonly behaviorPan: ViewportPanBehavior;\n readonly behaviorZoom: boolean;\n };\n\nexport interface ViewportNavigationDelegate {\n readonly animateTo: (target: Partial<ViewportTransform>, options?: ViewportAnimationOptions) => void;\n readonly commitTransform: (next: ViewportTransform) => boolean;\n readonly cancelAnimation: () => void;\n readonly consumeAutoFit: () => void;\n readonly events: ViewportNavigationEventDelegate;\n readonly getTransform: () => ViewportTransform;\n readonly getZoomTarget: (action: ViewportZoomAction) => ViewportTransform | undefined;\n readonly rebasePointerSessions: () => void;\n readonly viewportToClient: (viewportX: number, viewportY: number) => ViewportPoint;\n}\n\n/** Coordinates the viewport's opt-in keyboard and Invoker navigation behavior. */\nexport class ViewportNavigationController implements ReactiveController {\n readonly #host: ViewportNavigationHost;\n readonly #delegate: ViewportNavigationDelegate;\n #managesTabIndex = false;\n\n constructor(host: ViewportNavigationHost, delegate: ViewportNavigationDelegate) {\n this.#host = host;\n this.#delegate = delegate;\n host.addController(this);\n new KeyNavigationSpatialController(host, { isEnabled: () => Boolean(host.behaviorPan) || host.behaviorZoom });\n }\n\n hostConnected(): void {\n this.#host.addEventListener('nve-key', this.#handleSpatialKey as EventListener);\n this.#host.addEventListener('command', this.#handleCommand as EventListener);\n this.#host.addEventListener('keydown', this.#handleViewportKeyDown as EventListener);\n this.#syncFocusability(Boolean(this.#host.behaviorPan) || this.#host.behaviorZoom);\n }\n\n hostDisconnected(): void {\n this.#host.removeEventListener('nve-key', this.#handleSpatialKey as EventListener);\n this.#host.removeEventListener('command', this.#handleCommand as EventListener);\n this.#host.removeEventListener('keydown', this.#handleViewportKeyDown as EventListener);\n }\n\n hostUpdated(): void {\n this.#syncFocusability(Boolean(this.#host.behaviorPan) || this.#host.behaviorZoom);\n }\n\n #handleCommand = (event: CommandEvent): void => {\n const panDirection = this.#host.behaviorPan ? commandPanDirection(event.command) : undefined;\n if (panDirection) {\n this.#requestDiscretePan(event, {\n direction: panDirection,\n source: 'command',\n viewportPixelStep: KEYBOARD_PAN_STEP\n });\n return;\n }\n if (!this.#host.behaviorZoom) return;\n const action = commandZoomAction(event.command);\n if (!action) return;\n const next = this.#delegate.getZoomTarget(action);\n if (next) this.#requestZoom(event, next, 'command');\n };\n\n #handleSpatialKey = (event: CustomEvent<SpatialKeyCommand>): void => {\n const command = event.detail;\n if (command.kind === 'direction') {\n if (!this.#acceptsKeyboardPan(command.event)) return;\n command.event.preventDefault();\n this.#requestDiscretePan(command.event, {\n direction: keyboardPanDirection(command.key),\n source: 'keyboard',\n viewportPixelStep: command.shiftKey ? KEYBOARD_PAN_LARGE_STEP : KEYBOARD_PAN_STEP\n });\n } else if (this.#acceptsKeyboardZoom(command.event)) {\n command.event.preventDefault();\n const action = command.key === '-' ? 'out' : 'in';\n const next = this.#delegate.getZoomTarget(action);\n if (next) this.#requestZoom(command.event, next, 'keyboard');\n }\n };\n\n #requestDiscretePan(event: CommandEvent | KeyboardEvent, request: DiscretePanRequest): void {\n this.#delegate.consumeAutoFit();\n this.#delegate.cancelAnimation();\n const start = this.#delegate.getTransform();\n const contentStep = request.viewportPixelStep / start.scale;\n const next = {\n scale: start.scale,\n x: start.x + request.direction.horizontal * contentStep,\n y: start.y + request.direction.vertical * contentStep\n };\n const detail: ViewportDiscretePanDetail = { event, next, source: request.source, start };\n if (this.#delegate.events.dispatchPan(detail) && this.#delegate.commitTransform(next)) {\n this.#delegate.rebasePointerSessions();\n }\n }\n\n #handleViewportKeyDown = (event: KeyboardEvent): void => {\n if (!this.#acceptsKeyboardZoom(event) || (!event.ctrlKey && !event.metaKey)) return;\n const action = event.key === '0' ? 'reset' : event.key === '1' ? 'fit' : undefined;\n if (!action) return;\n const next = this.#delegate.getZoomTarget(action);\n if (!next) return;\n event.preventDefault();\n this.#requestZoom(event, next, 'keyboard');\n };\n\n #requestZoom(event: CommandEvent | KeyboardEvent, next: ViewportTransform, source: 'command' | 'keyboard'): void {\n this.#delegate.consumeAutoFit();\n const start = this.#delegate.getTransform();\n const viewport = { x: this.#host.clientWidth / 2, y: this.#host.clientHeight / 2 };\n const client = this.#delegate.viewportToClient(viewport.x, viewport.y);\n const detail: ViewportZoomDetail = {\n anchor: contentPointFromViewport(viewport.x, viewport.y, start),\n clientX: client.x,\n clientY: client.y,\n event,\n factor: next.scale / start.scale,\n next,\n source,\n start\n };\n if (this.#delegate.events.dispatchZoom(detail)) this.#delegate.animateTo(next);\n }\n\n #acceptsKeyboardZoom(event: KeyboardEvent): boolean {\n return (\n this.#host.behaviorZoom && isImmediateRootActiveElement(this.#host) && event.composedPath()[0] === this.#host\n );\n }\n\n #acceptsKeyboardPan(event: KeyboardEvent): boolean {\n return (\n Boolean(this.#host.behaviorPan) &&\n isImmediateRootActiveElement(this.#host) &&\n event.composedPath()[0] === this.#host &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n );\n }\n\n #syncFocusability(behaviorEnabled: boolean): void {\n if (!behaviorEnabled) {\n if (this.#managesTabIndex && this.#host.getAttribute('tabindex') === '0') this.#host.removeAttribute('tabindex');\n this.#managesTabIndex = false;\n } else if (!this.#host.hasAttribute('tabindex')) {\n this.#host.tabIndex = 0;\n this.#managesTabIndex = true;\n }\n }\n}\n\nfunction commandPanDirection(command: string): PanDirection | undefined {\n if (command === '--pan-left') return { horizontal: -1, vertical: 0 };\n if (command === '--pan-right') return { horizontal: 1, vertical: 0 };\n if (command === '--pan-up') return { horizontal: 0, vertical: -1 };\n if (command === '--pan-down') return { horizontal: 0, vertical: 1 };\n return undefined;\n}\n\nfunction commandZoomAction(command: string): ViewportZoomAction | undefined {\n if (command === '--zoom-in') return 'in';\n if (command === '--zoom-out') return 'out';\n if (command === '--zoom-reset') return 'reset';\n if (command === '--zoom-to-fit') return 'fit';\n return undefined;\n}\n\nfunction keyboardPanDirection(key: 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'ArrowUp'): PanDirection {\n if (key === 'ArrowLeft') return { horizontal: -1, vertical: 0 };\n if (key === 'ArrowRight') return { horizontal: 1, vertical: 0 };\n if (key === 'ArrowUp') return { horizontal: 0, vertical: -1 };\n return { horizontal: 0, vertical: 1 };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"viewport-navigation.controller.js","names":[],"sources":["../../src/viewport/viewport-navigation.controller.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport {\n isImmediateRootActiveElement,\n KeyNavigationSpatialController,\n type SpatialKeyCommand\n} from '@nvidia-elements/core/internal';\nimport type {\n ViewportPanProposal,\n ViewportZoomProposal,\n ViewportZoomRequestOptions,\n ViewportTransform\n} from './viewport.types.js';\nimport type { ViewportZoomAction } from './viewport-navigation.types.js';\nimport { contentPointFromViewport } from './viewport-projection.utils.js';\n\nconst KEYBOARD_PAN_STEP = 20;\nconst KEYBOARD_PAN_LARGE_STEP = 100;\n\ninterface PanDirection {\n readonly horizontal: -1 | 0 | 1;\n readonly vertical: -1 | 0 | 1;\n}\n\ninterface DiscretePanRequest {\n readonly direction: PanDirection;\n readonly source: 'command' | 'keyboard';\n readonly viewportPixelStep: number;\n}\n\ntype ViewportNavigationHost = HTMLElement &\n ReactiveControllerHost & {\n readonly pannable: boolean;\n readonly zoomable: boolean;\n requestPan(proposal: ViewportPanProposal): boolean;\n requestZoom(proposal: ViewportZoomProposal, options?: ViewportZoomRequestOptions): boolean;\n };\n\ninterface ViewportNavigationDelegate {\n readonly getTransform: () => ViewportTransform;\n readonly getZoomTarget: (action: ViewportZoomAction) => ViewportTransform | undefined;\n}\n\nexport class ViewportNavigationController implements ReactiveController {\n readonly #host: ViewportNavigationHost;\n readonly #delegate: ViewportNavigationDelegate;\n #managesTabIndex = false;\n\n constructor(host: ViewportNavigationHost, delegate: ViewportNavigationDelegate) {\n this.#host = host;\n this.#delegate = delegate;\n host.addController(this);\n new KeyNavigationSpatialController(host, { isEnabled: () => host.pannable || host.zoomable });\n }\n\n hostConnected(): void {\n this.#host.addEventListener('nve-key', this.#handleSpatialKey as EventListener);\n this.#host.addEventListener('command', this.#handleCommand as EventListener);\n this.#host.addEventListener('keydown', this.#handleViewportKeyDown as EventListener);\n this.#syncFocusability(this.#host.pannable || this.#host.zoomable);\n }\n\n hostDisconnected(): void {\n this.#host.removeEventListener('nve-key', this.#handleSpatialKey as EventListener);\n this.#host.removeEventListener('command', this.#handleCommand as EventListener);\n this.#host.removeEventListener('keydown', this.#handleViewportKeyDown as EventListener);\n }\n\n hostUpdated(): void {\n this.#syncFocusability(this.#host.pannable || this.#host.zoomable);\n }\n\n #handleCommand = (event: CommandEvent): void => {\n const panDirection = this.#host.pannable ? commandPanDirection(event.command) : undefined;\n if (panDirection) {\n this.#requestDiscretePan(event, {\n direction: panDirection,\n source: 'command',\n viewportPixelStep: KEYBOARD_PAN_STEP\n });\n return;\n }\n if (!this.#host.zoomable) return;\n const action = commandZoomAction(event.command);\n if (!action) return;\n const next = this.#delegate.getZoomTarget(action);\n if (next) this.#requestZoom(event, next, 'command');\n };\n\n #handleSpatialKey = (event: CustomEvent<SpatialKeyCommand>): void => {\n const command = event.detail;\n if (command.kind === 'direction') {\n if (!this.#acceptsKeyboardPan(command.event)) return;\n command.event.preventDefault();\n this.#requestDiscretePan(command.event, {\n direction: keyboardPanDirection(command.key),\n source: 'keyboard',\n viewportPixelStep: command.shiftKey ? KEYBOARD_PAN_LARGE_STEP : KEYBOARD_PAN_STEP\n });\n } else if (this.#acceptsKeyboardZoom(command.event)) {\n command.event.preventDefault();\n const action = command.key === '-' ? 'out' : 'in';\n const next = this.#delegate.getZoomTarget(action);\n if (next) this.#requestZoom(command.event, next, 'keyboard');\n }\n };\n\n #requestDiscretePan(event: CommandEvent | KeyboardEvent, request: DiscretePanRequest): void {\n const start = this.#delegate.getTransform();\n const contentStep = request.viewportPixelStep / start.scale;\n const next = {\n scale: start.scale,\n x: start.x + request.direction.horizontal * contentStep,\n y: start.y + request.direction.vertical * contentStep\n };\n this.#host.requestPan({ event, next, source: request.source });\n }\n\n #handleViewportKeyDown = (event: KeyboardEvent): void => {\n if (!this.#acceptsKeyboardZoom(event) || (!event.ctrlKey && !event.metaKey)) return;\n const action = event.key === '0' ? 'reset' : event.key === '1' ? 'fit' : undefined;\n if (!action) return;\n const next = this.#delegate.getZoomTarget(action);\n if (!next) return;\n event.preventDefault();\n this.#requestZoom(event, next, 'keyboard');\n };\n\n #requestZoom(event: CommandEvent | KeyboardEvent, next: ViewportTransform, source: 'command' | 'keyboard'): void {\n const start = this.#delegate.getTransform();\n const viewport = { x: this.#host.clientWidth / 2, y: this.#host.clientHeight / 2 };\n const proposal: ViewportZoomProposal = {\n anchor: contentPointFromViewport(viewport.x, viewport.y, start),\n event,\n factor: next.scale / start.scale,\n next,\n source\n };\n this.#host.requestZoom(proposal, { animated: true });\n }\n\n #acceptsKeyboardZoom(event: KeyboardEvent): boolean {\n return this.#host.zoomable && isImmediateRootActiveElement(this.#host) && event.composedPath()[0] === this.#host;\n }\n\n #acceptsKeyboardPan(event: KeyboardEvent): boolean {\n return (\n this.#host.pannable &&\n isImmediateRootActiveElement(this.#host) &&\n event.composedPath()[0] === this.#host &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n );\n }\n\n #syncFocusability(behaviorEnabled: boolean): void {\n if (!behaviorEnabled) {\n if (this.#managesTabIndex && this.#host.getAttribute('tabindex') === '0') this.#host.removeAttribute('tabindex');\n this.#managesTabIndex = false;\n } else if (!this.#host.hasAttribute('tabindex')) {\n this.#host.tabIndex = 0;\n this.#managesTabIndex = true;\n }\n }\n}\n\nfunction commandPanDirection(command: string): PanDirection | undefined {\n if (command === '--pan-left') return { horizontal: -1, vertical: 0 };\n if (command === '--pan-right') return { horizontal: 1, vertical: 0 };\n if (command === '--pan-up') return { horizontal: 0, vertical: -1 };\n if (command === '--pan-down') return { horizontal: 0, vertical: 1 };\n return undefined;\n}\n\nfunction commandZoomAction(command: string): ViewportZoomAction | undefined {\n if (command === '--zoom-in') return 'in';\n if (command === '--zoom-out') return 'out';\n if (command === '--zoom-reset') return 'reset';\n if (command === '--zoom-to-fit') return 'fit';\n return undefined;\n}\n\nfunction keyboardPanDirection(key: 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'ArrowUp'): PanDirection {\n if (key === 'ArrowLeft') return { horizontal: -1, vertical: 0 };\n if (key === 'ArrowRight') return { horizontal: 1, vertical: 0 };\n if (key === 'ArrowUp') return { horizontal: 0, vertical: -1 };\n return { horizontal: 0, vertical: 1 };\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
import type { ViewportPanDetail, ViewportPanEndDetail, ViewportPointerPanDetail, ViewportZoomDetail } from './viewport.types.js';
|
|
2
1
|
export type ViewportZoomAction = 'fit' | 'in' | 'out' | 'reset';
|
|
3
|
-
/** Dispatches public viewport navigation events on behalf of navigation controllers. */
|
|
4
|
-
export interface ViewportNavigationEventDelegate {
|
|
5
|
-
readonly dispatchPanStart: (detail: ViewportPointerPanDetail) => boolean;
|
|
6
|
-
readonly dispatchPan: (detail: ViewportPanDetail) => boolean;
|
|
7
|
-
readonly dispatchPanEnd: (detail: ViewportPanEndDetail) => void;
|
|
8
|
-
readonly dispatchZoom: (detail: ViewportZoomDetail) => boolean;
|
|
9
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, type PropertyValues } from 'lit';
|
|
2
|
-
import type { ViewportAnimationOptions, ViewportPanBehavior, ViewportPoint, ViewportRect, ViewportRevealOptions, ViewportTransform } from './viewport.types.js';
|
|
2
|
+
import type { ViewportAnimationOptions, ViewportPanBehavior, ViewportPanProposal, ViewportPanSession, ViewportPoint, ViewportRect, ViewportRevealOptions, ViewportTransform, ViewportZoomProposal, ViewportZoomRequestOptions } from './viewport.types.js';
|
|
3
3
|
/**
|
|
4
4
|
* @element nve-viewport
|
|
5
5
|
* @description A viewport provides a spatial surface for arbitrary content, with optional pan and zoom navigation.
|
|
@@ -8,11 +8,13 @@ import type { ViewportAnimationOptions, ViewportPanBehavior, ViewportPoint, View
|
|
|
8
8
|
* @entrypoint \@nvidia-elements/core/viewport
|
|
9
9
|
* @slot - Content positioned in the viewport's infinite content space.
|
|
10
10
|
* @slot background - Custom content rendered behind viewport content and excluded from content fitting
|
|
11
|
-
* @
|
|
12
|
-
* @event
|
|
13
|
-
* @event
|
|
14
|
-
* @event
|
|
11
|
+
* @slot overlay - Interactive content fixed above the transformed plane and excluded from content fitting
|
|
12
|
+
* @event panstart - Dispatched when a sustained pointer or control pan begins. Cancel to suppress the default for its session.
|
|
13
|
+
* @event pan - Dispatched for admitted user pan proposals. Cancel to skip the proposed transform mutation.
|
|
14
|
+
* @event panend - Dispatched once when a sustained pan ends, including its terminal reason.
|
|
15
|
+
* @event zoom - Dispatched for admitted user zoom proposals. Cancel to skip the proposed transform mutation.
|
|
15
16
|
* @event viewportchange - Dispatched once after a render that commits one or more viewport transform changes.
|
|
17
|
+
* @event capabilitieschange - Dispatched after effective user-input pan or zoom admission changes.
|
|
16
18
|
* @cssprop --background - Background color of the fixed viewport area.
|
|
17
19
|
* @cssprop --min-height
|
|
18
20
|
* @cssprop --pan-cursor - Cursor shown over a background eligible for primary-pointer panning.
|
|
@@ -58,6 +60,10 @@ export declare class Viewport extends LitElement {
|
|
|
58
60
|
set behaviorPan(value: ViewportPanBehavior | null | undefined);
|
|
59
61
|
/** Enables zooming by pinch, focused modified wheel, focused keyboard, and Invoker commands. */
|
|
60
62
|
behaviorZoom: boolean;
|
|
63
|
+
/** Whether the viewport may admit new user-input panning. */
|
|
64
|
+
get pannable(): boolean;
|
|
65
|
+
/** Whether the viewport may admit new user-input zooming. */
|
|
66
|
+
get zoomable(): boolean;
|
|
61
67
|
/** Fits measurable direct default-slot content once after initial layout. */
|
|
62
68
|
autoFit: boolean;
|
|
63
69
|
/** Default uniform CSS-pixel inset reserved around bounds when fitting content. */
|
|
@@ -69,7 +75,7 @@ export declare class Viewport extends LitElement {
|
|
|
69
75
|
connectedCallback(): void;
|
|
70
76
|
disconnectedCallback(): void;
|
|
71
77
|
protected updated(changed: PropertyValues<this>): void;
|
|
72
|
-
render(): import("lit").TemplateResult<1>;
|
|
78
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
73
79
|
/** Converts a content-space point to viewport CSS pixels. */
|
|
74
80
|
toViewportCoords(contentX: number, contentY: number): ViewportPoint;
|
|
75
81
|
/** Converts a viewport CSS-pixel point to content space. */
|
|
@@ -78,6 +84,25 @@ export declare class Viewport extends LitElement {
|
|
|
78
84
|
getTransform(): ViewportTransform;
|
|
79
85
|
/** Returns the visible content-space rectangle. */
|
|
80
86
|
getVisibleRect(): ViewportRect;
|
|
87
|
+
/**
|
|
88
|
+
* Requests one discrete user-originated pan. When pannable, the viewport dispatches
|
|
89
|
+
* a cancelable `pan` and applies the default transform if no listener cancels the event.
|
|
90
|
+
* Returns true only when that default changes the transform.
|
|
91
|
+
*/
|
|
92
|
+
requestPan(proposal: ViewportPanProposal): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Requests one discrete user-originated zoom. When zoomable, the viewport dispatches
|
|
95
|
+
* a cancelable `zoom` and applies the default transform if no listener cancels the event.
|
|
96
|
+
* Set `options.animated` to animate the uncanceled default; the option is absent from the `zoom` detail.
|
|
97
|
+
* Returns true when the default changes or schedules a change to the transform.
|
|
98
|
+
*/
|
|
99
|
+
requestZoom(proposal: ViewportZoomProposal, options?: ViewportZoomRequestOptions): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Starts a sustained semantic pan after the caller crosses its activation threshold.
|
|
102
|
+
* Dispatches `panstart`, performs the initial `pan` update, and returns a session for later updates
|
|
103
|
+
* and one terminal `panend`. Returns undefined when pannable is false.
|
|
104
|
+
*/
|
|
105
|
+
startPan(proposal: ViewportPanProposal): ViewportPanSession | undefined;
|
|
81
106
|
/** Animates the viewport to the requested partial transform. */
|
|
82
107
|
animateTo(target: Partial<ViewportTransform>, options?: ViewportAnimationOptions): void;
|
|
83
108
|
/** Centers or fits a content-space region within the viewport. */
|