@nvidia-elements/core 2.11.1 → 2.12.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/accordion/accordion2.js +4 -4
  3. package/dist/alert/alert-group2.js +1 -1
  4. package/dist/alert/alert2.js +1 -1
  5. package/dist/avatar/avatar-group2.js +1 -1
  6. package/dist/avatar/avatar2.js +1 -1
  7. package/dist/badge/badge2.js +1 -1
  8. package/dist/breadcrumb/breadcrumb2.js +1 -1
  9. package/dist/bundles/index.d.ts +8 -2
  10. package/dist/bundles/index.js +6 -6
  11. package/dist/button/button2.js +1 -1
  12. package/dist/button-group/button-group2.js +1 -1
  13. package/dist/card/card2.js +4 -4
  14. package/dist/chat-message/chat-message2.js +1 -1
  15. package/dist/checkbox/checkbox-group2.js +1 -1
  16. package/dist/checkbox/checkbox2.js +1 -1
  17. package/dist/color/color2.js +1 -1
  18. package/dist/combobox/combobox2.js +1 -1
  19. package/dist/copy-button/copy-button2.js +1 -1
  20. package/dist/custom-elements-jsx.d.ts +8 -2
  21. package/dist/custom-elements-vue.d.ts +8 -2
  22. package/dist/custom-elements.json +64 -3
  23. package/dist/data.html.json +11 -1
  24. package/dist/data.snippets.json +18 -18
  25. package/dist/date/date2.js +1 -1
  26. package/dist/datetime/datetime2.js +1 -1
  27. package/dist/dialog/dialog-footer2.js +1 -1
  28. package/dist/dialog/dialog-header2.js +1 -1
  29. package/dist/dialog/dialog2.js +1 -1
  30. package/dist/divider/divider2.js +1 -1
  31. package/dist/dot/dot2.js +1 -1
  32. package/dist/drawer/drawer-content2.js +1 -1
  33. package/dist/drawer/drawer-footer2.js +1 -1
  34. package/dist/drawer/drawer-header2.js +1 -1
  35. package/dist/drawer/drawer2.js +1 -1
  36. package/dist/dropdown/dropdown-footer2.js +1 -1
  37. package/dist/dropdown/dropdown-header2.js +1 -1
  38. package/dist/dropdown/dropdown2.js +1 -1
  39. package/dist/dropdown-group/dropdown-group.js +1 -1
  40. package/dist/dropzone/dropzone2.js +1 -1
  41. package/dist/file/file2.js +1 -1
  42. package/dist/format-bytes/format-bytes2.js +1 -1
  43. package/dist/format-datetime/format-datetime2.js +1 -1
  44. package/dist/format-number/format-number2.js +1 -1
  45. package/dist/format-relative-time/format-relative-time2.js +1 -1
  46. package/dist/format-truncate/format-truncate2.js +1 -1
  47. package/dist/forms/control/control2.js +1 -1
  48. package/dist/forms/control-group/control-group2.js +1 -1
  49. package/dist/forms/control-message/control-message2.js +1 -1
  50. package/dist/gauge/gauge2.js +1 -1
  51. package/dist/grid/cell/cell2.js +1 -1
  52. package/dist/grid/column/column2.js +1 -1
  53. package/dist/grid/footer/footer2.js +1 -1
  54. package/dist/grid/grid2.js +1 -1
  55. package/dist/grid/header/header2.js +1 -1
  56. package/dist/grid/placeholder/placeholder2.js +1 -1
  57. package/dist/grid/row/row2.js +1 -1
  58. package/dist/icon/icon2.js +2 -2
  59. package/dist/icon-button/icon-button2.js +1 -1
  60. package/dist/index.js +1 -1
  61. package/dist/input/input-group2.js +1 -1
  62. package/dist/input/input2.js +1 -1
  63. package/dist/internal/services/global.service.js +1 -1
  64. package/dist/logo/logo2.js +1 -1
  65. package/dist/menu/menu-group2.js +1 -1
  66. package/dist/menu/menu-item2.js +1 -1
  67. package/dist/menu/menu2.js +1 -1
  68. package/dist/month/month2.js +1 -1
  69. package/dist/notification/notification-group2.js +1 -1
  70. package/dist/notification/notification2.js +1 -1
  71. package/dist/page/page-panel/page-panel-content2.js +1 -1
  72. package/dist/page/page-panel/page-panel-footer2.js +1 -1
  73. package/dist/page/page-panel/page-panel-header2.js +1 -1
  74. package/dist/page/page-panel/page-panel.d.ts +2 -0
  75. package/dist/page/page-panel/page-panel.js +1 -1
  76. package/dist/page/page-panel/page-panel.js.map +1 -1
  77. package/dist/page/page-panel/page-panel2.js +8 -2
  78. package/dist/page/page-panel/page-panel2.js.map +1 -1
  79. package/dist/page/page.examples.js.map +1 -1
  80. package/dist/page/page.examples.json +11 -0
  81. package/dist/page/page.js +1 -1
  82. package/dist/page/page.js.map +1 -1
  83. package/dist/page/page2.js +1 -1
  84. package/dist/page-header/page-header2.js +1 -1
  85. package/dist/page-loader/page-loader2.js +1 -1
  86. package/dist/pagination/pagination2.js +1 -1
  87. package/dist/panel/panel2.js +4 -4
  88. package/dist/password/password2.js +1 -1
  89. package/dist/preferences-input/preferences-input2.js +1 -1
  90. package/dist/progress-bar/progress-bar2.js +1 -1
  91. package/dist/progress-ring/progress-ring2.js +1 -1
  92. package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
  93. package/dist/pulse/pulse2.js +1 -1
  94. package/dist/radio/radio-group2.js +1 -1
  95. package/dist/radio/radio2.js +1 -1
  96. package/dist/range/range2.js +1 -1
  97. package/dist/resize-handle/resize-handle2.js +1 -1
  98. package/dist/search/search2.js +1 -1
  99. package/dist/select/select2.js +1 -1
  100. package/dist/skeleton/skeleton2.js +1 -1
  101. package/dist/sort-button/sort-button2.js +1 -1
  102. package/dist/sparkline/sparkline2.js +1 -1
  103. package/dist/star-rating/star-rating2.js +1 -1
  104. package/dist/steps/steps2.js +2 -2
  105. package/dist/switch/switch-group2.js +1 -1
  106. package/dist/switch/switch2.js +1 -1
  107. package/dist/tabs/tabs-group2.js +1 -1
  108. package/dist/tabs/tabs2.js +2 -2
  109. package/dist/tag/tag2.js +1 -1
  110. package/dist/textarea/textarea2.js +1 -1
  111. package/dist/time/time2.js +1 -1
  112. package/dist/toast/toast2.js +1 -1
  113. package/dist/toggletip/toggletip-footer2.js +1 -1
  114. package/dist/toggletip/toggletip-header2.js +1 -1
  115. package/dist/toggletip/toggletip2.js +1 -1
  116. package/dist/toolbar/toolbar2.js +1 -1
  117. package/dist/tooltip/tooltip2.js +1 -1
  118. package/dist/tree/tree-node2.js +1 -1
  119. package/dist/tree/tree2.js +1 -1
  120. package/dist/viewport/viewport-gridlines.d.ts +6 -2
  121. package/dist/viewport/viewport-gridlines.js +1 -1
  122. package/dist/viewport/viewport-gridlines.js.map +1 -1
  123. package/dist/viewport/viewport-gridlines2.js +39 -29
  124. package/dist/viewport/viewport-gridlines2.js.map +1 -1
  125. package/dist/viewport/viewport-minimap2.js +1 -1
  126. package/dist/viewport/viewport.examples.js.map +1 -1
  127. package/dist/viewport/viewport.examples.json +28 -10
  128. package/dist/viewport/viewport2.js +1 -1
  129. package/dist/week/week2.js +1 -1
  130. package/package.json +1 -1
