kritzel-stencil 0.4.4 → 0.4.5

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 (117) hide show
  1. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +1 -1
  2. package/dist/collection/constants/version.js +1 -1
  3. package/dist/components/index.js +1226 -1
  4. package/dist/components/kritzel-active-users.js +6 -1
  5. package/dist/components/kritzel-avatar.js +6 -1
  6. package/dist/components/kritzel-awareness-cursors.js +6 -1
  7. package/dist/components/kritzel-back-to-content.js +6 -1
  8. package/dist/components/kritzel-brush-style.js +64 -1
  9. package/dist/components/kritzel-button.js +6 -1
  10. package/dist/components/kritzel-color-palette.js +6 -1
  11. package/dist/components/kritzel-color.js +6 -1
  12. package/dist/components/kritzel-context-menu.js +6 -1
  13. package/dist/components/kritzel-controls.js +6 -1
  14. package/dist/components/kritzel-current-user-dialog.js +6 -1
  15. package/dist/components/kritzel-current-user.js +6 -1
  16. package/dist/components/kritzel-cursor-trail.js +6 -1
  17. package/dist/components/kritzel-dialog.js +6 -1
  18. package/dist/components/kritzel-dropdown.js +6 -1
  19. package/dist/components/kritzel-editor.js +4396 -1
  20. package/dist/components/kritzel-engine.js +6 -1
  21. package/dist/components/kritzel-export.js +6 -1
  22. package/dist/components/kritzel-font-family.js +6 -1
  23. package/dist/components/kritzel-font-size.js +6 -1
  24. package/dist/components/kritzel-font.js +6 -1
  25. package/dist/components/kritzel-icon.js +6 -1
  26. package/dist/components/kritzel-input.js +6 -1
  27. package/dist/components/kritzel-line-endings.js +6 -1
  28. package/dist/components/kritzel-loading-overlay.js +6 -1
  29. package/dist/components/kritzel-login-dialog.js +6 -1
  30. package/dist/components/kritzel-master-detail.js +6 -1
  31. package/dist/components/kritzel-menu-item.js +6 -1
  32. package/dist/components/kritzel-menu.js +6 -1
  33. package/dist/components/kritzel-more-menu.js +6 -1
  34. package/dist/components/kritzel-notification-card.js +6 -1
  35. package/dist/components/kritzel-numeric-input.js +6 -1
  36. package/dist/components/kritzel-opacity-slider.js +6 -1
  37. package/dist/components/kritzel-pill-tabs.js +6 -1
  38. package/dist/components/kritzel-portal.js +6 -1
  39. package/dist/components/kritzel-settings.js +6 -1
  40. package/dist/components/kritzel-shape-fill.js +6 -1
  41. package/dist/components/kritzel-share-dialog.js +6 -1
  42. package/dist/components/kritzel-slide-toggle.js +6 -1
  43. package/dist/components/kritzel-split-button.js +6 -1
  44. package/dist/components/kritzel-stroke-size.js +6 -1
  45. package/dist/components/kritzel-sync-indicator.js +6 -1
  46. package/dist/components/kritzel-tool-config.js +6 -1
  47. package/dist/components/kritzel-tooltip.js +6 -1
  48. package/dist/components/kritzel-utility-panel.js +6 -1
  49. package/dist/components/kritzel-watermark.js +6 -1
  50. package/dist/components/kritzel-workspace-manager.js +6 -1
  51. package/dist/components/kritzel-zoom-panel.js +6 -1
  52. package/dist/components/p--Oazz-BP.js +51657 -2
  53. package/dist/components/p-894OnDQV.js +39 -1
  54. package/dist/components/p-B43upypT.js +1500 -1
  55. package/dist/components/p-B5oHmPJb.js +97 -1
  56. package/dist/components/p-B6t5q-V4.js +63 -1
  57. package/dist/components/p-B8Xi4Clg.js +43 -1
  58. package/dist/components/p-BDzlx2hB.js +135 -1
  59. package/dist/components/p-BFTU3MAI.js +7 -1
  60. package/dist/components/p-BFYtCsZu.js +56 -1
  61. package/dist/components/p-BI2ng9I_.js +62 -1
  62. package/dist/components/p-BTzlrIxe.js +194 -1
  63. package/dist/components/p-BmyTdQGy.js +1090 -1
  64. package/dist/components/p-BsANVili.js +150 -1
  65. package/dist/components/p-BxpKq94F.js +290 -1
  66. package/dist/components/p-C38P-Vd0.js +446 -1
  67. package/dist/components/p-C4NrrUfN.js +77 -1
  68. package/dist/components/p-CW-VyJgK.js +6 -1
  69. package/dist/components/p-CWRSGYOE.js +57 -1
  70. package/dist/components/p-CXpv9Rxe.js +106 -1
  71. package/dist/components/p-Ca-igU1f.js +320 -1
  72. package/dist/components/p-CdR76C4L.js +165 -1
  73. package/dist/components/p-ClFprFvz.js +209 -1
  74. package/dist/components/p-Cm33td2O.js +122 -1
  75. package/dist/components/p-CqLgB8JK.js +91 -1
  76. package/dist/components/p-Cr682JI_.js +156 -1
  77. package/dist/components/p-CsvMgk_f.js +62 -1
  78. package/dist/components/p-CwJwsRR3.js +277 -1
  79. package/dist/components/p-Cymum41a.js +88 -1
  80. package/dist/components/p-D09kgc5Q.js +94 -1
  81. package/dist/components/p-D30zs0kA.js +121 -1
  82. package/dist/components/p-D3y_Hauo.js +85 -1
  83. package/dist/components/p-D5jf8wAu.js +142 -1
  84. package/dist/components/p-D82VaHce.js +53 -1
  85. package/dist/components/p-DAwPPDMS.js +101 -1
  86. package/dist/components/p-DEBwmRTC.js +55 -1
  87. package/dist/components/p-DIazmg6w.js +52 -1
  88. package/dist/components/p-DJ88BrIW.js +70 -1
  89. package/dist/components/p-DJkKlUyZ.js +182 -1
  90. package/dist/components/p-DUYmwrWV.js +3267 -1
  91. package/dist/components/p-DX2nriaq.js +486 -1
  92. package/dist/components/p-Dd-pMvlr.js +20 -1
  93. package/dist/components/p-Df3BwVGy.js +299 -1
  94. package/dist/components/p-DgJ0ufzr.js +43 -1
  95. package/dist/components/p-DkUb2czk.js +70 -1
  96. package/dist/components/p-Dlp84thc.js +57 -1
  97. package/dist/components/p-JYj3Facr.js +431 -1
  98. package/dist/components/p-Ka7OWbnk.js +2304 -1
  99. package/dist/components/p-PSFAfAyd.js +49 -1
  100. package/dist/components/p-U6uE85Qx.js +320 -0
  101. package/dist/components/p-WUdQqYnu.js +118 -1
  102. package/dist/components/p-djJSnjAX.js +84 -1
  103. package/dist/components/p-e6Zpc9Vp.js +143 -1
  104. package/dist/components/p-jGOpkGDl.js +30 -1
  105. package/dist/components/p-pagW8YF7.js +99 -1
  106. package/dist/esm/kritzel-active-users_47.entry.js +1 -1
  107. package/dist/stencil/index.esm.js +1172 -1
  108. package/dist/stencil/p-4463dade.entry.js +36043 -0
  109. package/dist/stencil/p-DQuL1Twl.js +3 -1
  110. package/dist/stencil/p-Dhio9uis.js +1717 -2
  111. package/dist/stencil/p-fb32cd8f.entry.js +29 -1
  112. package/dist/stencil/p-uC7_X6yr.js +30737 -1
  113. package/dist/stencil/stencil.esm.js +21 -1
  114. package/dist/types/constants/version.d.ts +1 -1
  115. package/package.json +1 -1
  116. package/dist/components/p-Xsiz1D5Q.js +0 -1
  117. package/dist/stencil/p-9abc21b9.entry.js +0 -9