@@ -27,7 +27,7 @@ var S = class extends d {
27
27
  static {
28
28
  this.metadata = {
29
29
  tag: "nve-select",
30
- version: "2.11.1"
30
+ version: "2.12.0"
31
31
  };
32
32
  }
33
33
  static {
@@ -15,7 +15,7 @@ var s = class extends i {
15
15
  static {
16
16
  this.metadata = {
17
17
  tag: "nve-skeleton",
18
- version: "2.11.1"
18
+ version: "2.12.0"
19
19
  };
20
20
  }
21
21
  render() {
@@ -19,7 +19,7 @@ var u = {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-sort-button",
22
- version: "2.11.1"
22
+ version: "2.12.0"
23
23
  };
24
24
  }
25
25
  static {
@@ -21,7 +21,7 @@ var C = class extends _ {
21
21
  static {
22
22
  this.metadata = {
23
23
  tag: "nve-sparkline",
24
- version: "2.11.1"
24
+ version: "2.12.0"
25
25
  };
26
26
  }
27
27
  render() {
@@ -18,7 +18,7 @@ var l = class extends a {
18
18
  static {
19
19
  this.metadata = {
20
20
  tag: "nve-star-rating",
21
- version: "2.11.1"
21
+ version: "2.12.0"
22
22
  };
23
23
  }
24
24
  static {
@@ -23,7 +23,7 @@ var v = class extends h(d) {
23
23
  static {
24
24
  this.metadata = {
25
25
  tag: "nve-steps-item",
26
- version: "2.11.1",
26
+ version: "2.12.0",
27
27
  parents: ["nve-steps"]
28
28
  };
29
29
  }
@@ -69,7 +69,7 @@ var y = class extends d {
69
69
  static {
70
70
  this.metadata = {
71
71
  tag: "nve-steps",
72
- version: "2.11.1",
72
+ version: "2.12.0",
73
73
  children: ["nve-steps-item"]
74
74
  };
75
75
  }
@@ -11,7 +11,7 @@ var a = class extends r {
11
11
  static {
12
12
  this.metadata = {
13
13
  tag: "nve-switch-group",
14
- version: "2.11.1",
14
+ version: "2.12.0",
15
15
  children: [
16
16
  "label",
17
17
  "nve-control-message",
@@ -15,7 +15,7 @@ var o = class extends i {
15
15
  static {
16
16
  this.metadata = {
17
17
  tag: "nve-switch",
18
- version: "2.11.1",
18
+ version: "2.12.0",
19
19
  children: [
20
20
  "label",
21
21
  "input",
@@ -33,7 +33,7 @@ var m, h = class extends l {
33
33
  static {
34
34
  this.metadata = {
35
35
  tag: "nve-tabs-group",
36
- version: "2.11.1",
36
+ version: "2.12.0",
37
37
  children: ["nve-tabs"]
38
38
  };
39
39
  }
@@ -20,7 +20,7 @@ var _ = class extends h(f) {
20
20
  static {
21
21
  this.metadata = {
22
22
  tag: "nve-tabs-item",
23
- version: "2.11.1",
23
+ version: "2.12.0",
24
24
  parents: ["nve-tabs"]
25
25
  };
26
26
  }
@@ -53,7 +53,7 @@ var v = class extends f {
53
53
  static {
54
54
  this.metadata = {
55
55
  tag: "nve-tabs",
56
- version: "2.11.1",
56
+ version: "2.12.0",
57
57
  children: ["nve-tabs-item"]
58
58
  };
59
59
  }
package/dist/tag/tag2.js CHANGED
@@ -17,7 +17,7 @@ var p = class extends d(c) {
17
17
  static {
18
18
  this.metadata = {
19
19
  tag: "nve-tag",
20
- version: "2.11.1"
20
+ version: "2.12.0"
21
21
  };
22
22
  }
23
23
  static {
@@ -16,7 +16,7 @@ var i = class extends t {
16
16
  static {
17
17
  this.metadata = {
18
18
  tag: "nve-textarea",
19
- version: "2.11.1"
19
+ version: "2.12.0"
20
20
  };
21
21
  }
22
22
  };
@@ -19,7 +19,7 @@ var l = class extends r {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-time",
22
- version: "2.11.1"
22
+ version: "2.12.0"
23
23
  };
24
24
  }
25
25
  static {
@@ -23,7 +23,7 @@ var g = class extends f {
23
23
  static {
24
24
  this.metadata = {
25
25
  tag: "nve-toast",
26
- version: "2.11.1"
26
+ version: "2.12.0"
27
27
  };
28
28
  }
29
29
  static {
@@ -11,7 +11,7 @@ var o = class extends i {
11
11
  static {
12
12
  this.metadata = {
13
13
  tag: "nve-toggletip-footer",
14
- version: "2.11.1",
14
+ version: "2.12.0",
15
15
  parents: ["nve-toggletip"]
16
16
  };
17
17
  }
@@ -11,7 +11,7 @@ var o = class extends i {
11
11
  static {
12
12
  this.metadata = {
13
13
  tag: "nve-toggletip-header",
14
- version: "2.11.1",
14
+ version: "2.12.0",
15
15
  parents: ["nve-toggletip"]
16
16
  };
17
17
  }
@@ -24,7 +24,7 @@ var g = class extends f {
24
24
  static {
25
25
  this.metadata = {
26
26
  tag: "nve-toggletip",
27
- version: "2.11.1"
27
+ version: "2.12.0"
28
28
  };
29
29
  }
30
30
  static {
@@ -21,7 +21,7 @@ var f = class extends c {
21
21
  static {
22
22
  this.metadata = {
23
23
  tag: "nve-toolbar",
24
- version: "2.11.1"
24
+ version: "2.12.0"
25
25
  };
26
26
  }
27
27
  static {
@@ -19,7 +19,7 @@ var d = class extends s {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-tooltip",
22
- version: "2.11.1"
22
+ version: "2.12.0"
23
23
  };
24
24
  }
25
25
  render() {
@@ -44,7 +44,7 @@ var E = class extends b {
44
44
  static {
45
45
  this.metadata = {
46
46
  tag: "nve-tree-node",
47
- version: "2.11.1",
47
+ version: "2.12.0",
48
48
  parents: ["nve-tree", "nve-tree-node"]
49
49
  };
50
50
  }
@@ -22,7 +22,7 @@ var m = class extends d {
22
22
  static {
23
23
  this.metadata = {
24
24
  tag: "nve-tree",
25
- version: "2.11.1",
25
+ version: "2.12.0",
26
26
  children: ["nve-tree-node"]
27
27
  };
28
28
  }
@@ -1,12 +1,14 @@
1
1
  import { LitElement, nothing, type PropertyValues } from 'lit';
2
2
  /**
3
3
  * @element nve-viewport-gridlines
4
- * @description Renders origin-stable, zoom-adaptive gridlines behind viewport content.
4
+ * @description Renders origin-stable, zoom-adaptive gridline patterns behind viewport content.
5
5
  * @documentation https://nvidia.github.io/elements/docs/elements/viewport/
6
6
  * @since 0.0.0
7
7
  * @entrypoint \@nvidia-elements/core/viewport
8
- * @cssprop --color - Sets the gridline stroke color.
8
+ * @cssprop --color - Sets the gridline pattern color.
9
9
  * @cssprop --line-width - Sets the approximate stroke width in CSS pixels.
10
+ * @cssprop --dot-radius - Sets the approximate dot radius in CSS pixels.
11
+ * @cssprop --cross-size - Sets the approximate full width and height of each cross in CSS pixels.
10
12
  */
11
13
  export declare class ViewportGridlines extends LitElement {
12
14
  #private;
@@ -19,6 +21,8 @@ export declare class ViewportGridlines extends LitElement {
19
21
  slot: string;
20
22
  /** @private */
21
23
  protected accessibilityHidden: string;
24
+ /** Grid pattern to render. */
25
+ pattern: 'lines' | 'dots' | 'crosses';
22
26
  /** Smallest gridline interval in content-space units. */
23
27
  get step(): number;
24
28
  set step(value: number);
@@ -1,5 +1,5 @@
1
1
  //#region src/viewport/viewport-gridlines.css?inline
2
- var e = ":host{--_scale: 1;--color: var(--nve-ref-border-color-muted);--line-width: 1px;position:absolute;inset:0;contain:none;pointer-events:none;user-select:none}svg{position:absolute;overflow:visible;pointer-events:none}path{fill:none;stroke:var(--color);stroke-width:calc(var(--line-width) / var(--_scale))}";
2
+ var e = ":host{--color: var(--nve-ref-border-color-muted);--line-width: var(--nve-ref-border-width-sm);--dot-radius: var(--nve-ref-size-50);--cross-size: var(--nve-ref-size-200);--_scale: 1;position:absolute;inset:0;contain:none;pointer-events:none;user-select:none}svg{position:absolute;overflow:visible;pointer-events:none}path{fill:none;stroke:var(--color);stroke-width:calc(var(--line-width) / var(--_scale))}circle{fill:var(--color);r:calc(var(--dot-radius) / var(--_scale))}.cross{fill:var(--color)}.cross-horizontal{x:calc(var(--cross-size) / var(--_scale) / -2);y:calc(var(--line-width) / var(--_scale) / -2);width:calc(var(--cross-size) / var(--_scale));height:calc(var(--line-width) / var(--_scale))}.cross-vertical{x:calc(var(--line-width) / var(--_scale) / -2);y:calc(var(--cross-size) / var(--_scale) / -2);width:calc(var(--line-width) / var(--_scale));height:calc(var(--cross-size) / var(--_scale))}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"viewport-gridlines.js","names":[],"sources":["../../src/viewport/viewport-gridlines.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\n:host {\n --_scale: 1;\n --color: var(--nve-ref-border-color-muted);\n --line-width: 1px;\n\n position: absolute;\n inset: 0;\n contain: none;\n pointer-events: none;\n user-select: none;\n}\n\nsvg {\n position: absolute;\n overflow: visible;\n pointer-events: none;\n}\n\npath {\n fill: none;\n stroke: var(--color);\n stroke-width: calc(var(--line-width) / var(--_scale));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"viewport-gridlines.js","names":[],"sources":["../../src/viewport/viewport-gridlines.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\n:host {\n --color: var(--nve-ref-border-color-muted);\n --line-width: var(--nve-ref-border-width-sm);\n --dot-radius: var(--nve-ref-size-50);\n --cross-size: var(--nve-ref-size-200);\n\n --_scale: 1;\n\n position: absolute;\n inset: 0;\n contain: none;\n pointer-events: none;\n user-select: none;\n}\n\nsvg {\n position: absolute;\n overflow: visible;\n pointer-events: none;\n}\n\npath {\n fill: none;\n stroke: var(--color);\n stroke-width: calc(var(--line-width) / var(--_scale));\n}\n\ncircle {\n fill: var(--color);\n r: calc(var(--dot-radius) / var(--_scale));\n}\n\n.cross {\n fill: var(--color);\n}\n\n.cross-horizontal {\n x: calc(var(--cross-size) / var(--_scale) / -2);\n y: calc(var(--line-width) / var(--_scale) / -2);\n width: calc(var(--cross-size) / var(--_scale));\n height: calc(var(--line-width) / var(--_scale));\n}\n\n.cross-vertical {\n x: calc(var(--line-width) / var(--_scale) / -2);\n y: calc(var(--cross-size) / var(--_scale) / -2);\n width: calc(var(--line-width) / var(--_scale));\n height: calc(var(--cross-size) / var(--_scale));\n}\n"],"mappings":""}
@@ -5,17 +5,17 @@ import i from "../_virtual/_@oxc-project_runtime@0.147.0/helpers/esm/decorate.js
5
5
  import { Viewport as a } from "./viewport2.js";
6
6
  import o from "./viewport-gridlines.js";
7
7
  import { createGridlineCoverage as s, gridlineCoverageNeedsUpdate as c, selectGridlineInterval as l } from "./viewport-gridlines.utils.js";
8
- import { LitElement as u, html as d, nothing as f } from "lit";
9
- import { property as p } from "lit/decorators/property.js";
10
- import { styleMap as m } from "lit/directives/style-map.js";
8
+ import { LitElement as u, html as d, nothing as f, svg as p } from "lit";
9
+ import { property as m } from "lit/decorators/property.js";
10
+ import { styleMap as h } from "lit/directives/style-map.js";
11
11
  //#region src/viewport/viewport-gridlines.ts
12
- var h = 10, g = 64, _ = class extends u {
12
+ var g = 10, _ = 64, v = class extends u {
13
13
  constructor(...e) {
14
- super(...e), this.slot = "background", this.accessibilityHidden = "true", this.#e = h, this.#t = 0, this.#n = 0, this.#r = g, this.#s = () => {
14
+ super(...e), this.slot = "background", this.accessibilityHidden = "true", this.#e = g, this.#t = 0, this.#n = 0, this.#r = _, this.pattern = "lines", this.#c = () => {
15
15
  let e = this.#i;
16
- e && (this.style.setProperty("--_scale", `${e.scale}`), this.#l());
17
- }, this.#c = () => {
18
- this.#l({ forceCoverage: !0 });
16
+ e && (this.style.setProperty("--_scale", `${e.scale}`), this.#u());
17
+ }, this.#l = () => {
18
+ this.#u({ forceCoverage: !0 });
19
19
  };
20
20
  }
21
21
  static {
@@ -24,7 +24,7 @@ var h = 10, g = 64, _ = class extends u {
24
24
  static {
25
25
  this.metadata = {
26
26
  tag: "nve-viewport-gridlines",
27
- version: "2.11.1"
27
+ version: "2.12.0"
28
28
  };
29
29
  }
30
30
  #e;
@@ -38,7 +38,7 @@ var h = 10, g = 64, _ = class extends u {
38
38
  return this.#e;
39
39
  }
40
40
  set step(e) {
41
- let t = r(e, h);
41
+ let t = r(e, g);
42
42
  if (t === this.#e) return;
43
43
  let n = this.#e;
44
44
  this.#e = t, this.requestUpdate("step", n);
@@ -65,7 +65,7 @@ var h = 10, g = 64, _ = class extends u {
65
65
  return this.#r;
66
66
  }
67
67
  set targetSpacing(e) {
68
- let t = r(e, g);
68
+ let t = r(e, _);
69
69
  if (t === this.#r) return;
70
70
  let n = this.#r;
71
71
  this.#r = t, this.requestUpdate("targetSpacing", n);
@@ -73,16 +73,16 @@ var h = 10, g = 64, _ = class extends u {
73
73
  connectedCallback() {
74
74
  super.connectedCallback();
75
75
  let e = this.parentElement;
76
- e instanceof a && (this.#i = e, this.style.setProperty("--_scale", `${e.scale}`), this.#i.addEventListener("viewportchange", this.#s), typeof ResizeObserver < "u" && (this.#a = new ResizeObserver(this.#c), this.#a.observe(e)), this.#u({
76
+ e instanceof a && (this.#i = e, this.style.setProperty("--_scale", `${e.scale}`), this.#i.addEventListener("viewportchange", this.#c), typeof ResizeObserver < "u" && (this.#a = new ResizeObserver(this.#l), this.#a.observe(e)), this.#d({
77
77
  forceCoverage: !0,
78
78
  resetInterval: !0
79
79
  }));
80
80
  }
81
81
  disconnectedCallback() {
82
- this.#i && this.#i.removeEventListener("viewportchange", this.#s), this.#a?.disconnect(), this.#a = void 0, this.#i = void 0, this.#o = void 0, super.disconnectedCallback();
82
+ this.#i && this.#i.removeEventListener("viewportchange", this.#c), this.#a?.disconnect(), this.#a = void 0, this.#i = void 0, this.#o = void 0, super.disconnectedCallback();
83
83
  }
84
84
  willUpdate(e) {
85
- super.willUpdate(e), (e.has("step") || e.has("targetSpacing")) && this.#u({
85
+ super.willUpdate(e), (e.has("step") || e.has("targetSpacing")) && this.#d({
86
86
  forceCoverage: !0,
87
87
  resetInterval: !0
88
88
  });
@@ -90,15 +90,22 @@ var h = 10, g = 64, _ = class extends u {
90
90
  render() {
91
91
  let e = this.#o;
92
92
  if (!e) return f;
93
- let { coverage: t, interval: n } = e;
94
- return d`<svg internal-host aria-hidden="true" focusable="false" preserveAspectRatio="none" style="${m(y(t))}" viewBox="${t.x} ${t.y} ${t.width} ${t.height}"><defs><pattern data-gridline-pattern id="gridlines" x="${this.#t}" y="${this.#n}" width="${n}" height="${n}" patternUnits="userSpaceOnUse"><path d="M ${n} 0 H 0 V ${n}"></path></pattern></defs><rect x="${t.x}" y="${t.y}" width="${t.width}" height="${t.height}" fill="url(#gridlines)"></rect></svg>`;
93
+ let { coverage: t, interval: n } = e, r = this.pattern === "dots" || this.pattern === "crosses";
94
+ return d`<svg internal-host aria-hidden="true" focusable="false" preserveAspectRatio="none" style="${h(b(t))}" viewBox="${t.x} ${t.y} ${t.width} ${t.height}"><defs><pattern data-gridline-pattern id="gridlines" x="${this.#t - (r ? n / 2 : 0)}" y="${this.#n - (r ? n / 2 : 0)}" width="${n}" height="${n}" patternUnits="userSpaceOnUse">${this.#s(n)}</pattern></defs><rect x="${t.x}" y="${t.y}" width="${t.width}" height="${t.height}" fill="url(#gridlines)"></rect></svg>`;
95
95
  }
96
- #s;
97
- #c;
98
- #l(e = {}) {
99
- this.#u(e) && this.requestUpdate();
96
+ #s(e) {
97
+ switch (this.pattern) {
98
+ case "dots": return p`<circle cx="${e / 2}" cy="${e / 2}" r="2"></circle>`;
99
+ case "crosses": return p`<g transform="translate(${e / 2} ${e / 2})"><clipPath id="cross-clip"><rect class="cross-horizontal"></rect><rect class="cross-vertical"></rect></clipPath><rect class="cross" x="${-e / 2}" y="${-e / 2}" width="${e}" height="${e}" clip-path="url(#cross-clip)"></rect></g>`;
100
+ default: return p`<path d="M ${e} 0 H 0 V ${e}"></path>`;
101
+ }
100
102
  }
103
+ #c;
104
+ #l;
101
105
  #u(e = {}) {
106
+ this.#d(e) && this.requestUpdate();
107
+ }
108
+ #d(e = {}) {
102
109
  let t = this.#i;
103
110
  if (!t) return !1;
104
111
  let n = t.getVisibleRect();
@@ -108,7 +115,7 @@ var h = 10, g = 64, _ = class extends u {
108
115
  scale: t.scale,
109
116
  step: this.#e,
110
117
  targetSpacing: this.#r
111
- }), i = v({
118
+ }), i = y({
112
119
  forceCoverage: e.forceCoverage === !0,
113
120
  interval: r,
114
121
  previous: this.#o,
@@ -117,30 +124,33 @@ var h = 10, g = 64, _ = class extends u {
117
124
  return i ? (this.#o = i, !0) : !1;
118
125
  }
119
126
  };
120
- i([e()], _.prototype, "slot", void 0), i([e({ attribute: "aria-hidden" })], _.prototype, "accessibilityHidden", void 0), i([p({
127
+ i([e()], v.prototype, "slot", void 0), i([e({ attribute: "aria-hidden" })], v.prototype, "accessibilityHidden", void 0), i([m({
128
+ type: String,
129
+ reflect: !0
130
+ })], v.prototype, "pattern", void 0), i([m({
121
131
  type: Number,
122
132
  reflect: !0
123
- })], _.prototype, "step", null), i([p({
133
+ })], v.prototype, "step", null), i([m({
124
134
  type: Number,
125
135
  attribute: "origin-x",
126
136
  reflect: !0
127
- })], _.prototype, "originX", null), i([p({
137
+ })], v.prototype, "originX", null), i([m({
128
138
  type: Number,
129
139
  attribute: "origin-y",
130
140
  reflect: !0
131
- })], _.prototype, "originY", null), i([p({
141
+ })], v.prototype, "originY", null), i([m({
132
142
  type: Number,
133
143
  attribute: "target-spacing",
134
144
  reflect: !0
135
- })], _.prototype, "targetSpacing", null);
136
- function v({ forceCoverage: e, interval: t, previous: n, visible: r }) {
145
+ })], v.prototype, "targetSpacing", null);
146
+ function y({ forceCoverage: e, interval: t, previous: n, visible: r }) {
137
147
  let i = e || c(n?.coverage, r), a = t !== n?.interval;
138
148
  if (!(!i && !a)) return {
139
149
  coverage: i || !n ? s(r) : n.coverage,
140
150
  interval: t
141
151
  };
142
152
  }
143
- function y(e) {
153
+ function b(e) {
144
154
  return {
145
155
  height: `${e.height}px`,
146
156
  left: `${e.x}px`,
@@ -149,6 +159,6 @@ function y(e) {
149
159
  };
150
160
  }
151
161
  //#endregion
152
- export { _ as ViewportGridlines };
162
+ export { v as ViewportGridlines };
153
163
 
154
164
  //# sourceMappingURL=viewport-gridlines2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewport-gridlines2.js","names":[],"sources":["../../src/viewport/viewport-gridlines.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, type PropertyValues } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { finiteOr, hostAttr, positiveFiniteOr, useStyles } from '@nvidia-elements/core/internal';\nimport styles from './viewport-gridlines.css?inline';\nimport {\n createGridlineCoverage,\n gridlineCoverageNeedsUpdate,\n selectGridlineInterval\n} from './viewport-gridlines.utils.js';\nimport { Viewport } from './viewport.js';\nimport type { ViewportRect } from './viewport.types.js';\n\nconst DEFAULT_STEP = 10;\nconst DEFAULT_TARGET_SPACING = 64;\n\ninterface GridlineProjection {\n readonly coverage: ViewportRect;\n readonly interval: number;\n}\n\ninterface ProjectionSyncOptions {\n readonly forceCoverage?: boolean;\n readonly resetInterval?: boolean;\n}\n\n/**\n * @element nve-viewport-gridlines\n * @description Renders origin-stable, zoom-adaptive gridlines behind viewport content.\n * @documentation https://nvidia.github.io/elements/docs/elements/viewport/\n * @since 0.0.0\n * @entrypoint \\@nvidia-elements/core/viewport\n * @cssprop --color - Sets the gridline stroke color.\n * @cssprop --line-width - Sets the approximate stroke width in CSS pixels.\n */\nexport class ViewportGridlines extends LitElement {\n static styles = useStyles([styles]);\n\n static readonly metadata = {\n tag: 'nve-viewport-gridlines',\n version: '0.0.0'\n };\n\n /** @private */\n @hostAttr() slot = 'background';\n\n /** @private */\n @hostAttr({ attribute: 'aria-hidden' }) protected accessibilityHidden = 'true';\n\n #step = DEFAULT_STEP;\n #originX = 0;\n #originY = 0;\n #targetSpacing = DEFAULT_TARGET_SPACING;\n #viewport?: Viewport;\n #resizeObserver?: ResizeObserver;\n #projection?: GridlineProjection;\n\n /** Smallest gridline interval in content-space units. */\n @property({ type: Number, reflect: true })\n get step(): number {\n return this.#step;\n }\n\n set step(value: number) {\n const next = positiveFiniteOr(value, DEFAULT_STEP);\n if (next === this.#step) return;\n const previous = this.#step;\n this.#step = next;\n this.requestUpdate('step', previous);\n }\n\n /** Content-space x coordinate of the grid origin. */\n @property({ type: Number, attribute: 'origin-x', reflect: true })\n get originX(): number {\n return this.#originX;\n }\n\n set originX(value: number) {\n const next = finiteOr(value, 0);\n if (next === this.#originX) return;\n const previous = this.#originX;\n this.#originX = next;\n this.requestUpdate('originX', previous);\n }\n\n /** Content-space y coordinate of the grid origin. */\n @property({ type: Number, attribute: 'origin-y', reflect: true })\n get originY(): number {\n return this.#originY;\n }\n\n set originY(value: number) {\n const next = finiteOr(value, 0);\n if (next === this.#originY) return;\n const previous = this.#originY;\n this.#originY = next;\n this.requestUpdate('originY', previous);\n }\n\n /** Target on-screen separation used to choose the adaptive gridline interval, in CSS pixels. */\n @property({ type: Number, attribute: 'target-spacing', reflect: true })\n get targetSpacing(): number {\n return this.#targetSpacing;\n }\n\n set targetSpacing(value: number) {\n const next = positiveFiniteOr(value, DEFAULT_TARGET_SPACING);\n if (next === this.#targetSpacing) return;\n const previous = this.#targetSpacing;\n this.#targetSpacing = next;\n this.requestUpdate('targetSpacing', previous);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n const viewport = this.parentElement;\n if (!(viewport instanceof Viewport)) return;\n this.#viewport = viewport;\n this.style.setProperty('--_scale', `${viewport.scale}`);\n this.#viewport.addEventListener('viewportchange', this.#handleViewportChange);\n if (typeof ResizeObserver !== 'undefined') {\n this.#resizeObserver = new ResizeObserver(this.#handleViewportResize);\n this.#resizeObserver.observe(viewport);\n }\n this.#updateProjection({ forceCoverage: true, resetInterval: true });\n }\n\n disconnectedCallback(): void {\n if (this.#viewport) {\n this.#viewport.removeEventListener('viewportchange', this.#handleViewportChange);\n }\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#viewport = undefined;\n this.#projection = undefined;\n super.disconnectedCallback();\n }\n\n protected willUpdate(changed: PropertyValues<this>): void {\n super.willUpdate(changed);\n if (changed.has('step') || changed.has('targetSpacing')) {\n this.#updateProjection({ forceCoverage: true, resetInterval: true });\n }\n }\n\n render() {\n const projection = this.#projection;\n if (!projection) return nothing;\n const { coverage, interval } = projection;\n return html`\n <svg\n internal-host\n aria-hidden=\"true\"\n focusable=\"false\"\n preserveAspectRatio=\"none\"\n style=${styleMap(coverageStyles(coverage))}\n viewBox=\"${coverage.x} ${coverage.y} ${coverage.width} ${coverage.height}\"\n >\n <defs>\n <pattern\n data-gridline-pattern\n id=\"gridlines\"\n x=${this.#originX}\n y=${this.#originY}\n width=${interval}\n height=${interval}\n patternUnits=\"userSpaceOnUse\"\n >\n <path d=\"M ${interval} 0 H 0 V ${interval}\"></path>\n </pattern>\n </defs>\n <rect\n x=${coverage.x}\n y=${coverage.y}\n width=${coverage.width}\n height=${coverage.height}\n fill=\"url(#gridlines)\"\n ></rect>\n </svg>\n `;\n }\n\n #handleViewportChange = (): void => {\n const viewport = this.#viewport;\n if (!viewport) return;\n this.style.setProperty('--_scale', `${viewport.scale}`);\n this.#requestProjectionUpdate();\n };\n\n #handleViewportResize = (): void => {\n this.#requestProjectionUpdate({ forceCoverage: true });\n };\n\n #requestProjectionUpdate(options: ProjectionSyncOptions = {}): void {\n if (this.#updateProjection(options)) this.requestUpdate();\n }\n\n #updateProjection(options: ProjectionSyncOptions = {}): boolean {\n const viewport = this.#viewport;\n if (!viewport) return false;\n const visible = viewport.getVisibleRect();\n if (visible.width <= 0 || visible.height <= 0) return false;\n const interval = selectGridlineInterval({\n current: options.resetInterval ? undefined : this.#projection?.interval,\n scale: viewport.scale,\n step: this.#step,\n targetSpacing: this.#targetSpacing\n });\n const projection = nextProjection({\n forceCoverage: options.forceCoverage === true,\n interval,\n previous: this.#projection,\n visible\n });\n if (!projection) return false;\n this.#projection = projection;\n return true;\n }\n}\n\nfunction nextProjection({\n forceCoverage,\n interval,\n previous,\n visible\n}: {\n forceCoverage: boolean;\n interval: number;\n previous?: GridlineProjection;\n visible: ViewportRect;\n}): GridlineProjection | undefined {\n const coverageChanged = forceCoverage || gridlineCoverageNeedsUpdate(previous?.coverage, visible);\n const intervalChanged = interval !== previous?.interval;\n if (!coverageChanged && !intervalChanged) return undefined;\n const coverage = coverageChanged || !previous ? createGridlineCoverage(visible) : previous.coverage;\n return { coverage, interval };\n}\n\nfunction coverageStyles(coverage: ViewportRect): Record<string, string> {\n return {\n height: `${coverage.height}px`,\n left: `${coverage.x}px`,\n top: `${coverage.y}px`,\n width: `${coverage.width}px`\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"viewport-gridlines2.js","names":[],"sources":["../../src/viewport/viewport-gridlines.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, type PropertyValues } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { finiteOr, hostAttr, positiveFiniteOr, useStyles } from '@nvidia-elements/core/internal';\nimport styles from './viewport-gridlines.css?inline';\nimport {\n createGridlineCoverage,\n gridlineCoverageNeedsUpdate,\n selectGridlineInterval\n} from './viewport-gridlines.utils.js';\nimport { Viewport } from './viewport.js';\nimport type { ViewportRect } from './viewport.types.js';\n\nconst DEFAULT_STEP = 10;\nconst DEFAULT_TARGET_SPACING = 64;\n\ninterface GridlineProjection {\n readonly coverage: ViewportRect;\n readonly interval: number;\n}\n\ninterface ProjectionSyncOptions {\n readonly forceCoverage?: boolean;\n readonly resetInterval?: boolean;\n}\n\n/**\n * @element nve-viewport-gridlines\n * @description Renders origin-stable, zoom-adaptive gridline patterns behind viewport content.\n * @documentation https://nvidia.github.io/elements/docs/elements/viewport/\n * @since 0.0.0\n * @entrypoint \\@nvidia-elements/core/viewport\n * @cssprop --color - Sets the gridline pattern color.\n * @cssprop --line-width - Sets the approximate stroke width in CSS pixels.\n * @cssprop --dot-radius - Sets the approximate dot radius in CSS pixels.\n * @cssprop --cross-size - Sets the approximate full width and height of each cross in CSS pixels.\n */\nexport class ViewportGridlines extends LitElement {\n static styles = useStyles([styles]);\n\n static readonly metadata = {\n tag: 'nve-viewport-gridlines',\n version: '0.0.0'\n };\n\n /** @private */\n @hostAttr() slot = 'background';\n\n /** @private */\n @hostAttr({ attribute: 'aria-hidden' }) protected accessibilityHidden = 'true';\n\n #step = DEFAULT_STEP;\n #originX = 0;\n #originY = 0;\n #targetSpacing = DEFAULT_TARGET_SPACING;\n #viewport?: Viewport;\n #resizeObserver?: ResizeObserver;\n #projection?: GridlineProjection;\n\n /** Grid pattern to render. */\n @property({ type: String, reflect: true }) pattern: 'lines' | 'dots' | 'crosses' = 'lines';\n\n /** Smallest gridline interval in content-space units. */\n @property({ type: Number, reflect: true })\n get step(): number {\n return this.#step;\n }\n\n set step(value: number) {\n const next = positiveFiniteOr(value, DEFAULT_STEP);\n if (next === this.#step) return;\n const previous = this.#step;\n this.#step = next;\n this.requestUpdate('step', previous);\n }\n\n /** Content-space x coordinate of the grid origin. */\n @property({ type: Number, attribute: 'origin-x', reflect: true })\n get originX(): number {\n return this.#originX;\n }\n\n set originX(value: number) {\n const next = finiteOr(value, 0);\n if (next === this.#originX) return;\n const previous = this.#originX;\n this.#originX = next;\n this.requestUpdate('originX', previous);\n }\n\n /** Content-space y coordinate of the grid origin. */\n @property({ type: Number, attribute: 'origin-y', reflect: true })\n get originY(): number {\n return this.#originY;\n }\n\n set originY(value: number) {\n const next = finiteOr(value, 0);\n if (next === this.#originY) return;\n const previous = this.#originY;\n this.#originY = next;\n this.requestUpdate('originY', previous);\n }\n\n /** Target on-screen separation used to choose the adaptive gridline interval, in CSS pixels. */\n @property({ type: Number, attribute: 'target-spacing', reflect: true })\n get targetSpacing(): number {\n return this.#targetSpacing;\n }\n\n set targetSpacing(value: number) {\n const next = positiveFiniteOr(value, DEFAULT_TARGET_SPACING);\n if (next === this.#targetSpacing) return;\n const previous = this.#targetSpacing;\n this.#targetSpacing = next;\n this.requestUpdate('targetSpacing', previous);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n const viewport = this.parentElement;\n if (!(viewport instanceof Viewport)) return;\n this.#viewport = viewport;\n this.style.setProperty('--_scale', `${viewport.scale}`);\n this.#viewport.addEventListener('viewportchange', this.#handleViewportChange);\n if (typeof ResizeObserver !== 'undefined') {\n this.#resizeObserver = new ResizeObserver(this.#handleViewportResize);\n this.#resizeObserver.observe(viewport);\n }\n this.#updateProjection({ forceCoverage: true, resetInterval: true });\n }\n\n disconnectedCallback(): void {\n if (this.#viewport) {\n this.#viewport.removeEventListener('viewportchange', this.#handleViewportChange);\n }\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#viewport = undefined;\n this.#projection = undefined;\n super.disconnectedCallback();\n }\n\n protected willUpdate(changed: PropertyValues<this>): void {\n super.willUpdate(changed);\n if (changed.has('step') || changed.has('targetSpacing')) {\n this.#updateProjection({ forceCoverage: true, resetInterval: true });\n }\n }\n\n render() {\n const projection = this.#projection;\n if (!projection) return nothing;\n const { coverage, interval } = projection;\n const centered = this.pattern === 'dots' || this.pattern === 'crosses';\n return html`\n <svg\n internal-host\n aria-hidden=\"true\"\n focusable=\"false\"\n preserveAspectRatio=\"none\"\n style=${styleMap(coverageStyles(coverage))}\n viewBox=\"${coverage.x} ${coverage.y} ${coverage.width} ${coverage.height}\"\n >\n <defs>\n <pattern\n data-gridline-pattern\n id=\"gridlines\"\n x=${this.#originX - (centered ? interval / 2 : 0)}\n y=${this.#originY - (centered ? interval / 2 : 0)}\n width=${interval}\n height=${interval}\n patternUnits=\"userSpaceOnUse\"\n >\n ${this.#renderPattern(interval)}\n </pattern>\n </defs>\n <rect\n x=${coverage.x}\n y=${coverage.y}\n width=${coverage.width}\n height=${coverage.height}\n fill=\"url(#gridlines)\"\n ></rect>\n </svg>\n `;\n }\n\n #renderPattern(interval: number) {\n switch (this.pattern) {\n case 'dots':\n return svg`<circle cx=${interval / 2} cy=${interval / 2} r=\"2\"></circle>`;\n case 'crosses':\n return svg`\n <g transform=\"translate(${interval / 2} ${interval / 2})\">\n <clipPath id=\"cross-clip\">\n <rect class=\"cross-horizontal\"></rect>\n <rect class=\"cross-vertical\"></rect>\n </clipPath>\n <rect\n class=\"cross\"\n x=${-interval / 2}\n y=${-interval / 2}\n width=${interval}\n height=${interval}\n clip-path=\"url(#cross-clip)\"\n ></rect>\n </g>\n `;\n case 'lines':\n default:\n return svg`<path d=\"M ${interval} 0 H 0 V ${interval}\"></path>`;\n }\n }\n\n #handleViewportChange = (): void => {\n const viewport = this.#viewport;\n if (!viewport) return;\n this.style.setProperty('--_scale', `${viewport.scale}`);\n this.#requestProjectionUpdate();\n };\n\n #handleViewportResize = (): void => {\n this.#requestProjectionUpdate({ forceCoverage: true });\n };\n\n #requestProjectionUpdate(options: ProjectionSyncOptions = {}): void {\n if (this.#updateProjection(options)) this.requestUpdate();\n }\n\n #updateProjection(options: ProjectionSyncOptions = {}): boolean {\n const viewport = this.#viewport;\n if (!viewport) return false;\n const visible = viewport.getVisibleRect();\n if (visible.width <= 0 || visible.height <= 0) return false;\n const interval = selectGridlineInterval({\n current: options.resetInterval ? undefined : this.#projection?.interval,\n scale: viewport.scale,\n step: this.#step,\n targetSpacing: this.#targetSpacing\n });\n const projection = nextProjection({\n forceCoverage: options.forceCoverage === true,\n interval,\n previous: this.#projection,\n visible\n });\n if (!projection) return false;\n this.#projection = projection;\n return true;\n }\n}\n\nfunction nextProjection({\n forceCoverage,\n interval,\n previous,\n visible\n}: {\n forceCoverage: boolean;\n interval: number;\n previous?: GridlineProjection;\n visible: ViewportRect;\n}): GridlineProjection | undefined {\n const coverageChanged = forceCoverage || gridlineCoverageNeedsUpdate(previous?.coverage, visible);\n const intervalChanged = interval !== previous?.interval;\n if (!coverageChanged && !intervalChanged) return undefined;\n const coverage = coverageChanged || !previous ? createGridlineCoverage(visible) : previous.coverage;\n return { coverage, interval };\n}\n\nfunction coverageStyles(coverage: ViewportRect): Record<string, string> {\n return {\n height: `${coverage.height}px`,\n left: `${coverage.x}px`,\n top: `${coverage.y}px`,\n width: `${coverage.width}px`\n };\n}\n"],"mappings":"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"}
@@ -18,7 +18,7 @@ var _ = 3, v = class extends f {
18
18
  static {
19
19
  this.metadata = {
20
20
  tag: "nve-viewport-minimap",
21
- version: "2.11.1"
21
+ version: "2.12.0"
22
22
  };
23
23
  }
24
24
  #e;
@@ -1 +1 @@
1
- {"version":3,"file":"viewport.examples.js","names":[],"sources":["../../src/viewport/viewport.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/alert/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/button-group/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/input/define.js';\nimport '@nvidia-elements/core/toolbar/define.js';\nimport '@nvidia-elements/core/viewport/define.js';\n\nexport default {\n title: 'Elements/Viewport',\n component: 'nve-viewport'\n};\n\n/**\n * @summary Auto-fit a bounded SVG with direct pan and zoom; the minimap represents its single content root as one rectangle.\n */\nexport const Default = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n\n <nve-viewport-minimap></nve-viewport-minimap>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Provide custom minimap content to replace the automatic bounding boxes with a simplified representation of the viewport content.\n */\nexport const Minimap = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n\n <nve-viewport-minimap>\n <svg slot=\"preview\" width=\"900\" height=\"600\" viewBox=\"0 0 900 600\" style=\"position: absolute; left: 0; top: 0\">\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n </svg>\n </nve-viewport-minimap>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Place custom content in the background slot to provide a spatial reference without affecting content fitting.\n */\nexport const Background = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <svg\n slot=\"background\"\n aria-hidden=\"true\"\n width=\"20480\"\n height=\"20480\"\n viewBox=\"-10240 -10240 20480 20480\"\n style=\"position: absolute; left: -10240px; top: -10240px\"\n >\n <defs>\n <pattern id=\"viewport-background-dots\" width=\"100\" height=\"100\" patternUnits=\"userSpaceOnUse\">\n <circle cx=\"2\" cy=\"2\" r=\"2\" fill=\"var(--nve-ref-border-color-emphasis)\"></circle>\n </pattern>\n </defs>\n <rect x=\"-10240\" y=\"-10240\" width=\"20480\" height=\"20480\" fill=\"url(#viewport-background-dots)\"></rect>\n </svg>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Place native and Elements controls inside a viewport without losing their standard interactions.\n */\nexport const InteractiveContent = {\n render: () => html`\n <nve-viewport x=\"-20\" y=\"-20\" scale=\"0.9\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines step=\"20\" target-spacing=\"72\"></nve-viewport-gridlines>\n\n <nve-card style=\"position: absolute; left: 280px; top: 110px; width: 300px\">\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Viewport content</h2>\n </nve-card-header>\n <nve-card-content>\n <nve-input>\n <label>Label</label>\n <input value=\"Editable value\" />\n </nve-input>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Configure panning to require Space when application content needs to handle its own drag interactions.\n */\nexport const PanWithSpace = {\n render: () => html`\n <style>\n #viewport-space-pan-card {\n cursor: var(--drag-cursor, auto);\n }\n\n #viewport-space-pan-card:hover {\n --drag-cursor: grab;\n }\n\n #viewport-space-pan-card[data-dragging] {\n --background: var(--nve-sys-layer-overlay-background);\n --box-shadow: var(--nve-ref-shadow-300);\n --drag-cursor: grabbing;\n }\n </style>\n\n <div nve-layout=\"column align:horizontal-stretch\" style=\"height: 420px\">\n <nve-alert-group status=\"accent\">\n <nve-alert>\n <p nve-text=\"body sm medium\">\n Pan the viewport with <kbd nve-text=\"code\">Space</kbd>, or using the middle mouse button.\n </p>\n </nve-alert>\n </nve-alert-group>\n\n <nve-viewport\n id=\"viewport-space-pan-demo\"\n behavior-pan=\"space\"\n behavior-zoom\n style=\"flex: 1; --min-height: 0\"\n >\n <nve-viewport-gridlines step=\"20\"></nve-viewport-gridlines>\n\n <nve-card\n id=\"viewport-space-pan-card\"\n data-draggable-card\n data-card-drag-handle\n style=\"position: absolute; left: 290px; top: 120px; width: 300px\"\n >\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Drag this card</h2>\n </nve-card-header>\n <nve-card-content>\n <p nve-text=\"body relaxed\" nve-layout=\"pad:md\" style=\"text-align: center\">Application-defined dragging remains independent in this mode.</p>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n </div>\n\n <script type=\"module\">\n const viewport = document.querySelector('#viewport-space-pan-demo');\n const handles = viewport.querySelectorAll('[data-card-drag-handle]');\n\n handles.forEach(handle => {\n const card = handle.closest('[data-draggable-card]');\n let pointerId;\n let startClientX;\n let startClientY;\n let startLeft;\n let startTop;\n\n const finishDrag = event => {\n if (event.pointerId !== pointerId) return;\n pointerId = undefined;\n card.removeAttribute('data-dragging');\n };\n\n handle.addEventListener('pointerdown', event => {\n if (\n (event.pointerType !== 'mouse' && event.pointerType !== 'pen') ||\n event.button !== 0 ||\n event.defaultPrevented\n ) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n pointerId = event.pointerId;\n startClientX = event.clientX;\n startClientY = event.clientY;\n startLeft = Number.parseFloat(card.style.left);\n startTop = Number.parseFloat(card.style.top);\n card.setAttribute('data-dragging', '');\n handle.setPointerCapture(pointerId);\n });\n\n handle.addEventListener('pointermove', event => {\n if (event.pointerId !== pointerId) return;\n\n card.style.left = startLeft + (event.clientX - startClientX) / viewport.scale + 'px';\n card.style.top = startTop + (event.clientY - startClientY) / viewport.scale + 'px';\n event.preventDefault();\n });\n\n handle.addEventListener('pointerup', finishDrag);\n handle.addEventListener('pointercancel', finishDrag);\n handle.addEventListener('lostpointercapture', finishDrag);\n });\n </script>\n `\n};\n\n/**\n * @summary Use external controls with `commandfor` to invoke viewport pan, zoom, reset, and fit commands.\n */\nexport const Commands = {\n render: () => html`\n <div nve-layout=\"column align:horizontal-stretch\" style=\"height: 420px\">\n <nve-toolbar aria-label=\"Viewport navigation controls\">\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-left\" aria-label=\"Pan left\">←</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-up\" aria-label=\"Pan up\">↑</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-down\" aria-label=\"Pan down\">↓</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-right\" aria-label=\"Pan right\">→</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-out\" aria-label=\"Zoom out\">−</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-reset\">100%</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-in\" aria-label=\"Zoom in\">+</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-to-fit\">Fit</nve-button>\n </nve-toolbar>\n\n <nve-viewport\n id=\"viewport-command-demo\"\n autofit\n fit-inset=\"24\"\n behavior-pan\n behavior-zoom\n style=\"flex: 1; --min-height: 0\"\n >\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n </div>\n `\n};\n\n/**\n * @summary Viewport navigation helpers let application logic animate specific content regions into view.\n */\nexport const ProgrammaticNavigation = {\n render: () => html`\n <div nve-layout=\"column gap:sm align:horizontal-stretch\" style=\"height: 420px\">\n <div nve-layout=\"row align:center\">\n <nve-button-group container=\"rounded\" behavior-select=\"single\" aria-label=\"Navigate to workflow region\">\n <nve-button data-viewport-region=\"viewport-region-ingest\">Ingest</nve-button>\n <nve-button data-viewport-region=\"viewport-region-train\">Train</nve-button>\n <nve-button data-viewport-region=\"viewport-region-deploy\">Deploy</nve-button>\n </nve-button-group>\n </div>\n\n <nve-viewport id=\"viewport-reveal-demo\" autofit fit-inset=\"24\" style=\"flex: 1; --min-height: 0\">\n <nve-viewport-gridlines step=\"40\"></nve-viewport-gridlines>\n\n <svg\n aria-hidden=\"true\"\n width=\"500\"\n height=\"320\"\n viewBox=\"0 0 500 320\"\n style=\"position: absolute; left: 380px; top: 144px\"\n >\n <path\n d=\"M 0 0 C 50 0 50 160 100 160 M 400 160 C 450 160 450 320 500 320\"\n fill=\"none\"\n stroke=\"var(--nve-ref-border-color-emphasis)\"\n stroke-width=\"4\"\n ></path>\n </svg>\n\n <nve-card id=\"viewport-region-ingest\" style=\"position: absolute; left: 80px; top: 80px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Ingest</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Validate and prepare the dataset.</p>\n </nve-card-content>\n </nve-card>\n <nve-card id=\"viewport-region-train\" style=\"position: absolute; left: 480px; top: 240px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Train</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Run and compare model experiments.</p>\n </nve-card-content>\n </nve-card>\n <nve-card id=\"viewport-region-deploy\" style=\"position: absolute; left: 880px; top: 400px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Deploy</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Promote the selected model.</p>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n </div>\n\n <script type=\"module\">\n const viewport = document.querySelector('#viewport-reveal-demo');\n const buttons = Array.from(document.querySelectorAll('[data-viewport-region]'));\n const framing = 80;\n\n buttons.forEach(button => {\n button.addEventListener('click', () => {\n const region = viewport.querySelector('#' + button.dataset.viewportRegion);\n viewport.reveal(\n {\n x: region.offsetLeft - framing,\n y: region.offsetTop - framing,\n width: region.offsetWidth + framing * 2,\n height: region.offsetHeight + framing * 2\n },\n { animated: true, duration: 500 }\n );\n });\n });\n </script>\n `\n};\n"],"mappings":";AAGA,IAAA,IAAS"}
1
+ {"version":3,"file":"viewport.examples.js","names":[],"sources":["../../src/viewport/viewport.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/alert/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/button-group/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/input/define.js';\nimport '@nvidia-elements/core/toolbar/define.js';\nimport '@nvidia-elements/core/viewport/define.js';\n\nexport default {\n title: 'Elements/Viewport',\n component: 'nve-viewport'\n};\n\n/**\n * @summary Auto-fit a bounded SVG with direct pan and zoom; the minimap represents its single content root as one rectangle.\n */\nexport const Default = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n\n <nve-viewport-minimap></nve-viewport-minimap>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Provide custom minimap content to replace the default bounding boxes with a simplified representation of the viewport content.\n */\nexport const Minimap = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n\n <nve-viewport-minimap>\n <svg slot=\"preview\" width=\"900\" height=\"600\" viewBox=\"0 0 900 600\" style=\"position: absolute; left: 0; top: 0\">\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n </svg>\n </nve-viewport-minimap>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Place native and Elements controls inside a viewport without losing their standard interactions.\n */\nexport const InteractiveContent = {\n render: () => html`\n <nve-viewport x=\"-20\" y=\"-20\" scale=\"0.9\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines step=\"20\" target-spacing=\"72\"></nve-viewport-gridlines>\n\n <nve-card style=\"position: absolute; left: 280px; top: 110px; width: 300px\">\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Viewport content</h2>\n </nve-card-header>\n <nve-card-content>\n <nve-input>\n <label>Label</label>\n <input value=\"Editable value\" />\n </nve-input>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Configure panning to require Space when application content needs to handle its own drag interactions.\n */\nexport const PanWithSpace = {\n render: () => html`\n <style>\n #viewport-space-pan-card {\n cursor: var(--drag-cursor, auto);\n }\n\n #viewport-space-pan-card:hover {\n --drag-cursor: grab;\n }\n\n #viewport-space-pan-card[data-dragging] {\n --background: var(--nve-sys-layer-overlay-background);\n --box-shadow: var(--nve-ref-shadow-300);\n --drag-cursor: grabbing;\n }\n </style>\n\n <div nve-layout=\"column align:horizontal-stretch\" style=\"height: 420px\">\n <nve-alert-group status=\"accent\">\n <nve-alert>\n <p nve-text=\"body sm medium\">\n Pan the viewport with <kbd nve-text=\"code\">Space</kbd>, or using the middle mouse button.\n </p>\n </nve-alert>\n </nve-alert-group>\n\n <nve-viewport\n id=\"viewport-space-pan-demo\"\n behavior-pan=\"space\"\n behavior-zoom\n style=\"flex: 1; --min-height: 0\"\n >\n <nve-viewport-gridlines step=\"20\"></nve-viewport-gridlines>\n\n <nve-card\n id=\"viewport-space-pan-card\"\n data-draggable-card\n data-card-drag-handle\n style=\"position: absolute; left: 290px; top: 120px; width: 300px\"\n >\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Drag this card</h2>\n </nve-card-header>\n <nve-card-content>\n <p nve-text=\"body relaxed\" nve-layout=\"pad:md\" style=\"text-align: center\">Application-defined dragging remains independent in this mode.</p>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n </div>\n\n <script type=\"module\">\n const viewport = document.querySelector('#viewport-space-pan-demo');\n const handles = viewport.querySelectorAll('[data-card-drag-handle]');\n\n handles.forEach(handle => {\n const card = handle.closest('[data-draggable-card]');\n let pointerId;\n let startClientX;\n let startClientY;\n let startLeft;\n let startTop;\n\n const finishDrag = event => {\n if (event.pointerId !== pointerId) return;\n pointerId = undefined;\n card.removeAttribute('data-dragging');\n };\n\n handle.addEventListener('pointerdown', event => {\n if (\n (event.pointerType !== 'mouse' && event.pointerType !== 'pen') ||\n event.button !== 0 ||\n event.defaultPrevented\n ) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n pointerId = event.pointerId;\n startClientX = event.clientX;\n startClientY = event.clientY;\n startLeft = Number.parseFloat(card.style.left);\n startTop = Number.parseFloat(card.style.top);\n card.setAttribute('data-dragging', '');\n handle.setPointerCapture(pointerId);\n });\n\n handle.addEventListener('pointermove', event => {\n if (event.pointerId !== pointerId) return;\n\n card.style.left = startLeft + (event.clientX - startClientX) / viewport.scale + 'px';\n card.style.top = startTop + (event.clientY - startClientY) / viewport.scale + 'px';\n event.preventDefault();\n });\n\n handle.addEventListener('pointerup', finishDrag);\n handle.addEventListener('pointercancel', finishDrag);\n handle.addEventListener('lostpointercapture', finishDrag);\n });\n </script>\n `\n};\n\n/**\n * @summary Use external controls with `commandfor` to invoke viewport pan, zoom, reset, and fit commands.\n */\nexport const Commands = {\n render: () => html`\n <div nve-layout=\"column align:horizontal-stretch\" style=\"height: 420px\">\n <nve-toolbar aria-label=\"Viewport navigation controls\">\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-left\" aria-label=\"Pan left\">←</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-up\" aria-label=\"Pan up\">↑</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-down\" aria-label=\"Pan down\">↓</nve-button>\n <nve-button commandfor=\"viewport-command-demo\" command=\"--pan-right\" aria-label=\"Pan right\">→</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-out\" aria-label=\"Zoom out\">−</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-reset\">100%</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-in\" aria-label=\"Zoom in\">+</nve-button>\n <nve-button slot=\"suffix\" commandfor=\"viewport-command-demo\" command=\"--zoom-to-fit\">Fit</nve-button>\n </nve-toolbar>\n\n <nve-viewport\n id=\"viewport-command-demo\"\n autofit\n fit-inset=\"24\"\n behavior-pan\n behavior-zoom\n style=\"flex: 1; --min-height: 0\"\n >\n <nve-viewport-gridlines></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n </div>\n `\n};\n\n/**\n * @summary Viewport navigation helpers let application logic animate specific content regions into view.\n */\nexport const ProgrammaticNavigation = {\n render: () => html`\n <div nve-layout=\"column gap:sm align:horizontal-stretch\" style=\"height: 420px\">\n <div nve-layout=\"row align:center\">\n <nve-button-group container=\"rounded\" behavior-select=\"single\" aria-label=\"Navigate to workflow region\">\n <nve-button data-viewport-region=\"viewport-region-ingest\">Ingest</nve-button>\n <nve-button data-viewport-region=\"viewport-region-train\">Train</nve-button>\n <nve-button data-viewport-region=\"viewport-region-deploy\">Deploy</nve-button>\n </nve-button-group>\n </div>\n\n <nve-viewport id=\"viewport-reveal-demo\" autofit fit-inset=\"24\" style=\"flex: 1; --min-height: 0\">\n <nve-viewport-gridlines step=\"40\"></nve-viewport-gridlines>\n\n <svg\n aria-hidden=\"true\"\n width=\"500\"\n height=\"320\"\n viewBox=\"0 0 500 320\"\n style=\"position: absolute; left: 380px; top: 144px\"\n >\n <path\n d=\"M 0 0 C 50 0 50 160 100 160 M 400 160 C 450 160 450 320 500 320\"\n fill=\"none\"\n stroke=\"var(--nve-ref-border-color-emphasis)\"\n stroke-width=\"4\"\n ></path>\n </svg>\n\n <nve-card id=\"viewport-region-ingest\" style=\"position: absolute; left: 80px; top: 80px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Ingest</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Validate and prepare the dataset.</p>\n </nve-card-content>\n </nve-card>\n <nve-card id=\"viewport-region-train\" style=\"position: absolute; left: 480px; top: 240px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Train</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Run and compare model experiments.</p>\n </nve-card-content>\n </nve-card>\n <nve-card id=\"viewport-region-deploy\" style=\"position: absolute; left: 880px; top: 400px; width: 320px\">\n <nve-card-header><h2 nve-text=\"heading sm bold\">Deploy</h2></nve-card-header>\n <nve-card-content>\n <p nve-text=\"body\" nve-layout=\"pad:md\" style=\"text-align: center\">Promote the selected model.</p>\n </nve-card-content>\n </nve-card>\n </nve-viewport>\n </div>\n\n <script type=\"module\">\n const viewport = document.querySelector('#viewport-reveal-demo');\n const buttons = Array.from(document.querySelectorAll('[data-viewport-region]'));\n const framing = 80;\n\n buttons.forEach(button => {\n button.addEventListener('click', () => {\n const region = viewport.querySelector('#' + button.dataset.viewportRegion);\n viewport.reveal(\n {\n x: region.offsetLeft - framing,\n y: region.offsetTop - framing,\n width: region.offsetWidth + framing * 2,\n height: region.offsetHeight + framing * 2\n },\n { animated: true, duration: 500 }\n );\n });\n });\n </script>\n `\n};\n\n/**\n * @summary Optionally configure viewport grid lines to use dots instead of lines.\n */\nexport const Dots = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines pattern=\"dots\"></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Use crosses as spatial reference points to help users judge positions while keeping the content between them unobstructed.\n */\nexport const Crosses = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <nve-viewport-gridlines pattern=\"crosses\"></nve-viewport-gridlines>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n `\n};\n\n/**\n * @summary Place custom content in the background slot to provide a spatial reference without affecting content fitting.\n */\nexport const Background = {\n render: () => html`\n <nve-viewport autofit fit-inset=\"24\" behavior-pan behavior-zoom style=\"height: 420px\">\n <svg\n slot=\"background\"\n aria-hidden=\"true\"\n width=\"20480\"\n height=\"20480\"\n viewBox=\"-10240 -10240 20480 20480\"\n style=\"position: absolute; left: -10240px; top: -10240px\"\n >\n <defs>\n <pattern id=\"viewport-background-triangles\" width=\"200\" height=\"200\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 0 0 H 200 V 200 M 0 0 L 200 200 M 0 200 L 200 0\" fill=\"none\" stroke=\"var(--nve-ref-border-color-muted)\" stroke-width=\"1.5\" vector-effect=\"non-scaling-stroke\"></path>\n </pattern>\n </defs>\n <rect x=\"-10240\" y=\"-10240\" width=\"20480\" height=\"20480\" fill=\"url(#viewport-background-triangles)\"></rect>\n </svg>\n\n <svg\n role=\"img\"\n aria-label=\"Three geometric forms in a spatial field\"\n width=\"900\"\n height=\"600\"\n viewBox=\"0 0 900 600\"\n style=\"position: absolute; left: 0; top: 0\"\n >\n <circle cx=\"200\" cy=\"400\" r=\"100\" fill=\"var(--nve-ref-color-green-jade-600)\"></circle>\n <rect x=\"350\" y=\"100\" width=\"200\" height=\"200\" rx=\"50\" fill=\"var(--nve-ref-color-blue-cobalt-600)\"></rect>\n <path d=\"M 700 290 L 810 400 L 700 510 L 590 400 Z\" fill=\"var(--nve-ref-color-purple-lavender-600)\"></path>\n <rect x=\"1\" y=\"1\" width=\"898\" height=\"598\" rx=\"24\" fill=\"none\" stroke=\"var(--nve-ref-border-color-emphasis)\" stroke-width=\"2\" stroke-dasharray=\"32 20\" vector-effect=\"non-scaling-stroke\"></rect>\n </svg>\n </nve-viewport>\n `\n};\n"],"mappings":";AAGA,IAAA,IAAS"}