@@ -1 +1,106 @@
1
- import{p as e,H as n,c as t,h as o,d as i,t as r}from"./p-B43upypT.js";const s=e(class extends n{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.valueChange=t(this,"valueChange")}styles=["none","triangle"];value;valueChange;getStartEnding(){return this.value?.start?.enabled?this.value.start.style??"triangle":"none"}getEndEnding(){return this.value?.end?.enabled?this.value.end.style??"triangle":"none"}handleStartChange(e){const n={...this.value,start:"none"===e?{enabled:!1}:{enabled:!0,style:e}};this.value=n,this.valueChange.emit(n)}handleEndChange(e){const n={...this.value,end:"none"===e?{enabled:!1}:{enabled:!0,style:e}};this.value=n,this.valueChange.emit(n)}getEndingPath(e){switch(e){case"triangle":return"M 0 0 L 10 5 L 0 10 Z";case"open":return"M 0 0 L 10 5 L 0 10";case"diamond":return"M 0 5 L 5 0 L 10 5 L 5 10 Z";case"circle":return"M 10 5 A 5 5 0 1 1 0 5 A 5 5 0 1 1 10 5 Z";default:return""}}renderEndingIcon(e,n){const t="var(--kritzel-global-text-primary)";if("none"===e)return o("svg",{viewBox:"0 0 24 12",class:"ending-icon"},o("line",{x1:n?4:2,y1:"6",x2:n?22:20,y2:"6",stroke:t,"stroke-width":"2","stroke-linecap":"round"}));const i=this.getEndingPath(e),r="open"===e;return o("svg",{viewBox:"0 0 24 12",class:"ending-icon"},n?o("g",null,o("line",{x1:"12",y1:"6",x2:"22",y2:"6",stroke:t,"stroke-width":"2","stroke-linecap":"round"}),o("g",{transform:"translate(2, 1) scale(1, 1)"},o("path",{d:i,fill:r?"none":t,stroke:t,"stroke-width":r?2:0,"stroke-linecap":"round","stroke-linejoin":"round",transform:"scale(-1, 1) translate(-10, 0)"}))):o("g",null,o("line",{x1:"2",y1:"6",x2:"12",y2:"6",stroke:t,"stroke-width":"2","stroke-linecap":"round"}),o("g",{transform:"translate(12, 1)"},o("path",{d:i,fill:r?"none":t,stroke:t,"stroke-width":r?2:0,"stroke-linecap":"round","stroke-linejoin":"round"}))))}render(){const e=this.getStartEnding(),n=this.getEndEnding();return o(i,{key:"60115b8a2840ffe21e0846fdc2678c6ba24b22c0"},o("div",{key:"3b63aa05ca78699172c645fdd404efdc55bc4536",class:"endings-section"},o("div",{key:"9538369e8d2bb26600d6054ddbbc13d6c960bd56",class:"endings-row"},this.styles.map((n=>o("button",{class:{"ending-option":!0,selected:e===n},onClick:()=>this.handleStartChange(n),title:"none"===n?"No start arrow":`${n} start arrow`},this.renderEndingIcon(n,!0)))))),o("div",{key:"ecec29740c09a61190938bab4955ccde6b84cfa2",class:"endings-section"},o("div",{key:"ea054597c3e3566e7921f2c04c07d74e4f4331a1",class:"endings-row"},this.styles.map((e=>o("button",{class:{"ending-option":!0,selected:n===e},onClick:()=>this.handleEndChange(e),title:"none"===e?"No end arrow":`${e} end arrow`},this.renderEndingIcon(e,!1)))))))}static get style(){return":host{display:flex;flex-direction:column;gap:12px;padding:0;box-sizing:border-box}.endings-section{display:flex;flex-direction:column;gap:6px}.section-label{font-size:12px;font-weight:500;color:var(--kritzel-line-endings-label-color, #666666);padding-left:4px}.endings-row{display:flex;align-items:center;gap:4px}.ending-option{display:flex;justify-content:center;align-items:center;width:48px;height:32px;border-radius:6px;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background:var(--kritzel-line-endings-option-background, #ffffff);padding:4px;transition:background-color 0.15s ease, border-color 0.15s ease}.ending-option:hover{background-color:var(--kritzel-line-endings-hover-background-color, #ebebeb)}.ending-option.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-line-endings-selected-background-color, #ebebeb)}.ending-option:focus{outline:none;box-shadow:0 0 0 2px var(--kritzel-global-focus-ring-color, rgba(0, 122, 255, 0.3))}.ending-icon{width:100%;height:100%}"}},[513,"kritzel-line-endings",{styles:[16],value:[1040]}]);function l(){"undefined"!=typeof customElements&&["kritzel-line-endings"].forEach((e=>{"kritzel-line-endings"===e&&(customElements.get(r(e))||customElements.define(r(e),s))}))}export{s as K,l as d}
1
+ import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
+
3
+ const kritzelLineEndingsCss = () => `:host{display:flex;flex-direction:column;gap:12px;padding:0;box-sizing:border-box}.endings-section{display:flex;flex-direction:column;gap:6px}.section-label{font-size:12px;font-weight:500;color:var(--kritzel-line-endings-label-color, #666666);padding-left:4px}.endings-row{display:flex;align-items:center;gap:4px}.ending-option{display:flex;justify-content:center;align-items:center;width:48px;height:32px;border-radius:6px;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background:var(--kritzel-line-endings-option-background, #ffffff);padding:4px;transition:background-color 0.15s ease, border-color 0.15s ease}.ending-option:hover{background-color:var(--kritzel-line-endings-hover-background-color, #ebebeb)}.ending-option.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-line-endings-selected-background-color, #ebebeb)}.ending-option:focus{outline:none;box-shadow:0 0 0 2px var(--kritzel-global-focus-ring-color, rgba(0, 122, 255, 0.3))}.ending-icon{width:100%;height:100%}`;
4
+
5
+ const KritzelLineEndings = /*@__PURE__*/ proxyCustomElement(class KritzelLineEndings extends H {
6
+ constructor(registerHost) {
7
+ super();
8
+ if (registerHost !== false) {
9
+ this.__registerHost();
10
+ }
11
+ this.__attachShadow();
12
+ this.valueChange = createEvent(this, "valueChange");
13
+ }
14
+ /** Available ending styles */
15
+ styles = ['none', 'triangle'];
16
+ /** Current line arrow configuration */
17
+ value;
18
+ valueChange;
19
+ getStartEnding() {
20
+ if (!this.value?.start?.enabled)
21
+ return 'none';
22
+ return this.value.start.style ?? 'triangle';
23
+ }
24
+ getEndEnding() {
25
+ if (!this.value?.end?.enabled)
26
+ return 'none';
27
+ return this.value.end.style ?? 'triangle';
28
+ }
29
+ handleStartChange(type) {
30
+ const newValue = {
31
+ ...this.value,
32
+ start: type === 'none'
33
+ ? { enabled: false }
34
+ : { enabled: true, style: type },
35
+ };
36
+ this.value = newValue;
37
+ this.valueChange.emit(newValue);
38
+ }
39
+ handleEndChange(type) {
40
+ const newValue = {
41
+ ...this.value,
42
+ end: type === 'none'
43
+ ? { enabled: false }
44
+ : { enabled: true, style: type },
45
+ };
46
+ this.value = newValue;
47
+ this.valueChange.emit(newValue);
48
+ }
49
+ getEndingPath(type) {
50
+ switch (type) {
51
+ case 'triangle':
52
+ return 'M 0 0 L 10 5 L 0 10 Z';
53
+ case 'open':
54
+ return 'M 0 0 L 10 5 L 0 10';
55
+ case 'diamond':
56
+ return 'M 0 5 L 5 0 L 10 5 L 5 10 Z';
57
+ case 'circle':
58
+ return 'M 10 5 A 5 5 0 1 1 0 5 A 5 5 0 1 1 10 5 Z';
59
+ default:
60
+ return '';
61
+ }
62
+ }
63
+ renderEndingIcon(type, isStart) {
64
+ const color = 'var(--kritzel-global-text-primary)';
65
+ if (type === 'none') {
66
+ return (h("svg", { viewBox: "0 0 24 12", class: "ending-icon" }, h("line", { x1: isStart ? 4 : 2, y1: "6", x2: isStart ? 22 : 20, y2: "6", stroke: color, "stroke-width": "2", "stroke-linecap": "round" })));
67
+ }
68
+ const path = this.getEndingPath(type);
69
+ const isOpenStyle = type === 'open';
70
+ return (h("svg", { viewBox: "0 0 24 12", class: "ending-icon" }, isStart ? (
71
+ // Start arrow points left
72
+ h("g", null, h("line", { x1: "12", y1: "6", x2: "22", y2: "6", stroke: color, "stroke-width": "2", "stroke-linecap": "round" }), h("g", { transform: "translate(2, 1) scale(1, 1)" }, h("path", { d: path, fill: isOpenStyle ? 'none' : color, stroke: color, "stroke-width": isOpenStyle ? 2 : 0, "stroke-linecap": "round", "stroke-linejoin": "round", transform: "scale(-1, 1) translate(-10, 0)" })))) : (
73
+ // End arrow points right
74
+ h("g", null, h("line", { x1: "2", y1: "6", x2: "12", y2: "6", stroke: color, "stroke-width": "2", "stroke-linecap": "round" }), h("g", { transform: "translate(12, 1)" }, h("path", { d: path, fill: isOpenStyle ? 'none' : color, stroke: color, "stroke-width": isOpenStyle ? 2 : 0, "stroke-linecap": "round", "stroke-linejoin": "round" }))))));
75
+ }
76
+ render() {
77
+ const startEnding = this.getStartEnding();
78
+ const endEnding = this.getEndEnding();
79
+ return (h(Host, { key: '60115b8a2840ffe21e0846fdc2678c6ba24b22c0' }, h("div", { key: '3b63aa05ca78699172c645fdd404efdc55bc4536', class: "endings-section" }, h("div", { key: '9538369e8d2bb26600d6054ddbbc13d6c960bd56', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
80
+ 'ending-option': true,
81
+ 'selected': startEnding === type,
82
+ }, onClick: () => this.handleStartChange(type), title: type === 'none' ? 'No start arrow' : `${type} start arrow` }, this.renderEndingIcon(type, true)))))), h("div", { key: 'ecec29740c09a61190938bab4955ccde6b84cfa2', class: "endings-section" }, h("div", { key: 'ea054597c3e3566e7921f2c04c07d74e4f4331a1', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
83
+ 'ending-option': true,
84
+ 'selected': endEnding === type,
85
+ }, onClick: () => this.handleEndChange(type), title: type === 'none' ? 'No end arrow' : `${type} end arrow` }, this.renderEndingIcon(type, false))))))));
86
+ }
87
+ static get style() { return kritzelLineEndingsCss(); }
88
+ }, [513, "kritzel-line-endings", {
89
+ "styles": [16],
90
+ "value": [1040]
91
+ }]);
92
+ function defineCustomElement() {
93
+ if (typeof customElements === "undefined") {
94
+ return;
95
+ }
96
+ const components = ["kritzel-line-endings"];
97
+ components.forEach(tagName => { switch (tagName) {
98
+ case "kritzel-line-endings":
99
+ if (!customElements.get(transformTag(tagName))) {
100
+ customElements.define(transformTag(tagName), KritzelLineEndings);
101
+ }
102
+ break;
103
+ } });
104
+ }
105
+
106
+ export { KritzelLineEndings as K, defineCustomElement as d };
@@ -1 +1,320 @@
1
- import{p as t,H as s,c as i,h as e,d as n,t as h}from"./p-B43upypT.js";import{O as o}from"./p-Dd-pMvlr.js";import{K as r}from"./p-WUdQqYnu.js";const l=t(class extends s{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.close=i(this,"close")}get host(){return this}anchor;anchorChanged(t){t?(this.openPortal(),requestAnimationFrame((()=>{this.calculatePosition(),this.autoFocus&&this.focusFirstElement()}))):this.closePortal()}offsetX;offsetY;autoFocus=!0;close;handleDismissMenus(){this.portal&&(this.close.emit(),this.closePortal())}handleOutsideClick(t){this.lastAddedPortal===this.portal&&(this.host.contains(t.target)||(this.close.emit(),this.closePortal()))}handleOutsidePointerDown(t){if(!this.portal)return;if(this.lastAddedPortal!==this.portal)return;const s=t.composedPath(),i=s.some((t=>t===this.host)),e=this.anchor&&s.some((t=>t===this.anchor));i||e||(t.stopPropagation(),t.preventDefault(),this.close.emit(),this.closePortal())}handleKeyDown(t){if(this.lastAddedPortal===this.portal){if("Escape"===t.key)return t.stopPropagation(),this.anchor.focus(),this.close.emit(),void this.closePortal();if("Tab"!==t.key){if("Enter"===t.key){const s=this.getDeepActiveElement();s?.click&&(t.preventDefault(),s.click())}}else this.trapFocus(t)}}handleResize(){this.calculatePosition()}handleWindowScroll(){if(!r.isElementInViewport(this.anchor))return this.anchor?.blur(),void this.closePortal();this.calculatePosition()}portal;id=`portal-${o.generateUUID()}`;defaultOffset=0;minLeft=0;themeObserver;focusFirstElement(){requestAnimationFrame((()=>{this.firstFocusableElement?.focus?.()}))}getDeepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t}trapFocus(t){const s=r.getFocusableElements(this.host);if(0===s.length)return;const i=s[0],e=s[s.length-1],n=this.getDeepActiveElement();t.shiftKey?n===i&&(e.focus(),t.preventDefault()):n===e&&(i.focus(),t.preventDefault())}get firstFocusableElement(){const t=this.host.shadowRoot?.querySelector("slot"),s=t?.assignedElements({flatten:!0})[0];return s?r.getFocusableElements(s)[0]??s:null}get lastAddedPortal(){const t=Array.from(document.querySelectorAll('[id^="portal-"]'));return t.length?t[t.length-1]:null}calculateLeft(){if(!this.anchor||!this.portal)return 0;const t=this.anchor.getBoundingClientRect(),s=this.portal.getBoundingClientRect(),i=this.offsetX??this.defaultOffset;let e;e=t.left+t.width/2>window.innerWidth/2?t.right-s.width-i:t.left+i;const n=window.innerWidth-s.width-this.minLeft;return e<this.minLeft&&(e=this.minLeft),e>n&&(e=n),Math.round(e+window.scrollX)}calculateTop(){if(!this.anchor||!this.portal)return 0;const t=this.anchor.getBoundingClientRect(),s=this.portal.getBoundingClientRect(),i=this.offsetY??this.defaultOffset;let e=t.bottom+i;const n=window.innerHeight-t.bottom-i-8,h=t.top-i-8;return this.host.style.removeProperty("--kritzel-portal-max-height"),s.height<=n?e=t.bottom+i:s.height<=h?e=t.top-s.height-i:n>=h?(e=t.bottom+i,this.host.style.setProperty("--kritzel-portal-max-height",`${n}px`)):(e=8,this.host.style.setProperty("--kritzel-portal-max-height",`${h}px`)),Math.round(e+window.scrollY)}getThemeProvider(){if(!this.anchor)return null;let t=this.anchor;for(;t;){const i=t.closest("kritzel-editor");if(i instanceof s)return i;const e=t.closest('[id^="portal-"]');if(e instanceof s)return e;const n=t.getRootNode();if(!(n instanceof ShadowRoot))return null;t=n.host}return null}openPortal(){this.portal=document.createElement("div"),this.portal.setAttribute("id",this.id),this.portal.style.zIndex="1",this.portal.style.position="absolute",this.portal.style.top="0px",this.portal.style.left="0px",this.portal.style.visibility="hidden";const t=this.getThemeProvider();if(t){const s=()=>{if(this.portal)for(let s=0;s<t.style.length;s++){const i=t.style[s];i.startsWith("--kritzel-")&&this.portal.style.setProperty(i,t.style.getPropertyValue(i))}};s(),this.themeObserver=new MutationObserver((()=>s())),this.themeObserver.observe(t,{attributes:!0,attributeFilter:["style"]})}this.portal.appendChild(this.host),document.body.append(this.portal)}closePortal(){this.themeObserver?.disconnect(),this.themeObserver=null;const t=document.getElementById(this.id);t&&(document.body.removeChild(t),this.host.remove())}calculatePosition(){if(!this.anchor||!this.portal)return;const t=this.calculateTop(),s=this.calculateLeft();this.portal.style.top=`${t}px`,this.portal.style.left=`${s}px`,this.portal.style.visibility="visible"}render(){return e(n,{key:"f919789973cd7828b393028171594d481113fb45",style:{display:this.anchor?"block":"none"}},e("slot",{key:"21b837fe7162c0a0a8d01bb5c41d3736a265714c"}))}static get watchers(){return{anchor:[{anchorChanged:0}]}}},[769,"kritzel-portal",{anchor:[16],offsetX:[2,"offset-x"],offsetY:[2,"offset-y"],autoFocus:[4,"auto-focus"]},[[8,"kritzel-dismiss-menus","handleDismissMenus"],[8,"click","handleOutsideClick"],[6,"pointerdown","handleOutsidePointerDown"],[8,"keydown","handleKeyDown"],[11,"resize","handleResize"],[11,"scroll","handleWindowScroll"]],{anchor:[{anchorChanged:0}]}]);function a(){"undefined"!=typeof customElements&&["kritzel-portal"].forEach((t=>{"kritzel-portal"===t&&(customElements.get(h(t))||customElements.define(h(t),l))}))}export{l as K,a as d}
1
+ import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
+ import { O as ObjectHelper } from './p-Dd-pMvlr.js';
3
+ import { K as KritzelHTMLHelper } from './p-WUdQqYnu.js';
4
+
5
+ const KritzelPortal = /*@__PURE__*/ proxyCustomElement(class KritzelPortal extends H {
6
+ constructor(registerHost) {
7
+ super();
8
+ if (registerHost !== false) {
9
+ this.__registerHost();
10
+ }
11
+ this.__attachShadow();
12
+ this.close = createEvent(this, "close");
13
+ }
14
+ get host() { return this; }
15
+ anchor;
16
+ anchorChanged(newValue) {
17
+ if (newValue) {
18
+ this.openPortal();
19
+ // Use requestAnimationFrame to wait for the browser to paint the portal content
20
+ // so that getBoundingClientRect returns accurate dimensions
21
+ requestAnimationFrame(() => {
22
+ this.calculatePosition();
23
+ if (this.autoFocus) {
24
+ this.focusFirstElement();
25
+ }
26
+ });
27
+ }
28
+ else {
29
+ this.closePortal();
30
+ }
31
+ }
32
+ offsetX;
33
+ offsetY;
34
+ autoFocus = true;
35
+ close;
36
+ handleDismissMenus() {
37
+ if (this.portal) {
38
+ this.close.emit();
39
+ this.closePortal();
40
+ }
41
+ }
42
+ handleOutsideClick(event) {
43
+ const isLastPortal = this.lastAddedPortal === this.portal;
44
+ if (!isLastPortal)
45
+ return;
46
+ const target = event.target;
47
+ if (!this.host.contains(target)) {
48
+ this.close.emit();
49
+ this.closePortal();
50
+ }
51
+ }
52
+ handleOutsidePointerDown(event) {
53
+ if (!this.portal)
54
+ return;
55
+ const isLastPortal = this.lastAddedPortal === this.portal;
56
+ if (!isLastPortal)
57
+ return;
58
+ const path = event.composedPath();
59
+ const isInsidePortal = path.some(el => el === this.host);
60
+ const isOnAnchor = this.anchor && path.some(el => el === this.anchor);
61
+ if (!isInsidePortal && !isOnAnchor) {
62
+ event.stopPropagation();
63
+ event.preventDefault();
64
+ this.close.emit();
65
+ this.closePortal();
66
+ }
67
+ }
68
+ handleKeyDown(event) {
69
+ const isLastPortal = this.lastAddedPortal === this.portal;
70
+ if (!isLastPortal)
71
+ return;
72
+ if (event.key === 'Escape') {
73
+ event.stopPropagation();
74
+ this.anchor.focus();
75
+ this.close.emit();
76
+ this.closePortal();
77
+ return;
78
+ }
79
+ if (event.key === 'Tab') {
80
+ this.trapFocus(event);
81
+ return;
82
+ }
83
+ if (event.key === 'Enter') {
84
+ const activeElement = this.getDeepActiveElement();
85
+ if (activeElement?.click) {
86
+ event.preventDefault();
87
+ activeElement.click();
88
+ }
89
+ }
90
+ }
91
+ handleResize() {
92
+ this.calculatePosition();
93
+ }
94
+ handleWindowScroll() {
95
+ const isInViewport = KritzelHTMLHelper.isElementInViewport(this.anchor);
96
+ if (!isInViewport) {
97
+ this.anchor?.blur();
98
+ this.closePortal();
99
+ return;
100
+ }
101
+ this.calculatePosition();
102
+ }
103
+ portal;
104
+ id = `portal-${ObjectHelper.generateUUID()}`;
105
+ defaultOffset = 0;
106
+ minLeft = 0;
107
+ themeObserver;
108
+ focusFirstElement() {
109
+ requestAnimationFrame(() => {
110
+ this.firstFocusableElement?.focus?.();
111
+ });
112
+ }
113
+ getDeepActiveElement() {
114
+ let activeEl = document.activeElement;
115
+ while (activeEl?.shadowRoot?.activeElement) {
116
+ activeEl = activeEl.shadowRoot.activeElement;
117
+ }
118
+ return activeEl;
119
+ }
120
+ trapFocus(event) {
121
+ const focusableElements = KritzelHTMLHelper.getFocusableElements(this.host);
122
+ if (focusableElements.length === 0)
123
+ return;
124
+ const firstFocusable = focusableElements[0];
125
+ const lastFocusable = focusableElements[focusableElements.length - 1];
126
+ const activeElement = this.getDeepActiveElement();
127
+ if (event.shiftKey) {
128
+ /* shift + tab */
129
+ if (activeElement === firstFocusable) {
130
+ lastFocusable.focus();
131
+ event.preventDefault();
132
+ }
133
+ }
134
+ else {
135
+ /* tab */
136
+ if (activeElement === lastFocusable) {
137
+ firstFocusable.focus();
138
+ event.preventDefault();
139
+ }
140
+ }
141
+ }
142
+ get firstFocusableElement() {
143
+ const slotEl = this.host.shadowRoot?.querySelector('slot');
144
+ const firstAssigned = slotEl?.assignedElements({ flatten: true })[0];
145
+ if (!firstAssigned)
146
+ return null;
147
+ const focusable = KritzelHTMLHelper.getFocusableElements(firstAssigned);
148
+ return focusable[0] ?? firstAssigned;
149
+ }
150
+ get lastAddedPortal() {
151
+ const portals = Array.from(document.querySelectorAll('[id^="portal-"]'));
152
+ return portals.length ? portals[portals.length - 1] : null;
153
+ }
154
+ calculateLeft() {
155
+ if (!this.anchor || !this.portal)
156
+ return 0;
157
+ const refRect = this.anchor.getBoundingClientRect();
158
+ const portalRect = this.portal.getBoundingClientRect();
159
+ const offset = this.offsetX ?? this.defaultOffset;
160
+ // Determine alignment based on anchor position
161
+ // If anchor center is past the viewport midpoint, align to end (right edge of anchor)
162
+ const anchorCenter = refRect.left + refRect.width / 2;
163
+ const viewportMidpoint = window.innerWidth / 2;
164
+ const shouldAlignEnd = anchorCenter > viewportMidpoint;
165
+ let left;
166
+ if (shouldAlignEnd) {
167
+ // Align portal's right edge to anchor's right edge
168
+ left = refRect.right - portalRect.width - offset;
169
+ }
170
+ else {
171
+ // Align portal's left edge to anchor's left edge
172
+ left = refRect.left + offset;
173
+ }
174
+ // Clamp to viewport bounds
175
+ const maxLeft = window.innerWidth - portalRect.width - this.minLeft;
176
+ if (left < this.minLeft)
177
+ left = this.minLeft;
178
+ if (left > maxLeft)
179
+ left = maxLeft;
180
+ return Math.round(left + window.scrollX);
181
+ }
182
+ calculateTop() {
183
+ if (!this.anchor || !this.portal)
184
+ return 0;
185
+ const refRect = this.anchor.getBoundingClientRect();
186
+ const portalRect = this.portal.getBoundingClientRect();
187
+ const offset = this.offsetY ?? this.defaultOffset;
188
+ const padding = 8; // Minimum padding from viewport edges
189
+ let top = refRect.bottom + offset;
190
+ const spaceBelow = window.innerHeight - refRect.bottom - offset - padding;
191
+ const spaceAbove = refRect.top - offset - padding;
192
+ // Reset max-height CSS custom property
193
+ this.host.style.removeProperty('--kritzel-portal-max-height');
194
+ if (portalRect.height <= spaceBelow) {
195
+ // Fits below the anchor
196
+ top = refRect.bottom + offset;
197
+ }
198
+ else if (portalRect.height <= spaceAbove) {
199
+ // Fits above the anchor
200
+ top = refRect.top - portalRect.height - offset;
201
+ }
202
+ else {
203
+ // Doesn't fit above or below - constrain the height
204
+ if (spaceBelow >= spaceAbove) {
205
+ // More space below, keep it below with constrained height
206
+ top = refRect.bottom + offset;
207
+ this.host.style.setProperty('--kritzel-portal-max-height', `${spaceBelow}px`);
208
+ }
209
+ else {
210
+ // More space above, position above with constrained height
211
+ top = padding;
212
+ this.host.style.setProperty('--kritzel-portal-max-height', `${spaceAbove}px`);
213
+ }
214
+ }
215
+ return Math.round(top + window.scrollY);
216
+ }
217
+ getThemeProvider() {
218
+ if (!this.anchor)
219
+ return null;
220
+ let current = this.anchor;
221
+ while (current) {
222
+ const provider = current.closest('kritzel-editor');
223
+ if (provider instanceof H) {
224
+ return provider;
225
+ }
226
+ const portalProvider = current.closest('[id^="portal-"]');
227
+ if (portalProvider instanceof H) {
228
+ return portalProvider;
229
+ }
230
+ const root = current.getRootNode();
231
+ if (root instanceof ShadowRoot) {
232
+ current = root.host;
233
+ }
234
+ else {
235
+ return null;
236
+ }
237
+ }
238
+ return null;
239
+ }
240
+ openPortal() {
241
+ this.portal = document.createElement('div');
242
+ this.portal.setAttribute('id', this.id);
243
+ this.portal.style.zIndex = '1';
244
+ this.portal.style.position = 'absolute';
245
+ this.portal.style.top = '0px';
246
+ this.portal.style.left = '0px';
247
+ this.portal.style.visibility = 'hidden';
248
+ const themeProvider = this.getThemeProvider();
249
+ if (themeProvider) {
250
+ const applyTheme = () => {
251
+ if (!this.portal)
252
+ return;
253
+ for (let i = 0; i < themeProvider.style.length; i++) {
254
+ const prop = themeProvider.style[i];
255
+ if (prop.startsWith('--kritzel-')) {
256
+ this.portal.style.setProperty(prop, themeProvider.style.getPropertyValue(prop));
257
+ }
258
+ }
259
+ };
260
+ applyTheme();
261
+ this.themeObserver = new MutationObserver(() => applyTheme());
262
+ this.themeObserver.observe(themeProvider, {
263
+ attributes: true,
264
+ attributeFilter: ['style'],
265
+ });
266
+ }
267
+ this.portal.appendChild(this.host);
268
+ document.body.append(this.portal);
269
+ }
270
+ closePortal() {
271
+ this.themeObserver?.disconnect();
272
+ this.themeObserver = null;
273
+ const portal = document.getElementById(this.id);
274
+ if (!portal)
275
+ return;
276
+ document.body.removeChild(portal);
277
+ this.host.remove();
278
+ }
279
+ calculatePosition() {
280
+ if (!this.anchor || !this.portal)
281
+ return;
282
+ const top = this.calculateTop();
283
+ const left = this.calculateLeft();
284
+ this.portal.style.top = `${top}px`;
285
+ this.portal.style.left = `${left}px`;
286
+ this.portal.style.visibility = 'visible';
287
+ }
288
+ render() {
289
+ return (h(Host, { key: 'f919789973cd7828b393028171594d481113fb45', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '21b837fe7162c0a0a8d01bb5c41d3736a265714c' })));
290
+ }
291
+ static get watchers() { return {
292
+ "anchor": [{
293
+ "anchorChanged": 0
294
+ }]
295
+ }; }
296
+ }, [769, "kritzel-portal", {
297
+ "anchor": [16],
298
+ "offsetX": [2, "offset-x"],
299
+ "offsetY": [2, "offset-y"],
300
+ "autoFocus": [4, "auto-focus"]
301
+ }, [[8, "kritzel-dismiss-menus", "handleDismissMenus"], [8, "click", "handleOutsideClick"], [6, "pointerdown", "handleOutsidePointerDown"], [8, "keydown", "handleKeyDown"], [11, "resize", "handleResize"], [11, "scroll", "handleWindowScroll"]], {
302
+ "anchor": [{
303
+ "anchorChanged": 0
304
+ }]
305
+ }]);
306
+ function defineCustomElement() {
307
+ if (typeof customElements === "undefined") {
308
+ return;
309
+ }
310
+ const components = ["kritzel-portal"];
311
+ components.forEach(tagName => { switch (tagName) {
312
+ case "kritzel-portal":
313
+ if (!customElements.get(transformTag(tagName))) {
314
+ customElements.define(transformTag(tagName), KritzelPortal);
315
+ }
316
+ break;
317
+ } });
318
+ }
319
+
320
+ export { KritzelPortal as K, defineCustomElement as d };