@verbb/plugin-kit-web 2.0.16 → 2.0.18

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 (155) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +3 -3
  3. package/custom-elements.json +19620 -19410
  4. package/dist/chunks/{pk-autocomplete-kOT0Zlld.js → pk-autocomplete-IFL-u-RF.js} +2 -2
  5. package/dist/chunks/{pk-autocomplete-kOT0Zlld.js.map → pk-autocomplete-IFL-u-RF.js.map} +1 -1
  6. package/dist/chunks/{pk-combobox-Dn7UJ_CV.js → pk-combobox-CL9En0J-.js} +2 -2
  7. package/dist/chunks/{pk-combobox-Dn7UJ_CV.js.map → pk-combobox-CL9En0J-.js.map} +1 -1
  8. package/dist/chunks/pk-copy-button-BVaOLtYG.js.map +1 -1
  9. package/dist/chunks/{pk-date-picker-DfIvmoZ1.js → pk-date-picker-BEAd4Ngl.js} +2 -2
  10. package/dist/chunks/{pk-date-picker-DfIvmoZ1.js.map → pk-date-picker-BEAd4Ngl.js.map} +1 -1
  11. package/dist/chunks/pk-dialog-VMQqLW1f.js.map +1 -1
  12. package/dist/chunks/{pk-dropdown-item-BZQS87U0.js → pk-dropdown-item-D9OaG5o-.js} +8 -4
  13. package/dist/chunks/pk-dropdown-item-D9OaG5o-.js.map +1 -0
  14. package/dist/chunks/{pk-dropdown-menu-D60p2-9X.js → pk-dropdown-menu-DW1wI8xQ.js} +5 -3
  15. package/dist/chunks/pk-dropdown-menu-DW1wI8xQ.js.map +1 -0
  16. package/dist/chunks/{pk-editable-table-BQ47MXpu.js → pk-editable-table-BubcKCBn.js} +17 -12
  17. package/dist/chunks/pk-editable-table-BubcKCBn.js.map +1 -0
  18. package/dist/chunks/{pk-image-browser-BXFDfch3.js → pk-image-browser-DwiCFOIG.js} +3 -3
  19. package/dist/chunks/pk-image-browser-DwiCFOIG.js.map +1 -0
  20. package/dist/chunks/pk-input-CF_icEtR.js.map +1 -1
  21. package/dist/chunks/{pk-input-group-CWdoVhkH.js → pk-input-group-BLqKPnfc.js} +2 -2
  22. package/dist/chunks/{pk-input-group-CWdoVhkH.js.map → pk-input-group-BLqKPnfc.js.map} +1 -1
  23. package/dist/chunks/{pk-popover-KSIOYlbs.js → pk-popover-D3jkHfwB.js} +2 -2
  24. package/dist/chunks/pk-popover-D3jkHfwB.js.map +1 -0
  25. package/dist/chunks/{pk-popup-B9AgBC2V.js → pk-popup-B65tZMQH.js} +23 -1
  26. package/dist/chunks/pk-popup-B65tZMQH.js.map +1 -0
  27. package/dist/chunks/{pk-select-DQtORz-v.js → pk-select-CdQdhnZN.js} +2 -2
  28. package/dist/chunks/{pk-select-DQtORz-v.js.map → pk-select-CdQdhnZN.js.map} +1 -1
  29. package/dist/chunks/{pk-time-picker-DLUBYLFo.js → pk-time-picker-CebRqydV.js} +2 -2
  30. package/dist/chunks/{pk-time-picker-DLUBYLFo.js.map → pk-time-picker-CebRqydV.js.map} +1 -1
  31. package/dist/chunks/{pk-tiptap-content-BwkqYVJb.js → pk-tiptap-content-CL8smjGi.js} +5 -2
  32. package/dist/chunks/{pk-tiptap-content-BwkqYVJb.js.map → pk-tiptap-content-CL8smjGi.js.map} +1 -1
  33. package/dist/chunks/{pk-tiptap-editor-De8UUTis.js → pk-tiptap-editor-CTz-yfHL.js} +327 -11
  34. package/dist/chunks/pk-tiptap-editor-CTz-yfHL.js.map +1 -0
  35. package/dist/chunks/{pk-tooltip-Cmmc0916.js → pk-tooltip--QBV6puX.js} +2 -2
  36. package/dist/chunks/{pk-tooltip-Cmmc0916.js.map → pk-tooltip--QBV6puX.js.map} +1 -1
  37. package/dist/chunks/{register-posLyX3U.js → register-Bw9kG690.js} +14 -14
  38. package/dist/chunks/{register-posLyX3U.js.map → register-Bw9kG690.js.map} +1 -1
  39. package/dist/components/autocomplete/pk-autocomplete.js +1 -1
  40. package/dist/components/autocomplete.js +1 -1
  41. package/dist/components/combobox/pk-combobox.js +1 -1
  42. package/dist/components/combobox.js +1 -1
  43. package/dist/components/connect/pk-connect-oauth.d.ts +1 -1
  44. package/dist/components/connect/pk-connect-oauth.js.map +1 -1
  45. package/dist/components/copy-button/pk-copy-button.d.ts +1 -1
  46. package/dist/components/date-picker/pk-date-picker.js +1 -1
  47. package/dist/components/date-picker.js +1 -1
  48. package/dist/components/dialog/pk-dialog.d.ts +1 -1
  49. package/dist/components/dropdown-menu/pk-dropdown-item.d.ts +3 -1
  50. package/dist/components/dropdown-menu/pk-dropdown-item.d.ts.map +1 -1
  51. package/dist/components/dropdown-menu/pk-dropdown-item.js +1 -1
  52. package/dist/components/dropdown-menu/pk-dropdown-item.styles.d.ts.map +1 -1
  53. package/dist/components/dropdown-menu/pk-dropdown-menu.js +1 -1
  54. package/dist/components/dropdown-menu/pk-dropdown-menu.styles.d.ts.map +1 -1
  55. package/dist/components/dropdown-menu.js +2 -2
  56. package/dist/components/editable-table/pk-editable-table.d.ts +1 -1
  57. package/dist/components/editable-table/pk-editable-table.d.ts.map +1 -1
  58. package/dist/components/editable-table/pk-editable-table.js +1 -1
  59. package/dist/components/editable-table.js +1 -1
  60. package/dist/components/image-browser/pk-image-browser.d.ts +1 -1
  61. package/dist/components/image-browser/pk-image-browser.js +1 -1
  62. package/dist/components/image-browser.js +1 -1
  63. package/dist/components/input/pk-input.d.ts +2 -2
  64. package/dist/components/input-group/pk-input-group.d.ts +2 -2
  65. package/dist/components/input-group/pk-input-group.d.ts.map +1 -1
  66. package/dist/components/input-group/pk-input-group.js +1 -1
  67. package/dist/components/input-group.js +1 -1
  68. package/dist/components/popover/pk-popover.d.ts +2 -2
  69. package/dist/components/popover/pk-popover.js +1 -1
  70. package/dist/components/popover.js +1 -1
  71. package/dist/components/popup/pk-popup.d.ts +4 -0
  72. package/dist/components/popup/pk-popup.d.ts.map +1 -1
  73. package/dist/components/popup/pk-popup.js +1 -1
  74. package/dist/components/popup.js +1 -1
  75. package/dist/components/select/pk-select.js +1 -1
  76. package/dist/components/select.js +1 -1
  77. package/dist/components/time-picker/pk-time-picker.js +1 -1
  78. package/dist/components/time-picker.js +1 -1
  79. package/dist/components/tiptap/pk-tiptap-content.d.ts.map +1 -1
  80. package/dist/components/tiptap/pk-tiptap-content.js +1 -1
  81. package/dist/components/tiptap/pk-tiptap-editor.d.ts +11 -1
  82. package/dist/components/tiptap/pk-tiptap-editor.d.ts.map +1 -1
  83. package/dist/components/tiptap/pk-tiptap-editor.js +1 -1
  84. package/dist/components/tiptap/pk-tiptap-editor.styles.d.ts.map +1 -1
  85. package/dist/components/tiptap/tiptap-toolbar.d.ts +1 -0
  86. package/dist/components/tiptap/tiptap-toolbar.d.ts.map +1 -1
  87. package/dist/components/tiptap-content.js +1 -1
  88. package/dist/components/tiptap-editor.js +1 -1
  89. package/dist/components/tooltip/pk-tooltip.js +1 -1
  90. package/dist/components/tooltip.js +1 -1
  91. package/dist/index.js +14 -14
  92. package/dist/register.js +14 -14
  93. package/dist-loader/chunks/{option-filter-Z7bomRrK.js → option-filter-Bc5aNNT0.js} +1 -1
  94. package/dist-loader/chunks/{pk-button-dngp-vOd.js → pk-button-saBDszJV.js} +1 -1
  95. package/dist-loader/chunks/{pk-calendar-BE4HRfCq.js → pk-calendar-BrF8i3dW.js} +2 -2
  96. package/dist-loader/chunks/{pk-combobox-DMBKXPLB.js → pk-combobox-Cpx0w1KV.js} +6 -6
  97. package/dist-loader/chunks/{pk-date-picker-wntQmeIM.js → pk-date-picker-DEoiTOxN.js} +5 -5
  98. package/dist-loader/chunks/{pk-dialog-B6lzsRur.js → pk-dialog-C6aaPokv.js} +2 -2
  99. package/dist-loader/chunks/{pk-dropdown-item-DJ5TeF1r.js → pk-dropdown-item-D8RrwjxL.js} +9 -5
  100. package/dist-loader/chunks/pk-dropdown-label-Cg32UgRe.js +51 -0
  101. package/dist-loader/chunks/{pk-dropdown-menu-B87bsdlI.js → pk-dropdown-menu-CAHCltlX.js} +4 -2
  102. package/dist-loader/chunks/{pk-field-D_SNOJpl.js → pk-field-V7JOy26T.js} +2 -2
  103. package/dist-loader/chunks/{pk-icon-B5ob3JdK.js → pk-icon-Bph-EBqp.js} +1 -1
  104. package/dist-loader/chunks/{pk-option-Cc6QWw-0.js → pk-option-BrDMERSl.js} +2 -2
  105. package/dist-loader/chunks/{pk-popup-BooGjXgH.js → pk-popup-CrxxR-Hb.js} +23 -1
  106. package/dist-loader/chunks/{pk-select-BG8qPsBd.js → pk-select-Dok-JdSe.js} +5 -5
  107. package/dist-loader/chunks/{pk-time-picker-CDVFNhN7.js → pk-time-picker-h5Wgd4a_.js} +4 -4
  108. package/dist-loader/chunks/{pk-tooltip-BS2dNLOS.js → pk-tooltip-Dd_Q0Bn5.js} +1 -1
  109. package/dist-loader/chunks/{render-BKfL_WRl.js → render-Bnzcxfss.js} +1 -1
  110. package/dist-loader/chunks/{svg-BiAlXtCn.js → svg-Bz-bXZn7.js} +7 -1
  111. package/dist-loader/chunks/{tiptap-Db7MTUH1.js → tiptap-CgXkiK8d.js} +283 -13
  112. package/dist-loader/chunks/{tiptap.styles-BFGP4eTV.js → tiptap.styles-C0E1NpSx.js} +222 -3
  113. package/dist-loader/components/autocomplete/autocomplete.js +6 -6
  114. package/dist-loader/components/button/button.js +1 -1
  115. package/dist-loader/components/calendar/calendar.js +1 -1
  116. package/dist-loader/components/code-editor/code-editor.js +5 -5
  117. package/dist-loader/components/combobox/combobox.js +1 -1
  118. package/dist-loader/components/connect/connect-oauth.js +3 -3
  119. package/dist-loader/components/connect/connect.js +5 -5
  120. package/dist-loader/components/copy-button/copy-button.js +3 -3
  121. package/dist-loader/components/date-picker/date-picker.js +1 -1
  122. package/dist-loader/components/dialog/dialog.js +1 -1
  123. package/dist-loader/components/dropdown-menu/dropdown-item.js +1 -1
  124. package/dist-loader/components/dropdown-menu/dropdown-label.js +1 -50
  125. package/dist-loader/components/dropdown-menu/dropdown-menu.js +1 -1
  126. package/dist-loader/components/editable-table/editable-table.js +21 -16
  127. package/dist-loader/components/field/field.js +1 -1
  128. package/dist-loader/components/icon/icon.js +2 -2
  129. package/dist-loader/components/image-browser/image-browser.js +5 -5
  130. package/dist-loader/components/input-group/input-group.js +1 -1
  131. package/dist-loader/components/lightswitch/lightswitch.js +1 -1
  132. package/dist-loader/components/popover/popover.js +2 -2
  133. package/dist-loader/components/popup/popup.js +1 -1
  134. package/dist-loader/components/select/option.js +1 -1
  135. package/dist-loader/components/select/select.js +1 -1
  136. package/dist-loader/components/status/status.js +1 -1
  137. package/dist-loader/components/time-picker/time-picker.js +1 -1
  138. package/dist-loader/components/tiptap/tiptap-content.js +6 -3
  139. package/dist-loader/components/tiptap/tiptap-editor.js +332 -16
  140. package/dist-loader/components/tiptap/tiptap-input.js +2 -2
  141. package/dist-loader/components/tooltip/tooltip.js +1 -1
  142. package/package.json +11 -8
  143. package/dist/chunks/pk-dropdown-item-BZQS87U0.js.map +0 -1
  144. package/dist/chunks/pk-dropdown-menu-D60p2-9X.js.map +0 -1
  145. package/dist/chunks/pk-editable-table-BQ47MXpu.js.map +0 -1
  146. package/dist/chunks/pk-image-browser-BXFDfch3.js.map +0 -1
  147. package/dist/chunks/pk-popover-KSIOYlbs.js.map +0 -1
  148. package/dist/chunks/pk-popup-B9AgBC2V.js.map +0 -1
  149. package/dist/chunks/pk-tiptap-editor-De8UUTis.js.map +0 -1
  150. /package/dist-loader/chunks/{floating-ui-DU6GNott.js → floating-ui-Cj0imr6d.js} +0 -0
  151. /package/dist-loader/chunks/{pk-connect.styles-Bfgwu0VH.js → pk-connect.styles-k61snd3X.js} +0 -0
  152. /package/dist-loader/chunks/{pk-lightswitch-DRxY8511.js → pk-lightswitch-m23Cy3_D.js} +0 -0
  153. /package/dist-loader/chunks/{pk-status-D3ArH2ui.js → pk-status-D2g_77m_.js} +0 -0
  154. /package/dist-loader/chunks/{popup-pointer-caPc8kwB.js → popup-pointer-Ck28WdVP.js} +0 -0
  155. /package/dist-loader/chunks/{sync-listbox-separators-Dk_E_IVa.js → sync-listbox-separators-Ch5krDUs.js} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"pk-image-browser-BXFDfch3.js","names":[],"sources":["../../src/components/image-browser/pk-image-browser.styles.ts","../../src/components/image-browser/pk-image-browser.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { iconStyles } from '../../base/icon.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\n/**\n * Presentational static image / icon browser.\n * Trigger chrome mirrors combobox popup-mode; panel grid mirrors Vizy icon picker.\n */\nexport const pkImageBrowserStyles = [\n popupContentAnimationStyles,\n css`\n ${iconStyles}\n @layer pk-component {\n :host {\n display: inline-block;\n position: relative;\n width: fit-content;\n max-width: 100%;\n vertical-align: top;\n color: var(--pk-color-gray-700);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-default);\n --pk-image-browser-padding-block: 6px;\n --pk-image-browser-padding-inline: 10px;\n --pk-image-browser-font-size: var(--pk-font-size-base);\n --pk-image-browser-line-height: var(--pk-input-control-line-height, 1.25rem);\n --pk-image-browser-glyph-size: 1rem;\n --pk-image-browser-panel-width: 26.25rem;\n /* Hit target larger than the glyph so the select ring has breathing room. */\n --pk-image-browser-cell-min: 2.25rem;\n --pk-image-browser-glyph-tile: 1.375rem;\n --pk-image-browser-fill: var(--pk-color-slate-250);\n --pk-image-browser-fill-hover: var(--pk-color-slate-300);\n }\n\n /* Caption under each cell — wider tracks; glyph size stays put. */\n :host([label-mode='inline']) {\n --pk-image-browser-cell-min: 3.75rem;\n }\n\n :host([size='xs']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-xs);\n --pk-image-browser-padding-block: 2px;\n --pk-image-browser-padding-inline: 6px;\n --pk-image-browser-font-size: var(--pk-font-size-xs, 0.75rem);\n --pk-image-browser-glyph-size: 0.875rem;\n }\n\n :host([size='sm']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-sm);\n --pk-image-browser-padding-block: 4px;\n --pk-image-browser-padding-inline: 8px;\n --pk-image-browser-font-size: var(--pk-font-size-sm, 0.8125rem);\n --pk-image-browser-glyph-size: 0.875rem;\n }\n\n :host([size='lg']),\n :host([size='xl']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-lg);\n --pk-image-browser-padding-block: 8px;\n --pk-image-browser-padding-inline: 12px;\n --pk-image-browser-font-size: var(--pk-font-size-lg, 1rem);\n --pk-image-browser-glyph-size: 1.125rem;\n }\n\n /* Image mode — roomier photo tiles; captions still opt-in via label-mode=\"inline\". */\n :host([mode='image']) {\n --pk-image-browser-panel-width: 34rem;\n --pk-image-browser-cell-min: 7.5rem;\n }\n\n :host([mode='image'][label-mode='inline']) {\n /* Captions reclaim a little width; preview stays the hero. */\n --pk-image-browser-cell-min: 6.5rem;\n }\n\n :host([width='full']) {\n display: block;\n width: 100%;\n }\n\n :host([width='full']) .control {\n width: 100%;\n }\n\n .value-input {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n /* Combobox-style chrome: label + clear + chevron share one filled control.\n * 0.5rem gap keeps ellipsized filenames from kissing the clear glyph. */\n .control {\n display: inline-flex;\n align-items: stretch;\n gap: 0.5rem;\n min-width: 12.5rem;\n max-width: 100%;\n height: var(--pk-image-browser-trigger-min-height);\n min-height: var(--pk-image-browser-trigger-min-height);\n margin: 0;\n padding: 0 0 0 var(--pk-image-browser-padding-inline);\n border: 1px solid transparent;\n border-radius: var(--pk-input-border-radius, var(--pk-radius-lg));\n background: var(--pk-image-browser-fill);\n color: inherit;\n box-sizing: border-box;\n overflow: hidden;\n transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;\n }\n\n .control:hover:not(.is-disabled) {\n background: var(--pk-image-browser-fill-hover);\n }\n\n .control.is-open:not(.is-disabled) {\n background: var(--pk-image-browser-fill-hover);\n }\n\n .control:focus-within:not(.is-disabled) {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n background: var(--pk-color-white);\n }\n\n :host([invalid]) .control,\n :host(:state(user-invalid)) .control {\n border-color: var(--pk-color-rose-500, #f43f5e);\n }\n\n .control.is-disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .trigger {\n display: inline-flex;\n align-items: center;\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n padding: var(--pk-image-browser-padding-block) 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: var(--pk-image-browser-font-size);\n font-weight: 400;\n line-height: var(--pk-image-browser-line-height);\n text-align: left;\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n box-sizing: border-box;\n }\n\n .trigger:disabled {\n cursor: not-allowed;\n }\n\n .trigger-main {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n }\n\n .trigger-preview {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n width: var(--pk-image-browser-glyph-size);\n height: var(--pk-image-browser-glyph-size);\n overflow: hidden;\n }\n\n .trigger-preview svg,\n .trigger-preview img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n .trigger-preview svg {\n fill: currentColor;\n }\n\n .trigger-label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .trigger-label.is-placeholder {\n color: var(--pk-color-gray-500);\n }\n\n .clear-button,\n .expand-button {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n box-sizing: border-box;\n width: calc(0.75rem + 0.5rem);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--pk-color-gray-600);\n cursor: pointer;\n outline: none;\n }\n\n .expand-button {\n width: calc(0.75rem + 0.5rem + var(--pk-image-browser-padding-inline));\n padding-inline-end: var(--pk-image-browser-padding-inline);\n }\n\n .clear-button:hover:not(:disabled),\n .expand-button:hover:not(:disabled) {\n color: var(--pk-color-gray-800);\n }\n\n .clear-button:disabled,\n .expand-button:disabled {\n cursor: not-allowed;\n }\n\n .clear-button-icon,\n .expand-button-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 0;\n pointer-events: none;\n }\n\n .clear-button-icon svg,\n .expand-button-icon svg {\n display: block;\n width: 0.75rem;\n height: 0.75rem;\n }\n\n .panel {\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: var(--pk-image-browser-panel-width);\n max-width: min(100vw - 1.5rem, var(--pk-image-browser-panel-width));\n max-height: min(28.75rem, 60vh);\n border-radius: var(--pk-radius-lg);\n background: var(--pk-color-white);\n box-shadow:\n 0 0 0 1px rgba(31, 41, 51, 0.1),\n 0 5px 20px rgba(31, 41, 51, 0.25);\n overflow: hidden;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n\n .panel-search {\n flex: none;\n /* Same inline inset as panel-body so search + grid share one vertical edge. */\n padding: 0.625rem 0.625rem 0.5rem;\n border-bottom: 1px solid var(--pk-color-gray-150, rgba(51, 64, 77, 0.1));\n }\n\n .panel-input {\n display: block;\n width: 100%;\n box-sizing: border-box;\n margin: 0;\n padding: 0.375rem 0.625rem;\n border: 1px solid var(--pk-color-gray-200, #d4dce4);\n border-radius: var(--pk-input-border-radius, var(--pk-radius-md));\n background: var(--pk-color-white);\n color: var(--pk-color-gray-700);\n font: inherit;\n font-size: var(--pk-font-size-sm, 0.8125rem);\n line-height: 1.25rem;\n outline: none;\n }\n\n .panel-input:focus {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n }\n\n .panel-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n /* Match search field inset so the grid lines up with the input. */\n padding: 0.5rem 0.625rem 0.625rem;\n }\n\n :host([mode='image']) .panel-body {\n padding: 0.5rem 0.625rem 0.625rem;\n }\n\n .group + .group {\n margin-top: 0.875rem;\n }\n\n .group-heading {\n display: flex;\n justify-content: space-between;\n gap: 0.5rem;\n margin: 0 0 0.375rem;\n color: var(--pk-color-gray-500);\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n line-height: 1.25;\n text-transform: uppercase;\n }\n\n .group-heading-count {\n font-weight: 400;\n letter-spacing: 0;\n text-transform: none;\n }\n\n /* Fixed column width (not 1fr) so sparse catalogs stay dense instead of stretching. */\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, var(--pk-image-browser-cell-min));\n gap: 0.375rem;\n justify-content: start;\n /* Don’t stretch short single-line cells to match taller wrapped neighbors in the row. */\n align-items: start;\n }\n\n :host([mode='image']) .grid {\n grid-template-columns: repeat(auto-fill, minmax(var(--pk-image-browser-cell-min), 1fr));\n gap: 0.375rem;\n }\n\n .option {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0;\n width: var(--pk-image-browser-cell-min);\n height: var(--pk-image-browser-cell-min);\n margin: 0;\n /* Square hit target; glyph is smaller so the ring doesn’t clip tips. */\n padding: 0;\n border: 1px solid transparent;\n border-radius: var(--pk-radius-sm);\n background: none;\n color: inherit;\n cursor: pointer;\n outline: none;\n overflow: hidden;\n }\n\n /* With captions, height hugs glyph + label instead of a fixed square. */\n :host([label-mode='inline']) .option {\n justify-content: flex-start;\n gap: 0.125rem;\n height: auto;\n /* Keep glyph + caption inside the inset highlight ring. */\n padding: 0.25rem 0.125rem 0.3125rem;\n }\n\n :host([mode='image']) .option {\n position: relative;\n width: auto;\n height: auto;\n min-height: 0;\n gap: 0;\n padding: 0;\n overflow: hidden;\n border-radius: var(--pk-radius-md);\n }\n\n :host([mode='image'][label-mode='inline']) .option {\n gap: 0.375rem;\n padding: 0.375rem 0.375rem 0.5rem;\n overflow: visible;\n }\n\n .option:hover,\n .option:focus-visible,\n .option.is-highlighted {\n background: var(--pk-color-gray-050, #f3f7fc);\n }\n\n /* Selected is the durable chrome; highlight/hover share the same ring for keyboard parity. */\n .option.is-selected,\n .option.is-highlighted,\n .option:hover {\n box-shadow: inset 0 0 0 2px var(--pk-color-sky-600);\n }\n\n /*\n * Flush photo tiles paint over inset box-shadow (descendants sit above it).\n * Overlay the same ring so tooltip/none match inline chrome.\n */\n :host([mode='image']) .option.is-selected,\n :host([mode='image']) .option.is-highlighted,\n :host([mode='image']) .option:hover {\n box-shadow: none;\n }\n\n :host([mode='image']) .option.is-selected::after,\n :host([mode='image']) .option.is-highlighted::after,\n :host([mode='image']) .option:hover::after {\n content: '';\n position: absolute;\n inset: 0;\n z-index: 1;\n border-radius: inherit;\n box-shadow: inset 0 0 0 2px var(--pk-color-sky-600);\n pointer-events: none;\n }\n\n .option:focus-visible {\n outline: none;\n }\n\n .option-preview {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: var(--pk-image-browser-glyph-tile);\n height: var(--pk-image-browser-glyph-tile);\n margin: 0;\n overflow: hidden;\n }\n\n :host([mode='image']) .option-preview {\n width: 100%;\n height: auto;\n aspect-ratio: 4 / 3;\n margin: 0;\n border-radius: inherit;\n }\n\n .option-preview svg,\n .option-preview img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n /* Photo tiles crop to fill — previews, not faithful aspect viewers. */\n :host([mode='image']) .option-preview svg,\n :host([mode='image']) .option-preview img {\n object-fit: cover;\n }\n\n .option-preview svg {\n fill: currentColor;\n }\n\n .option-label {\n display: -webkit-box;\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n padding-inline: 2px;\n overflow: hidden;\n color: var(--pk-color-gray-700);\n font-size: 0.625rem;\n line-height: 0.75rem;\n text-align: center;\n overflow-wrap: anywhere;\n word-break: break-word;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n line-clamp: 3;\n }\n\n :host([mode='image']) .option-label {\n display: block;\n color: var(--pk-color-gray-600);\n font-size: 0.6875rem;\n line-height: 1.2;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow-wrap: normal;\n word-break: normal;\n -webkit-line-clamp: unset;\n line-clamp: unset;\n }\n\n .notice {\n margin: 0.375rem 0;\n color: var(--pk-color-gray-500);\n font-size: var(--pk-font-size-sm, 0.8125rem);\n }\n\n .notice.is-error {\n color: var(--pk-color-rose-600, #e11d48);\n }\n\n /* Host-driven catalog warm — spinner only (no loading copy). */\n .loading {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-height: 6rem;\n padding: 1.25rem 0.75rem;\n color: var(--pk-color-gray-500);\n }\n\n .panel-input:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n /* Host is inert layout chrome; the floating tip lives in pk-popup. */\n .option-tooltip {\n position: absolute;\n width: 0;\n height: 0;\n margin: 0;\n padding: 0;\n overflow: hidden;\n pointer-events: none;\n }\n }\n `,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { chevronDown, xmark, renderIconHtml } from '../../icons/index.js';\nimport { LiveRegion, uniqueId } from '../../a11y/focus.js';\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { scrollIntoView } from '../../a11y/scroll-lock.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { PkClearEvent } from '../../events/pk-clear.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\nimport { MirrorValidator, RequiredValidator } from '../../validators/index.js';\nimport { isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport '../spinner/pk-spinner.js';\nimport '../tooltip/pk-tooltip.js';\nimport type { PkTooltip } from '../tooltip/pk-tooltip.js';\nimport { pkImageBrowserStyles } from './pk-image-browser.styles.js';\n\nexport type PkImageBrowserSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\n\n/** Grid preview kind — compact glyphs vs larger photo tiles. */\nexport type PkImageBrowserMode = 'icon' | 'image';\n\n/**\n * How option names appear in the grid.\n * - `tooltip` (default) — shared `pk-tooltip` on hover; `aria-label` always\n * - `inline` — caption under each cell\n * - `none` — `aria-label` only (no tooltip, no caption)\n *\n * Named `labelMode` (not `labels`) to avoid clashing with the native\n * form-associated `HTMLElement.labels` NodeList getter.\n */\nexport type PkImageBrowserLabelMode = 'tooltip' | 'inline' | 'none';\n\nexport type PkImageBrowserWidth = 'auto' | 'full';\n\n/**\n * One browsable entry. Plugins own filtering / filesystem scanning and pass\n * already-resolved preview URLs or inline SVG markup.\n */\nexport type PkImageBrowserItem = {\n value: string;\n label: string;\n /** Public URL for `<img>`, or inline `<svg>…</svg>` markup. */\n preview?: string;\n};\n\nexport type PkImageBrowserGroup = {\n name: string;\n items: PkImageBrowserItem[];\n};\n\nconst CHEVRON_ICON = renderIconHtml(chevronDown);\nconst XMARK_ICON = renderIconHtml(xmark);\n\n/** How many matched items per group are painted before scroll reveals more. */\nconst DEFAULT_PAGE_SIZE = 96;\n\nfunction isInlineSvg(preview: string): boolean {\n return /^\\s*<svg[\\s>]/i.test(preview);\n}\n\n/**\n * Image browser — presentational picker for static filesystem icons/images.\n *\n * Plugins supply `items` / `groups` (and optional `selected-label` /\n * `selected-preview` for the closed trigger before the catalog is ready). The\n * kit does not scan disks or filter extensions.\n *\n * Keyboard: trigger opens with Enter / Space / ArrowDown; search owns focus with\n * `aria-activedescendant`; arrows move the highlight (2D in the grid); Enter\n * selects; Escape closes.\n *\n * @csspart root - Filled control chrome (trigger + clear + chevron)\n * @csspart trigger - Opens the panel (preview + label)\n * @csspart clear-button - Clear selection button (inside the control)\n * @csspart panel - Popup panel shell\n * @csspart panel-search - Search field container\n * @csspart panel-input - Search input\n * @csspart panel-body - Scrollable results region\n * @csspart loading - Catalog-loading status region (spinner)\n * @csspart option - Grid cell button\n *\n * @dependency pk-popup - Positioned panel host.\n * @dependency pk-spinner - Shown in the panel while `loading` is set.\n * @dependency pk-tooltip - Hover label when `label-mode=\"tooltip\"`.\n */\n@customElement('pk-image-browser')\nexport class PkImageBrowser extends PkFormAssociatedElement {\n static override styles = pkImageBrowserStyles;\n\n static override get validators() {\n return [...super.validators, MirrorValidator(), RequiredValidator()];\n }\n\n override assumeInteractionOn = ['pk-change'];\n\n @property({ reflect: true })\n size: PkImageBrowserSize = 'default';\n\n /** `icon` = compact glyph tiles; `image` = larger photo tiles. */\n @property({ reflect: true })\n mode: PkImageBrowserMode = 'icon';\n\n @property({ reflect: true })\n width: PkImageBrowserWidth = 'auto';\n\n /**\n * How option names appear in the grid: `tooltip` (default), `inline` under\n * each cell, or `none` (`aria-label` only).\n */\n @property({ reflect: true, attribute: 'label-mode' })\n labelMode: PkImageBrowserLabelMode = 'tooltip';\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property()\n value = '';\n\n @property({ attribute: 'default-value' })\n defaultValue = '';\n\n @property()\n placeholder = 'Choose…';\n\n @property({ attribute: 'search-placeholder' })\n searchPlaceholder = 'Search…';\n\n @property({ attribute: 'empty-message' })\n emptyMessage = 'No items match your query.';\n\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n /**\n * Host-driven catalog warm / refresh. Shows a centered `pk-spinner` in the\n * panel (no loading copy). Prefer this over inferring from empty `items` /\n * `groups` — empty can also mean a filter miss or a genuinely empty catalog.\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** Show a clear control when a value is selected. */\n @property({ type: Boolean, reflect: true, attribute: 'with-clear' })\n withClear = true;\n\n @property({ attribute: false })\n items: PkImageBrowserItem[] = [];\n\n @property({ attribute: false })\n groups: PkImageBrowserGroup[] = [];\n\n /**\n * Closed-trigger label when `value` is set but not yet found in `items` /\n * `groups` (e.g. catalog still loading).\n */\n @property({ attribute: 'selected-label' })\n selectedLabel = '';\n\n /** Closed-trigger preview for the same pre-catalog case as `selected-label`. */\n @property({ attribute: 'selected-preview' })\n selectedPreview = '';\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom-start';\n\n @property({ type: Number, attribute: 'side-offset' })\n sideOffset = 4;\n\n /** Items drawn per group before scroll reveals the next page. */\n @property({ type: Number, attribute: 'page-size' })\n pageSize = DEFAULT_PAGE_SIZE;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @state()\n private query = '';\n\n /** Render budget shared across groups — raised by scrolling, reset on query/open. */\n @state()\n private limit = DEFAULT_PAGE_SIZE;\n\n @state()\n private closing = false;\n\n @state()\n private panelAnimated = false;\n\n /** Flat index into `flatVisibleItems()` for aria-activedescendant navigation. */\n @state()\n private highlightedIndex = -1;\n\n /** Shared hover tooltip target when `labelMode=\"tooltip\"`. */\n @state()\n private tooltipFor = '';\n\n @state()\n private tooltipContent = '';\n\n @query('.value-input')\n override input!: HTMLInputElement;\n\n @query('.trigger')\n private triggerElement!: HTMLButtonElement;\n\n @query('.control')\n private controlElement!: HTMLDivElement;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n @query('.panel')\n private panelElement!: HTMLDivElement;\n\n @query('.panel-input')\n private searchInput!: HTMLInputElement | null;\n\n @query('.panel-body')\n private panelBody!: HTMLDivElement | null;\n\n @query('.option-tooltip')\n private optionTooltip!: PkTooltip | null;\n\n private readonly listboxId = uniqueId('pk-image-browser-listbox');\n private readonly searchId = uniqueId('pk-image-browser-search');\n private closeTimer: number | null = null;\n private tooltipOpenTimer: number | null = null;\n private liveRegion: LiveRegion | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.limit = this.normalizedPageSize();\n }\n\n override disconnectedCallback(): void {\n this.teardownDismissListeners();\n this.clearCloseTimer();\n this.clearTooltipOpenTimer();\n this.liveRegion?.destroy();\n this.liveRegion = null;\n super.disconnectedCallback();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has('pageSize') && !this.open) {\n this.limit = this.normalizedPageSize();\n }\n\n super.willUpdate(changed);\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (changed.has('open')) {\n if (this.open) {\n this.attachDismissListeners();\n } else if (!this.closing) {\n this.teardownDismissListeners();\n }\n }\n\n if ((changed.has('open') || changed.has('closing')) && (this.open || this.closing)) {\n void this.syncPanelPlacement();\n }\n\n if (this.open && (changed.has('highlightedIndex') || changed.has('query') || changed.has('limit'))) {\n this.scrollHighlightedIntoView();\n }\n\n // Catalog arrived while the panel is open — seat highlight on selection / first cell.\n if (this.open && changed.has('loading') && !this.loading) {\n this.resetHighlightForOpenCatalog();\n }\n }\n\n protected override get validationTarget(): HTMLElement {\n return this.triggerElement ?? this;\n }\n\n protected override syncFormValue(): void {\n this.setFormValue(this.value, this.value);\n }\n\n protected override resetToDefaultValue(): void {\n this.value = this.defaultValue;\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n }\n }\n\n async show(): Promise<void> {\n if (this.open || this.closing || this.disabled || this.readonly) {\n return;\n }\n\n await this.openPanel();\n }\n\n async hide(source: PkOverlaySource = 'api'): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n await this.closePanel(source);\n }\n\n private optionId(index: number): string {\n return `${this.listboxId}-opt-${index}`;\n }\n\n private groupHeadingId(groupIndex: number): string {\n return `${this.listboxId}-group-${groupIndex}`;\n }\n\n private normalizedPageSize(): number {\n return this.pageSize > 0 ? this.pageSize : DEFAULT_PAGE_SIZE;\n }\n\n private resolveGroups(): PkImageBrowserGroup[] {\n if (this.groups.length > 0) {\n return this.groups;\n }\n\n if (this.items.length > 0) {\n return [{ name: '', items: this.items }];\n }\n\n return [];\n }\n\n private findItem(value: string): PkImageBrowserItem | null {\n if (value === '') {\n return null;\n }\n\n for (const group of this.resolveGroups()) {\n const found = group.items.find((item) => item.value === value);\n if (found) {\n return found;\n }\n }\n\n return null;\n }\n\n private selectedItem(): PkImageBrowserItem | null {\n return this.findItem(this.value);\n }\n\n private triggerDisplay(): { label: string; preview?: string; isPlaceholder: boolean } {\n const selected = this.selectedItem();\n if (selected) {\n return {\n label: selected.label,\n preview: selected.preview,\n isPlaceholder: false,\n };\n }\n\n if (this.value !== '') {\n return {\n label: this.selectedLabel || this.value,\n preview: this.selectedPreview || undefined,\n isPlaceholder: false,\n };\n }\n\n return {\n label: this.placeholder,\n isPlaceholder: true,\n };\n }\n\n /** Groups matching the query, each truncated to the current render budget. */\n private visibleGroups(): Array<PkImageBrowserGroup & { total: number }> {\n const query = this.query.trim().toLowerCase();\n\n return this.resolveGroups().reduce<Array<PkImageBrowserGroup & { total: number }>>((acc, group) => {\n const matched = query === ''\n ? group.items\n : group.items.filter((item) => (\n item.label.toLowerCase().includes(query)\n || item.value.toLowerCase().includes(query)\n ));\n\n if (matched.length === 0) {\n return acc;\n }\n\n acc.push({\n name: group.name,\n total: matched.length,\n items: matched.slice(0, this.limit),\n });\n return acc;\n }, []);\n }\n\n private flatVisibleItems(): PkImageBrowserItem[] {\n return this.visibleGroups().flatMap((group) => group.items);\n }\n\n private isTruncated(): boolean {\n return this.visibleGroups().some((group) => group.items.length < group.total);\n }\n\n private activeDescendantId(): string | null {\n if (!this.open || this.highlightedIndex < 0) {\n return null;\n }\n\n return this.optionId(this.highlightedIndex);\n }\n\n private triggerAccessibleName(): string {\n if (this.ariaLabel) {\n const display = this.triggerDisplay();\n if (display.isPlaceholder) {\n return this.ariaLabel;\n }\n return `${this.ariaLabel}, ${display.label}`;\n }\n\n return this.triggerDisplay().label;\n }\n\n private announceResults(): void {\n // Skip while the host is still warming — empty would read as \"no matches\".\n if (this.loading) {\n return;\n }\n\n const items = this.flatVisibleItems();\n const filter = this.query.trim();\n\n if (!filter) {\n return;\n }\n\n if (!this.liveRegion) {\n this.liveRegion = new LiveRegion('polite');\n }\n\n this.liveRegion.announce(\n items.length === 0\n ? this.emptyMessage\n : `${items.length} ${items.length === 1 ? 'result' : 'results'} available`,\n );\n }\n\n private resetHighlightForOpenCatalog(): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const selectedIdx = items.findIndex((item) => item.value === this.value);\n this.highlightedIndex = selectedIdx >= 0 ? selectedIdx : 0;\n }\n\n private setHighlightedIndex(index: number): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const next = Math.max(0, Math.min(index, items.length - 1));\n this.highlightedIndex = next;\n\n // Navigating near the end of a truncated catalog should reveal more, same as scroll.\n if (next >= items.length - 4 && this.isTruncated()) {\n this.limit += this.normalizedPageSize();\n }\n }\n\n private scrollHighlightedIntoView(): void {\n if (this.highlightedIndex < 0 || !this.panelBody) {\n return;\n }\n\n const option = this.renderRoot.querySelector<HTMLElement>(\n `#${CSS.escape(this.optionId(this.highlightedIndex))}`,\n );\n if (!option) {\n return;\n }\n\n scrollIntoView(option, this.panelBody, 'vertical', 'auto');\n }\n\n /** Column count of the CSS grid that owns the highlighted option (for 2D arrows). */\n private columnCountNear(index: number): number {\n const option = this.renderRoot.querySelector<HTMLElement>(\n `#${CSS.escape(this.optionId(index))}`,\n );\n const grid = option?.closest('.grid');\n if (!grid) {\n return 1;\n }\n\n const options = [...grid.querySelectorAll<HTMLElement>('.option')];\n if (options.length === 0) {\n return 1;\n }\n\n const firstTop = options[0]!.offsetTop;\n let cols = 0;\n for (const candidate of options) {\n if (candidate.offsetTop !== firstTop) {\n break;\n }\n cols += 1;\n }\n\n return Math.max(1, cols);\n }\n\n private moveHighlight(key: string): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n let next = this.highlightedIndex;\n\n if (next < 0) {\n next = (key === 'ArrowUp' || key === 'ArrowLeft' || key === 'End')\n ? items.length - 1\n : 0;\n this.setHighlightedIndex(next);\n return;\n }\n\n const cols = this.columnCountNear(next);\n\n switch (key) {\n case 'ArrowRight':\n next = Math.min(next + 1, items.length - 1);\n break;\n case 'ArrowLeft':\n next = Math.max(next - 1, 0);\n break;\n case 'ArrowDown':\n next = Math.min(next + cols, items.length - 1);\n break;\n case 'ArrowUp':\n next = Math.max(next - cols, 0);\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = items.length - 1;\n break;\n default:\n return;\n }\n\n this.setHighlightedIndex(next);\n }\n\n private emitChange(next: string): void {\n this.value = next;\n this.syncFormValue();\n this.updateValidity();\n\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: next },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private selectValue(next: string): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n const previous = this.value;\n void this.closePanel('api');\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.highlightedIndex = -1;\n\n // Re-clicking the active option clears it (same as the trigger clear control).\n if (previous === next) {\n if (this.withClear && previous !== '') {\n this.emitChange('');\n this.dispatchEvent(new PkClearEvent());\n }\n return;\n }\n\n this.emitChange(next);\n }\n\n private handleClear = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.disabled || this.readonly || this.value === '') {\n return;\n }\n\n this.emitChange('');\n this.dispatchEvent(new PkClearEvent());\n this.triggerElement?.focus({ preventScroll: true });\n };\n\n private togglePanel = (event?: Event): void => {\n event?.preventDefault();\n event?.stopPropagation();\n\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (this.open || this.closing) {\n void this.closePanel('api');\n } else {\n void this.openPanel();\n }\n };\n\n private handleTriggerKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (\n event.key === 'ArrowDown'\n || event.key === 'ArrowUp'\n || event.key === 'Enter'\n || event.key === ' '\n ) {\n event.preventDefault();\n if (!this.open && !this.closing) {\n void this.openPanel();\n }\n }\n };\n\n private async openPanel(): Promise<void> {\n if (this.open || this.closing || this.disabled || this.readonly) {\n return;\n }\n\n this.dispatchEvent(new PkShowEvent());\n this.closing = false;\n this.panelAnimated = false;\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.open = true;\n this.resetHighlightForOpenCatalog();\n\n await this.updateComplete;\n await this.syncPanelPlacement();\n this.panelAnimated = true;\n this.dispatchEvent(new PkAfterShowEvent());\n await this.focusSearchWhenReady();\n this.scrollHighlightedIntoView();\n }\n\n private async closePanel(source: PkOverlaySource): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n this.dispatchEvent(hideEvent);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n this.closing = true;\n this.open = false;\n this.highlightedIndex = -1;\n this.clearOptionTooltip();\n this.teardownDismissListeners();\n this.triggerElement?.focus({ preventScroll: true });\n\n this.clearCloseTimer();\n this.closeTimer = window.setTimeout(() => {\n this.closing = false;\n this.panelAnimated = false;\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.closeTimer = null;\n this.dispatchEvent(new PkAfterHideEvent());\n }, 100);\n }\n\n private clearCloseTimer(): void {\n if (this.closeTimer != null) {\n window.clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private async syncPanelPlacement(): Promise<void> {\n if (!this.popupElement || !this.panelElement) {\n return;\n }\n\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n const placement = await waitForPopupReposition(this.popupElement, this.placement, 300, {\n requireEvent: true,\n });\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n private attachDismissListeners(): void {\n registerDismissible(this);\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private teardownDismissListeners(): void {\n unregisterDismissible(this);\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (!this.open || this.closing || !isTopDismissible(this)) {\n return;\n }\n\n if (isPointerInsideOverlay(event, {\n host: this,\n anchor: this.controlElement ?? this.triggerElement,\n panel: this.panelElement,\n })) {\n return;\n }\n\n void this.closePanel('pointer-dismiss');\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (!this.open || this.closing || !isTopDismissible(this)) {\n return;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n void this.closePanel('escape');\n }\n };\n\n private handleSearchInput = (event: Event): void => {\n if (this.loading) {\n return;\n }\n\n this.query = (event.target as HTMLInputElement).value;\n // New query = new set; don't keep a tall scroll budget from the previous browse.\n this.limit = this.normalizedPageSize();\n this.resetHighlightForOpenCatalog();\n this.announceResults();\n };\n\n private handleSearchKeyDown = (event: KeyboardEvent): void => {\n if (!this.open || this.closing || this.loading) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'ArrowLeft':\n case 'ArrowRight':\n case 'Home':\n case 'End':\n event.preventDefault();\n event.stopPropagation();\n this.moveHighlight(event.key);\n return;\n case 'Enter': {\n event.preventDefault();\n event.stopPropagation();\n const items = this.flatVisibleItems();\n const item = items[this.highlightedIndex];\n if (item) {\n this.selectValue(item.value);\n }\n return;\n }\n default:\n break;\n }\n };\n\n private handleResultsScroll = (): void => {\n // Tip can trail a scrolled-away cell; drop it and let hover re-open.\n this.clearOptionTooltip();\n\n const results = this.panelBody;\n if (!results || !this.isTruncated()) {\n return;\n }\n\n if (results.scrollTop + results.clientHeight < results.scrollHeight - 200) {\n return;\n }\n\n const anchor = results.scrollTop;\n this.limit += this.normalizedPageSize();\n void this.updateComplete.then(() => {\n if (this.panelBody) {\n this.panelBody.scrollTop = anchor;\n }\n });\n };\n\n private async focusSearchWhenReady(): Promise<void> {\n const started = performance.now();\n while (this.open && performance.now() - started < 2000) {\n const input = this.searchInput;\n if (input && getComputedStyle(input).visibility !== 'hidden') {\n input.focus({ preventScroll: true });\n if (document.activeElement === input) {\n return;\n }\n }\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n }\n }\n\n private renderPreview(preview: string | undefined, className: string) {\n if (!preview) {\n return nothing;\n }\n\n if (isInlineSvg(preview)) {\n return html`<span class=${className} aria-hidden=\"true\">${unsafeSVG(preview)}</span>`;\n }\n\n return html`<img class=${className} src=${preview} alt=\"\" />`;\n }\n\n private usesInlineLabels(): boolean {\n return this.labelMode === 'inline';\n }\n\n private usesTooltipLabels(): boolean {\n return this.labelMode === 'tooltip';\n }\n\n /** Hover caption via one shared tooltip — avoids N×pk-tooltip in large catalogs. */\n private showOptionTooltip(optionId: string, label: string): void {\n if (!this.usesTooltipLabels()) {\n return;\n }\n\n // Already tracking a cell → re-anchor immediately; first hover waits so scans don’t flash.\n const alreadyTracking = this.tooltipFor !== '';\n this.tooltipFor = optionId;\n this.tooltipContent = label;\n this.clearTooltipOpenTimer();\n\n const openNow = (): void => {\n this.tooltipOpenTimer = null;\n void this.updateComplete.then(() => {\n void this.optionTooltip?.show();\n });\n };\n\n if (alreadyTracking) {\n openNow();\n return;\n }\n\n this.tooltipOpenTimer = window.setTimeout(openNow, 280);\n }\n\n private clearOptionTooltip(): void {\n this.clearTooltipOpenTimer();\n this.tooltipFor = '';\n this.tooltipContent = '';\n void this.optionTooltip?.hide();\n }\n\n private clearTooltipOpenTimer(): void {\n if (this.tooltipOpenTimer != null) {\n window.clearTimeout(this.tooltipOpenTimer);\n this.tooltipOpenTimer = null;\n }\n }\n\n private handleOptionPointerEnter(index: number, label: string): void {\n this.highlightedIndex = index;\n this.showOptionTooltip(this.optionId(index), label);\n }\n\n private handleOptionPointerLeave = (event: MouseEvent): void => {\n const next = event.relatedTarget;\n const movingToNeighbor = next instanceof Node\n && this.panelBody?.contains(next)\n && Boolean(\n next instanceof Element\n ? next.closest('.option')\n : next.parentElement?.closest('.option'),\n );\n\n if (movingToNeighbor) {\n return;\n }\n\n // Leave the grid — drop sticky hover chrome back onto the selected cell (or none).\n this.resetHighlightToSelected();\n this.clearOptionTooltip();\n };\n\n private resetHighlightToSelected(): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const selectedIdx = items.findIndex((item) => item.value === this.value);\n this.highlightedIndex = selectedIdx;\n }\n\n private renderTriggerContents() {\n const display = this.triggerDisplay();\n\n return html`\n <span class=\"trigger-main\">\n ${this.renderPreview(display.preview, 'trigger-preview')}\n <span\n class=${classMap({\n 'trigger-label': true,\n 'is-placeholder': display.isPlaceholder,\n })}\n aria-hidden=\"true\"\n >${display.label}</span>\n </span>\n `;\n }\n\n private renderResults() {\n if (this.loading) {\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n aria-busy=\"true\"\n >\n <div part=\"loading\" class=\"loading\" role=\"status\" aria-label=\"Loading\">\n <pk-spinner size=\"sm\" centered></pk-spinner>\n </div>\n </div>\n `;\n }\n\n const groups = this.visibleGroups();\n\n if (groups.length === 0) {\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n >\n <p class=\"notice\" part=\"empty\" role=\"status\">${this.emptyMessage}</p>\n </div>\n `;\n }\n\n let flatIndex = 0;\n\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n >\n ${groups.map((group, groupIndex) => {\n const headingId = this.groupHeadingId(groupIndex);\n const groupStart = flatIndex;\n\n const options = group.items.map((item, itemIndex) => {\n const index = groupStart + itemIndex;\n flatIndex = index + 1;\n const selected = item.value === this.value;\n const highlighted = index === this.highlightedIndex;\n\n return html`\n <button\n type=\"button\"\n part=\"option\"\n id=${this.optionId(index)}\n class=${classMap({\n option: true,\n 'is-highlighted': highlighted,\n 'is-selected': selected,\n })}\n role=\"option\"\n tabindex=\"-1\"\n aria-label=${item.label}\n aria-selected=${selected ? 'true' : 'false'}\n @click=${() => this.selectValue(item.value)}\n @mouseenter=${() => this.handleOptionPointerEnter(index, item.label)}\n @mouseleave=${this.handleOptionPointerLeave}\n >\n ${this.renderPreview(item.preview, 'option-preview')}\n ${this.usesInlineLabels()\n ? html`<span class=\"option-label\" aria-hidden=\"true\">${item.label}</span>`\n : nothing}\n </button>\n `;\n });\n\n return html`\n <div\n class=\"group\"\n role=${group.name ? 'group' : nothing}\n aria-labelledby=${group.name ? headingId : nothing}\n >\n ${group.name\n ? html`\n <h6 class=\"group-heading\" id=${headingId}>\n <span>${group.name}</span>\n ${group.items.length < group.total\n ? html`\n <span class=\"group-heading-count\">\n Showing ${group.items.length} of ${group.total}\n </span>\n `\n : nothing}\n </h6>\n `\n : nothing}\n <div class=\"grid\">\n ${options}\n </div>\n </div>\n `;\n })}\n </div>\n `;\n }\n\n override render() {\n const showClear = this.withClear && this.value !== '' && !this.disabled && !this.readonly;\n const panelActive = this.open || this.closing;\n const activeDescendant = this.activeDescendantId();\n\n return html`\n <input\n class=\"value-input\"\n part=\"value-input\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n .value=${this.value}\n ?required=${this.required}\n @input=${() => this.updateValidity()}\n />\n <div\n part=\"root\"\n class=${classMap({\n control: true,\n 'is-disabled': this.disabled || this.readonly,\n 'is-open': this.open,\n })}\n >\n <button\n type=\"button\"\n part=\"trigger\"\n class=\"trigger\"\n ?disabled=${this.disabled || this.readonly}\n aria-label=${this.triggerAccessibleName()}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n @click=${this.togglePanel}\n @keydown=${this.handleTriggerKeyDown}\n >\n ${this.renderTriggerContents()}\n </button>\n ${showClear\n ? html`\n <button\n type=\"button\"\n part=\"clear-button\"\n class=\"clear-button\"\n aria-label=\"Clear selection\"\n ?disabled=${this.disabled}\n @click=${this.handleClear}\n >\n <span class=\"clear-button-icon\" aria-hidden=\"true\">${unsafeSVG(XMARK_ICON)}</span>\n </button>\n `\n : nothing}\n <button\n type=\"button\"\n class=\"expand-button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n ?disabled=${this.disabled || this.readonly}\n @click=${this.togglePanel}\n >\n <span class=\"expand-button-icon\">${unsafeSVG(CHEVRON_ICON)}</span>\n </button>\n </div>\n <pk-popup\n .active=${panelActive}\n .anchor=${this.controlElement ?? this.triggerElement ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n tabindex=\"-1\"\n ?hidden=${!panelActive}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n >\n <div part=\"panel-search\" class=\"panel-search\">\n <input\n part=\"panel-input\"\n class=\"panel-input\"\n id=${this.searchId}\n type=\"text\"\n role=\"combobox\"\n .value=${this.query}\n placeholder=${this.searchPlaceholder}\n aria-label=${this.searchPlaceholder}\n aria-autocomplete=\"list\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n aria-activedescendant=${activeDescendant ?? nothing}\n ?disabled=${this.loading}\n @input=${this.handleSearchInput}\n @keydown=${this.handleSearchKeyDown}\n />\n </div>\n <div\n part=\"panel-body\"\n class=\"panel-body\"\n @scroll=${this.handleResultsScroll}\n >\n ${this.renderResults()}\n </div>\n ${this.usesTooltipLabels() && panelActive\n ? html`\n <pk-tooltip\n class=\"option-tooltip\"\n for=${this.tooltipFor}\n content=${this.tooltipContent}\n placement=\"top\"\n trigger=\"manual\"\n ></pk-tooltip>\n `\n : nothing}\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-image-browser': PkImageBrowser;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pk-popover-KSIOYlbs.js","names":[],"sources":["../../src/components/popover/pk-popover.styles.ts","../../src/components/popover/pk-popover.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { buttonGroupCornerRoleStyles } from '../button-group/button-group-item.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\nexport const pkPopoverStyles = [\n buttonGroupCornerRoleStyles(),\n popupContentAnimationStyles,\n css`\n @layer pk-component {\n :host {\n /* Flex column parents stretch cross-axis size — pin to content.\n (inline-block + align-self; same class of fix as dialog / dropdown.) */\n display: inline-block;\n max-width: 100%;\n align-self: flex-start;\n flex: none;\n vertical-align: middle;\n }\n\n :host([data-pk-group-orientation]) {\n display: inline-flex;\n vertical-align: middle;\n flex: 0 0 auto;\n align-self: auto;\n }\n\n :host([data-pk-group-orientation]) ::slotted([slot='trigger']) {\n --pk-bg-start-start-radius: inherit;\n --pk-bg-start-end-radius: inherit;\n --pk-bg-end-start-radius: inherit;\n --pk-bg-end-end-radius: inherit;\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]) {\n margin-inline-start: var(--pk-bg-horizontal-indent, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]) {\n margin-block-start: var(--pk-bg-vertical-indent, 0);\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-inline-start: var(--pk-bg-horizontal-indent-outlined, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-block-start: var(--pk-bg-vertical-indent-outlined, 0);\n }\n\n /* Match pk-popup's arrow fill to the panel surface when with-arrow is on. */\n :host([with-arrow]) {\n --pk-popup-arrow-color: var(--pk-color-white);\n --pk-popup-arrow-size: 8px;\n }\n\n .panel {\n box-sizing: border-box;\n width: 18rem;\n padding: 1rem;\n border-radius: var(--pk-radius-md);\n background: var(--pk-color-white);\n box-shadow: var(--pk-shadow-popover);\n /* Craft CP body text (~gray-700), not gray-900. */\n color: var(--pk-color-gray-700);\n }\n\n /* Flush panels for command/menu chrome that owns its own inset (variable picker, etc.).\n Match kit v1 PopoverContent min-w 260px / max-w 360px: without min-width,\n width max-content shrinks to short labels and looks narrower than the old picker. */\n :host([flush]) .panel {\n width: max-content;\n min-width: var(--pk-popover-flush-min-width, 16.25rem);\n max-width: min(var(--pk-popover-flush-max-width, 22.5rem), 100vw - 1rem);\n padding: 0;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n }\n `,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { resolveElementById } from '../../internal/resolve-element-by-id.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\nimport { isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport { pkPopoverStyles } from './pk-popover.styles.js';\n\n/**\n * Popover — pattern: trigger toggles a floating panel.\n *\n * @slot trigger - Popover trigger\n * @slot - Popover content\n *\n * @csspart panel - Floating content panel\n *\n * @attr with-arrow - Show a pointing arrow toward the trigger (default: off)\n */\n@customElement('pk-popover')\nexport class PkPopover extends PkElement {\n static override styles = pkPopoverStyles;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom';\n\n @property({ attribute: 'side-offset', type: Number })\n sideOffset = 4;\n\n /**\n * Drop default panel padding/fixed width so slotted chrome (command lists, etc.)\n * can control its own inset. Consumer outer `p-0` alone cannot reach `.panel`.\n */\n @property({ type: Boolean, reflect: true })\n flush = false;\n\n /**\n * Show a floating-ui arrow on the panel (off by default).\n * Named like other optional chrome (`with-clear`, `with-caret`) — tooltip always\n * paints its own arrow and has no toggle.\n */\n @property({ attribute: 'with-arrow', type: Boolean, reflect: true })\n withArrow = false;\n\n /** Anchor element id — alternative to the trigger slot. */\n @property({ reflect: true })\n for = '';\n\n /**\n * Live element anchor — use when the target lives in another shadow tree\n * (e.g. TipTap chips). Preferred over `for` / trigger slot when set.\n * Stays in the consumer tree so modal `showModal()` inert does not apply\n * (unlike portaling the panel to a root outside the dialog).\n */\n @property({ attribute: false })\n anchor: Element | null = null;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n private get panelElement(): HTMLDivElement | null {\n return this.popupElement?.getContentElement() as HTMLDivElement | null ?? null;\n }\n\n @state()\n private triggerElement: HTMLElement | null = null;\n\n /** True while the shared popup-content exit animation is running. */\n @state()\n private closing = false;\n\n /** Gates `data-open` so enter motion starts after Floating UI places the panel. */\n @state()\n private panelAnimated = false;\n\n private readonly triggerId = uniqueId('pk-popover-trigger');\n private dismissRegistered = false;\n /** Guard re-entry while openPopover/closePopover mutate `open`. */\n private syncingOpenSideEffects = false;\n /** Coalesce overlapping close calls (updated + light-dismiss) onto one exit. */\n private exitAnimationPromise: Promise<void> | null = null;\n\n override disconnectedCallback(): void {\n // Skip exit motion on teardown — demote immediately.\n void this.closePopover('api', true);\n super.disconnectedCallback();\n }\n\n /**\n * When controlled/toggle `open` flips false, arm `closing` in the same update so the\n * panel is not `hidden` for a frame before the exit animation starts.\n */\n override willUpdate(changed: PropertyValues): void {\n if (\n changed.has('open')\n && this.open === false\n && changed.get('open') === true\n && !this.syncingOpenSideEffects\n && !this.closing\n ) {\n this.closing = true;\n this.panelAnimated = false;\n }\n }\n\n /**\n * Controlled `open` (e.g. React) must arm/disarm light-dismiss the same way as\n * trigger toggles. Without this, programmatic open shows the panel but click-away\n * never fires.\n */\n override async updated(changed: PropertyValues): Promise<void> {\n super.updated(changed);\n\n if (!changed.has('open') || this.syncingOpenSideEffects) {\n return;\n }\n\n const previousOpen = changed.get('open');\n\n if (previousOpen === this.open) {\n return;\n }\n\n // Initial connect with open=false — nothing to tear down.\n if (previousOpen === undefined && this.open === false) {\n return;\n }\n\n if (this.open) {\n await this.openPopover();\n } else {\n await this.closePopover('api');\n }\n }\n\n private onTriggerSlotChange(event: Event): void {\n const slot = event.target as HTMLSlotElement;\n const [trigger] = slot.assignedElements({ flatten: true }) as HTMLElement[];\n\n this.unbindTrigger(this.triggerElement);\n this.triggerElement = trigger ?? null;\n this.bindTrigger(this.triggerElement);\n }\n\n private bindTrigger(trigger: HTMLElement | null): void {\n if (!trigger) {\n return;\n }\n\n if (!trigger.id) {\n trigger.id = this.triggerId;\n }\n\n trigger.setAttribute('aria-haspopup', 'dialog');\n trigger.addEventListener('click', this.handleToggleClick);\n this.syncExpanded();\n }\n\n private unbindTrigger(trigger: HTMLElement | null): void {\n trigger?.removeEventListener('click', this.handleToggleClick);\n }\n\n private handleToggleClick = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.closing) {\n return;\n }\n\n // Flip `open` only — side effects run from `updated()` (same as dropdown-menu).\n this.open = !this.open;\n };\n\n private async openPopover(): Promise<void> {\n if (!this.getAnchor()) {\n return;\n }\n\n // Finish any in-flight exit before arming a new open.\n if (this.exitAnimationPromise) {\n await this.exitAnimationPromise;\n }\n\n // Already armed from a prior controlled/toggle open.\n if (this.dismissRegistered && this.open) {\n if (this.panelElement) {\n this.panelElement.hidden = false;\n }\n this.syncExpanded();\n return;\n }\n\n if (!this.dispatchEvent(new PkShowEvent())) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n return;\n }\n\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = false;\n // Seed side before first paint so enter keyframes pick a direction.\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n }\n\n this.syncExpanded();\n this.registerDismissHandlers();\n\n await this.updateComplete;\n const placement = await waitForPopupReposition(this.popupElement, this.placement);\n\n if (this.panelElement) {\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n // Flip data-open after placement so the shared enter animation can run.\n this.panelAnimated = true;\n\n this.dispatchEvent(new PkAfterShowEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: true },\n bubbles: true,\n composed: true,\n }));\n }\n\n /**\n * @param immediate Skip exit animation (disconnect / forced teardown).\n */\n async closePopover(source: PkOverlaySource = 'unknown', immediate = false): Promise<void> {\n if (this.exitAnimationPromise) {\n return this.exitAnimationPromise;\n }\n\n if (!this.dismissRegistered && !this.closing && !this.open) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n\n if (!this.dispatchEvent(hideEvent)) {\n // Controlled close was cancelled — restore open and cancel exit arming.\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = true;\n return;\n }\n\n this.unregisterDismissHandlers();\n this.closing = true;\n this.panelAnimated = false;\n\n if (this.open) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n }\n\n const finishClose = async (): Promise<void> => {\n if (!immediate) {\n await this.updateComplete;\n await this.waitForExitAnimation();\n }\n\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = true;\n this.panelElement.removeAttribute('data-side');\n }\n\n this.syncExpanded();\n\n this.dispatchEvent(new PkAfterHideEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: false },\n bubbles: true,\n composed: true,\n }));\n };\n\n this.exitAnimationPromise = finishClose().finally(() => {\n this.exitAnimationPromise = null;\n });\n\n return this.exitAnimationPromise;\n }\n\n private waitForExitAnimation(): Promise<void> {\n const panel = this.panelElement;\n\n if (!panel) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n let settled = false;\n\n const finish = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n panel.removeEventListener('animationend', onAnimationEnd);\n window.clearTimeout(fallback);\n panel.classList.remove('closing');\n resolve();\n };\n\n const onAnimationEnd = (event: AnimationEvent): void => {\n if (event.target === panel && event.animationName.startsWith('pk-popup-content-out')) {\n finish();\n }\n };\n\n panel.classList.add('closing');\n panel.addEventListener('animationend', onAnimationEnd);\n const fallback = window.setTimeout(finish, 150);\n });\n }\n\n private getAnchor(): Element | string | null {\n if (this.anchor) {\n return this.anchor;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n return null;\n }\n\n private registerDismissHandlers(): void {\n if (this.dismissRegistered) {\n return;\n }\n\n registerDismissible(this);\n this.dismissRegistered = true;\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private unregisterDismissHandlers(): void {\n if (this.dismissRegistered) {\n unregisterDismissible(this);\n this.dismissRegistered = false;\n }\n\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (this.isPointerInside(event) || this.closing) {\n return;\n }\n\n void this.closePopover('light-dismiss');\n };\n\n private isPointerInside(event: PointerEvent): boolean {\n return isPointerInsideOverlay(event, {\n host: this,\n anchor: this.getAnchorElement(),\n panel: this.panelElement,\n });\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape' || !isTopDismissible(this) || this.closing) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n void this.closePopover('escape');\n };\n\n private getAnchorElement(): HTMLElement | null {\n if (this.anchor instanceof HTMLElement) {\n return this.anchor;\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n return null;\n }\n\n private syncExpanded(): void {\n this.triggerElement?.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n\n override render() {\n const anchor = this.getAnchor();\n\n return html`\n <slot name=\"trigger\" @slotchange=${this.onTriggerSlotChange}></slot>\n <pk-popup\n .active=${this.open || this.closing}\n .anchor=${anchor ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n .arrow=${this.withArrow}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n ?hidden=${!this.open && !this.closing}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n tabindex=${this.open ? '-1' : nothing}\n >\n <slot></slot>\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-popover': PkPopover;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pk-popup-B9AgBC2V.js","names":[],"sources":["../../src/internal/resolve-element-by-id.ts","../../src/events/pk-reposition.ts","../../src/components/popup/pk-popup.styles.ts","../../src/components/popup/pk-popup.ts"],"sourcesContent":["/** Resolve an element id from the same root as the host (shadow or document), then the document. */\nexport function resolveElementById(host: HTMLElement, id: string): HTMLElement | null {\n if (!id) {\n return null;\n }\n\n const root = host.getRootNode();\n\n if (root instanceof Document || root instanceof ShadowRoot) {\n const match = root.getElementById(id);\n\n if (match) {\n return match;\n }\n }\n\n return host.ownerDocument.getElementById(id);\n}\n","/** Emitted when a popup repositions — mirrors reposition semantics with pk naming. */\nexport class PkRepositionEvent extends Event {\n constructor() {\n super('pk-reposition', { bubbles: true, cancelable: false, composed: true });\n }\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'pk-reposition': PkRepositionEvent;\n }\n}\n","import { css } from 'lit';\n\nexport const pkPopupStyles = css`\n @layer pk-component {\n :host {\n display: contents;\n }\n\n .popup {\n position: absolute;\n isolation: isolate;\n width: max-content;\n z-index: var(--pk-popup-z-index, 1000);\n /* Never transition coordinates — flip would animate the jump. */\n transition: none;\n\n /* Reset UA styles for [popover] — see pk-popup. */\n inset: unset;\n padding: unset;\n margin: unset;\n height: unset;\n color: unset;\n background: unset;\n border: unset;\n overflow: unset;\n }\n\n .popup-fixed {\n position: fixed;\n }\n\n .popup:not(.active) {\n display: none;\n }\n\n /* Prefer visibility over opacity so enter animations are not fighting a\n * 0→1 fade. Matches base-ui isPositioned / hide-until-placed.\n */\n .popup.active:not(.positioned) {\n visibility: hidden;\n pointer-events: none;\n }\n\n .popup.show {\n animation: pk-popup-surface-in 100ms ease-out;\n }\n\n .popup.hide {\n animation: pk-popup-surface-out 100ms ease-in forwards;\n }\n\n @keyframes pk-popup-surface-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @keyframes pk-popup-surface-out {\n from {\n opacity: 1;\n transform: scale(1);\n }\n\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n }\n\n .arrow {\n position: absolute;\n width: var(--pk-popup-arrow-size, 6px);\n height: var(--pk-popup-arrow-size, 6px);\n rotate: 45deg;\n background: var(--pk-popup-arrow-color, var(--pk-color-white));\n z-index: 1;\n }\n\n .hover-bridge {\n position: fixed;\n z-index: calc(var(--pk-popup-z-index, 1000) - 1);\n inset: 0;\n clip-path: polygon(\n var(--pk-hover-bridge-top-left-x, 0) var(--pk-hover-bridge-top-left-y, 0),\n var(--pk-hover-bridge-top-right-x, 0) var(--pk-hover-bridge-top-right-y, 0),\n var(--pk-hover-bridge-bottom-right-x, 0) var(--pk-hover-bridge-bottom-right-y, 0),\n var(--pk-hover-bridge-bottom-left-x, 0) var(--pk-hover-bridge-bottom-left-y, 0)\n );\n pointer-events: auto;\n }\n\n .hover-bridge:not(.hover-bridge-visible) {\n display: none;\n }\n }\n`;\n","import {\n arrow,\n autoUpdate,\n computePosition,\n flip,\n getOverflowAncestors,\n offset,\n platform,\n shift,\n size,\n type Placement,\n} from '@floating-ui/dom';\nimport { offsetParent } from 'composed-offset-position';\nimport { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { PkElement } from '../../base/pk-element.js';\nimport { resolveElementById } from '../../internal/resolve-element-by-id.js';\nimport { PkRepositionEvent } from '../../events/pk-reposition.js';\nimport { computePopupTransformOrigin } from '../../utils/popup-placement-animation.js';\nimport { SUPPORTS_POPOVER } from '../../utils/supports-popover.js';\nimport { pkPopupStyles } from './pk-popup.styles.js';\n\nexport type PkPopupPlacement = Placement;\n\nexport type PkPopupVirtualElement = {\n getBoundingClientRect: () => DOMRect;\n contextElement?: Element;\n};\n\nfunction isVirtualElement(value: unknown): value is PkPopupVirtualElement {\n return (\n value !== null\n && typeof value === 'object'\n && 'getBoundingClientRect' in value\n );\n}\n\nfunction resolvePositionStrategy(\n positionMethod: 'fixed' | 'absolute' | undefined,\n): 'fixed' | 'absolute' {\n if (positionMethod) {\n return positionMethod;\n }\n\n // Top-layer popovers use absolute coords; legacy fallback uses fixed viewport coords.\n return SUPPORTS_POPOVER ? 'absolute' : 'fixed';\n}\n\nfunction resolveScrollBoundary(\n anchorElement: Element | PkPopupVirtualElement,\n boundary: 'viewport' | 'scroll',\n): Element[] | undefined {\n if (!SUPPORTS_POPOVER || isVirtualElement(anchorElement) || boundary !== 'scroll') {\n return undefined;\n }\n\n // Popover content leaves the anchor's overflow chain — pass ancestor bounds explicitly.\n return getOverflowAncestors(anchorElement).filter((node): node is Element => node instanceof Element);\n}\n\n/**\n * Anchors floating content to a reference element — popup pattern with pk naming.\n * When the Popover API is available, content stays in the component tree and is promoted to\n * the top layer via `popover=\"manual\"` + `showPopover()` (no DOM reparenting).\n *\n * @event pk-reposition - Emitted when the popup is repositioned.\n *\n * @slot - Popup content.\n * @slot anchor - Anchor element when it lives inside the popup host.\n *\n * @csspart popup - Floating container.\n * @csspart arrow - Arrow element.\n * @csspart hover-bridge - Invisible bridge between anchor and popup.\n */\n@customElement('pk-popup')\nexport class PkPopup extends PkElement {\n static override styles = pkPopupStyles;\n\n /** Element id, DOM reference, or virtual element to anchor against. */\n @property()\n anchor: Element | string | PkPopupVirtualElement = '';\n\n /** When true, positioning runs and the popup is shown. */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n /**\n * Floating UI positioning strategy.\n * Defaults to `absolute` when the Popover API is supported, otherwise `fixed`.\n */\n @property({ attribute: 'position-method' })\n positionMethod?: 'fixed' | 'absolute';\n\n /** Bounding box for flip/shift collision — `scroll` uses overflow ancestors when popover is active. */\n @property({ reflect: true })\n boundary: 'viewport' | 'scroll' = 'viewport';\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom-start';\n\n @property({ type: Number })\n distance = 4;\n\n @property({ type: Number })\n skidding = 0;\n\n @property({ type: Boolean })\n flip = true;\n\n @property({ attribute: 'flip-fallback-placements' })\n flipFallbackPlacements = '';\n\n @property({ attribute: 'flip-fallback-strategy' })\n flipFallbackStrategy: 'best-fit' | 'initial' = 'best-fit';\n\n @property({ attribute: 'flip-padding', type: Number })\n flipPadding = 8;\n\n @property({ type: Boolean })\n shift = true;\n\n @property({ attribute: 'shift-padding', type: Number })\n shiftPadding = 8;\n\n @property({ type: Boolean })\n arrow = false;\n\n @property({ attribute: 'arrow-placement' })\n arrowPlacement: 'start' | 'end' | 'center' | 'anchor' = 'anchor';\n\n @property({ attribute: 'arrow-padding', type: Number })\n arrowPadding = 10;\n\n @property()\n sync?: 'width' | 'height' | 'both';\n\n /** When false, the popup is positioned once and not tracked on scroll/resize. */\n @property({ attribute: 'anchor-tracking', type: Boolean })\n anchorTracking = true;\n\n @property({ attribute: 'hover-bridge', type: Boolean })\n hoverBridge = false;\n\n @query('.popup')\n private popupElement?: HTMLElement;\n\n @query('.arrow')\n private arrowElement?: HTMLElement;\n\n private anchorElement: Element | PkPopupVirtualElement | null = null;\n private cleanup?: () => void;\n /** True while waiting for layout-stable coords before first paint. */\n private settlingInitialPosition = false;\n private settleGeneration = 0;\n\n override disconnectedCallback(): void {\n void this.stop();\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (changed.has('active')) {\n if (this.active) {\n this.resolveAnchor();\n this.start();\n } else {\n this.stop();\n }\n }\n\n if (changed.has('anchor')) {\n void this.handleAnchorChange();\n }\n\n if (this.active && !changed.has('active')) {\n this.reposition();\n }\n }\n\n /** Forces the popup to recalculate and reposition itself. */\n reposition(): void {\n if (this.settlingInitialPosition) {\n return;\n }\n\n void this.repositionAsync();\n }\n\n /**\n * Runs Floating UI once and applies coords. Does not reveal an unpositioned\n * popup — `settleInitialPosition()` owns the first paint.\n */\n private async repositionAsync(emitEvent = true): Promise<boolean> {\n const floatingElement = this.popupElement;\n const arrowTarget = this.arrow ? this.arrowElement : null;\n\n if (!this.active || !this.anchorElement || !floatingElement) {\n return false;\n }\n\n const scrollBoundary = resolveScrollBoundary(this.anchorElement, this.boundary);\n\n const middleware = [\n offset({ mainAxis: this.distance, crossAxis: this.skidding }),\n ];\n\n if (this.sync) {\n middleware.push(\n size({\n apply: ({ rects }) => {\n const syncWidth = this.sync === 'width' || this.sync === 'both';\n const syncHeight = this.sync === 'height' || this.sync === 'both';\n floatingElement.style.width = syncWidth ? `${rects.reference.width}px` : '';\n floatingElement.style.height = syncHeight ? `${rects.reference.height}px` : '';\n },\n }),\n );\n } else {\n floatingElement.style.width = '';\n floatingElement.style.height = '';\n }\n\n if (this.flip) {\n middleware.push(\n flip({\n boundary: scrollBoundary,\n fallbackPlacements: this.flipFallbackPlacements\n ? this.flipFallbackPlacements.split(' ').map((value) => value.trim()).filter(Boolean) as Placement[]\n : undefined,\n fallbackStrategy: this.flipFallbackStrategy === 'best-fit' ? 'bestFit' : 'initialPlacement',\n padding: this.flipPadding,\n }),\n );\n }\n\n if (this.shift) {\n middleware.push(\n shift({\n boundary: scrollBoundary,\n padding: this.shiftPadding,\n }),\n );\n }\n\n if (this.arrow && arrowTarget) {\n middleware.push(\n arrow({\n element: arrowTarget,\n padding: this.arrowPadding,\n }),\n );\n }\n\n const strategy = resolvePositionStrategy(this.positionMethod);\n const useFixedFallback = strategy === 'fixed';\n\n floatingElement.classList.toggle('popup-fixed', useFixedFallback);\n\n const getOffsetParentFn = SUPPORTS_POPOVER\n ? (element: Element) => platform.getOffsetParent(element, offsetParent)\n : platform.getOffsetParent;\n\n const { x, y, middlewareData, placement } = await computePosition(this.anchorElement, floatingElement, {\n placement: this.placement,\n middleware,\n strategy,\n platform: {\n ...platform,\n getOffsetParent: getOffsetParentFn,\n },\n });\n\n if (!this.active || !floatingElement.isConnected) {\n return false;\n }\n\n const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[\n placement.split('-')[0] as 'top' | 'right' | 'bottom' | 'left'\n ]!;\n\n this.setAttribute('data-current-placement', placement);\n\n Object.assign(floatingElement.style, {\n left: `${x}px`,\n top: `${y}px`,\n ...(useFixedFallback ? { position: 'fixed' } : { position: '' }),\n });\n\n if (this.anchorElement) {\n // Use viewport rects for both sides — computePosition x/y can be offset-parent\n // relative, and mixing that with getBoundingClientRect shifts transform-origin\n // sideways (menu appears to slide in from the right).\n const referenceRect = this.anchorElement.getBoundingClientRect();\n const floatingRect = floatingElement.getBoundingClientRect();\n\n floatingElement.style.setProperty('--pk-anchor-width', `${referenceRect.width}px`);\n floatingElement.style.setProperty('--pk-anchor-height', `${referenceRect.height}px`);\n\n const transformOrigin = computePopupTransformOrigin(\n placement,\n referenceRect,\n floatingRect,\n this.distance,\n middlewareData.shift,\n );\n\n floatingElement.style.setProperty('--pk-transform-origin', transformOrigin);\n }\n\n if (this.arrow && arrowTarget) {\n const arrowX = middlewareData.arrow?.x;\n const arrowY = middlewareData.arrow?.y;\n let top = '';\n let right = '';\n let bottom = '';\n let left = '';\n\n if (this.arrowPlacement === 'start') {\n const value = typeof arrowX === 'number' ? `${this.arrowPadding}px` : '';\n top = typeof arrowY === 'number' ? `${this.arrowPadding}px` : '';\n left = value;\n } else if (this.arrowPlacement === 'end') {\n right = typeof arrowX === 'number' ? `${this.arrowPadding}px` : '';\n bottom = typeof arrowY === 'number' ? `${this.arrowPadding}px` : '';\n } else if (this.arrowPlacement === 'center') {\n left = typeof arrowX === 'number' ? '50%' : '';\n top = typeof arrowY === 'number' ? '50%' : '';\n } else {\n left = typeof arrowX === 'number' ? `${arrowX}px` : '';\n top = typeof arrowY === 'number' ? `${arrowY}px` : '';\n }\n\n Object.assign(arrowTarget.style, {\n top,\n right,\n bottom,\n left,\n transform: '',\n [staticSide]: 'calc(-1 * var(--pk-popup-arrow-size, 6px) / 2)',\n });\n }\n\n requestAnimationFrame(() => this.updateHoverBridge());\n\n if (emitEvent) {\n this.dispatchEvent(new PkRepositionEvent());\n }\n\n return true;\n }\n\n private frames(count: number): Promise<void> {\n return new Promise((resolve) => {\n const step = (remaining: number): void => {\n if (remaining <= 0) {\n resolve();\n return;\n }\n\n requestAnimationFrame(() => step(remaining - 1));\n };\n\n step(count);\n });\n }\n\n /**\n * Hide → layout → measure → confirm flip → reveal.\n * A single computePosition often runs before slotted content has height, so flip\n * picks the preferred side; autoUpdate then jumps — that was the visible flash.\n */\n private async settleInitialPosition(): Promise<void> {\n const generation = ++this.settleGeneration;\n const floatingElement = this.popupElement;\n\n if (!floatingElement) {\n this.settlingInitialPosition = false;\n return;\n }\n\n // Two frames: display:none→block + slotted panel unhide need a layout pass.\n await this.frames(2);\n\n if (!this.active || generation !== this.settleGeneration) {\n return;\n }\n\n // Quiet passes — consumers waiting on pk-reposition should see the settled place.\n await this.repositionAsync(false);\n\n // Confirm after the first coords are applied (size middleware / content height).\n void floatingElement.offsetHeight;\n await this.frames(1);\n\n if (!this.active || generation !== this.settleGeneration) {\n return;\n }\n\n await this.repositionAsync(false);\n\n if (!this.active || generation !== this.settleGeneration) {\n return;\n }\n\n floatingElement.classList.add('positioned');\n this.settlingInitialPosition = false;\n requestAnimationFrame(() => this.updateHoverBridge());\n this.dispatchEvent(new PkRepositionEvent());\n }\n\n private resolveAnchor(): void {\n if (typeof this.anchor === 'string' && this.anchor) {\n this.anchorElement = resolveElementById(this, this.anchor);\n return;\n }\n\n if (this.anchor instanceof Element || isVirtualElement(this.anchor)) {\n this.anchorElement = this.anchor;\n return;\n }\n\n let slotted = this.querySelector('[slot=\"anchor\"]');\n\n if (slotted instanceof HTMLSlotElement) {\n slotted = slotted.assignedElements({ flatten: true })[0] ?? null;\n }\n\n this.anchorElement = slotted;\n }\n\n private async handleAnchorChange(): Promise<void> {\n await this.stop();\n this.resolveAnchor();\n\n if (this.anchorElement && this.active) {\n this.start();\n }\n }\n\n /** When false, skip popover top layer (e.g. menu/select use fixed coords to simplify modal handoff). */\n private usesPopoverTopLayer(): boolean {\n return SUPPORTS_POPOVER && this.positionMethod !== 'fixed';\n }\n\n /** `stop()` — sync hidePopover + cleanup autoUpdate. */\n stop(): Promise<void> {\n return new Promise((resolve) => {\n const popup = this.popupElement;\n this.settleGeneration += 1;\n this.settlingInitialPosition = false;\n popup?.classList.remove('positioned');\n\n if (this.usesPopoverTopLayer()) {\n popup?.hidePopover?.();\n }\n\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n popup?.style.removeProperty('--pk-transform-origin');\n requestAnimationFrame(() => resolve());\n } else {\n resolve();\n }\n\n // Always clear — even when autoUpdate never started — so the next open\n // cannot short-circuit waitForPopupReposition on a stale placement.\n this.removeAttribute('data-current-placement');\n });\n }\n\n /** @deprecated Prefer `stop()` — kept for select/combobox handoff call sites. */\n releasePositioning(): void {\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n }\n }\n\n /** @deprecated Prefer `stop()`. */\n async awaitHidden(): Promise<void> {\n await this.stop();\n }\n\n private start(): void {\n if (!this.anchorElement || !this.active || !this.isConnected || !this.popupElement) {\n return;\n }\n\n // Stay invisible until settleInitialPosition confirms flip with real content size.\n this.popupElement.classList.remove('positioned');\n this.settlingInitialPosition = true;\n\n if (this.usesPopoverTopLayer()) {\n this.popupElement.showPopover?.();\n }\n\n if (this.anchorTracking) {\n this.cleanup = autoUpdate(this.anchorElement, this.popupElement, () => {\n // Ignore the sync autoUpdate kick during settle — it races layout.\n if (this.settlingInitialPosition) {\n return;\n }\n\n this.reposition();\n });\n }\n\n void this.settleInitialPosition();\n }\n\n /** Slotted popup content root (e.g. `.panel`) — keeps content in-tree. */\n getContentElement(): HTMLElement | null {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n const assigned = slot?.assignedElements({ flatten: true }) ?? [];\n const slotted = assigned.find((node): node is HTMLElement => node instanceof HTMLElement);\n\n if (slotted) {\n return slotted;\n }\n\n for (const node of this.childNodes) {\n if (node instanceof HTMLElement && node.getAttribute('slot') !== 'anchor') {\n return node;\n }\n }\n\n return null;\n }\n\n private updateHoverBridge(): void {\n const floatingElement = this.popupElement;\n\n if (!this.hoverBridge || !this.anchorElement || !floatingElement) {\n return;\n }\n\n const anchorRect = this.anchorElement.getBoundingClientRect();\n const popupRect = floatingElement.getBoundingClientRect();\n const isVertical = this.placement.includes('top') || this.placement.includes('bottom');\n\n let topLeftX = 0;\n let topLeftY = 0;\n let topRightX = 0;\n let topRightY = 0;\n let bottomLeftX = 0;\n let bottomLeftY = 0;\n let bottomRightX = 0;\n let bottomRightY = 0;\n\n if (isVertical) {\n if (anchorRect.top < popupRect.top) {\n topLeftX = anchorRect.left;\n topLeftY = anchorRect.bottom;\n topRightX = anchorRect.right;\n topRightY = anchorRect.bottom;\n bottomLeftX = popupRect.left;\n bottomLeftY = popupRect.top;\n bottomRightX = popupRect.right;\n bottomRightY = popupRect.top;\n } else {\n topLeftX = popupRect.left;\n topLeftY = popupRect.bottom;\n topRightX = popupRect.right;\n topRightY = popupRect.bottom;\n bottomLeftX = anchorRect.left;\n bottomLeftY = anchorRect.top;\n bottomRightX = anchorRect.right;\n bottomRightY = anchorRect.top;\n }\n } else if (anchorRect.left < popupRect.left) {\n topLeftX = anchorRect.right;\n topLeftY = anchorRect.top;\n topRightX = popupRect.left;\n topRightY = popupRect.top;\n bottomLeftX = anchorRect.right;\n bottomLeftY = anchorRect.bottom;\n bottomRightX = popupRect.left;\n bottomRightY = popupRect.bottom;\n } else {\n topLeftX = popupRect.right;\n topLeftY = popupRect.top;\n topRightX = anchorRect.left;\n topRightY = anchorRect.top;\n bottomLeftX = popupRect.right;\n bottomLeftY = popupRect.bottom;\n bottomRightX = anchorRect.left;\n bottomRightY = anchorRect.bottom;\n }\n\n this.style.setProperty('--pk-hover-bridge-top-left-x', `${topLeftX}px`);\n this.style.setProperty('--pk-hover-bridge-top-left-y', `${topLeftY}px`);\n this.style.setProperty('--pk-hover-bridge-top-right-x', `${topRightX}px`);\n this.style.setProperty('--pk-hover-bridge-top-right-y', `${topRightY}px`);\n this.style.setProperty('--pk-hover-bridge-bottom-left-x', `${bottomLeftX}px`);\n this.style.setProperty('--pk-hover-bridge-bottom-left-y', `${bottomLeftY}px`);\n this.style.setProperty('--pk-hover-bridge-bottom-right-x', `${bottomRightX}px`);\n this.style.setProperty('--pk-hover-bridge-bottom-right-y', `${bottomRightY}px`);\n }\n\n override render() {\n const useFixedFallback = !SUPPORTS_POPOVER || this.positionMethod === 'fixed';\n const usePopoverTopLayer = this.usesPopoverTopLayer();\n\n return html`\n <slot name=\"anchor\" @slotchange=${() => { void this.handleAnchorChange(); }}></slot>\n ${this.hoverBridge ? html`\n <div\n part=\"hover-bridge\"\n class=${classMap({\n 'hover-bridge': true,\n 'hover-bridge-visible': this.active,\n })}\n aria-hidden=\"true\"\n ></div>\n ` : nothing}\n <div\n popover=${usePopoverTopLayer ? 'manual' : nothing}\n part=\"popup\"\n class=${classMap({\n popup: true,\n active: this.active,\n 'popup-fixed': useFixedFallback,\n })}\n >\n ${this.arrow ? html`<div part=\"arrow\" class=\"arrow\"></div>` : nothing}\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-popup': PkPopup;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pk-tiptap-editor-De8UUTis.js","names":[],"sources":["../../src/components/tiptap/tiptap-editor-host.ts","../../src/components/tiptap/tiptap-utils.ts","../../src/components/tiptap/tiptap-toolbar.ts","../../src/components/tiptap/pk-tiptap-editor.styles.ts","../../src/components/tiptap/pk-tiptap-editor.ts"],"sourcesContent":["import { Editor, type Extensions } from '@tiptap/core';\nimport {\n createTiptapExtensions,\n normalizeContentArray,\n valueToContent,\n} from '@verbb/plugin-kit-tiptap-core';\n\nexport function serializeTiptapDocumentContent(content: unknown): string {\n return JSON.stringify(normalizeContentArray(content));\n}\n\n/** Normalize React/HTML `value` into the JSON string the editor stores and emits. */\nexport function serializeTiptapDocumentValue(raw: string | unknown[] | null | undefined): string {\n if (raw == null) {\n return '[]';\n }\n\n if (typeof raw === 'string') {\n return raw;\n }\n\n if (Array.isArray(raw)) {\n return JSON.stringify(raw);\n }\n\n return '[]';\n}\n\nexport function parseTiptapDocumentValue(raw: string | unknown[] | null | undefined): unknown[] {\n if (raw == null || raw === '') {\n return [];\n }\n\n // React often passes a document array prop — accept it without JSON.parse.\n if (Array.isArray(raw)) {\n return raw;\n }\n\n if (typeof raw !== 'string') {\n return [];\n }\n\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\nexport type TiptapEditorHostOptions = {\n element: HTMLElement;\n extensions?: Extensions;\n content: unknown;\n editable: boolean;\n trailingCursorText?: string;\n minHeight?: string;\n onUpdate?: (content: unknown[]) => void;\n};\n\nexport class TiptapEditorHost {\n editor: Editor | null = null;\n\n private lastEmitted: string | null = null;\n\n /** Skip TipTap `onUpdate` while applying controlled prop content — otherwise setContent\n * re-emits pk-change → React setValue → value prop → setContent … forever. */\n private suppressUpdateEmission = false;\n\n mount({\n element,\n extensions,\n content,\n editable,\n trailingCursorText = '\\u2060',\n minHeight,\n onUpdate,\n }: TiptapEditorHostOptions): void {\n const doc = valueToContent(content, { trailingCursorText });\n\n this.editor = new Editor({\n element,\n extensions: extensions ?? createTiptapExtensions({ trailingCursorText }),\n content: doc,\n editable,\n onUpdate: ({ editor }) => {\n const normalized = normalizeContentArray(editor.getJSON().content);\n const serialized = JSON.stringify(normalized);\n this.lastEmitted = serialized;\n\n if (this.suppressUpdateEmission) {\n return;\n }\n\n onUpdate?.(normalized);\n },\n });\n\n if (minHeight) {\n this.editor.view.dom.style.minHeight = minHeight;\n }\n }\n\n setContent(content: unknown, options: { trailingCursorText?: string; respectFocus?: boolean } = {}): void {\n if (!this.editor) {\n return;\n }\n\n const { trailingCursorText = '\\u2060', respectFocus = true } = options;\n\n if (respectFocus && this.editor.isFocused) {\n return;\n }\n\n const doc = valueToContent(content, { trailingCursorText });\n const incoming = JSON.stringify(doc?.content ?? []);\n const current = JSON.stringify(this.editor.getJSON().content ?? []);\n\n if (incoming === current || incoming === this.lastEmitted) {\n return;\n }\n\n this.suppressUpdateEmission = true;\n try {\n this.editor.commands.setContent(doc ?? { type: 'doc', content: [] });\n } finally {\n this.suppressUpdateEmission = false;\n }\n }\n\n destroy(): void {\n this.editor?.destroy();\n this.editor = null;\n this.lastEmitted = null;\n this.suppressUpdateEmission = false;\n }\n}\n","import type {\n ElementSelectorHost,\n LinkOptionsInput,\n ToolbarNode,\n} from '@verbb/plugin-kit-tiptap-core';\nimport { parseToolbarConfig } from '@verbb/plugin-kit-tiptap-core';\n\ndeclare global {\n interface Window {\n Craft?: {\n createElementSelectorModal?: ElementSelectorHost['openElementSelector'];\n };\n }\n}\n\nexport function createCraftElementSelectorHost(): ElementSelectorHost {\n return {\n openElementSelector: (elementType, options) => {\n const open = window.Craft?.createElementSelectorModal;\n\n if (!open) {\n throw new Error('Craft element selector is not available in this environment.');\n }\n\n open(elementType, options);\n },\n };\n}\n\nexport function parseLinkOptionsAttribute(raw: string | null): LinkOptionsInput | undefined {\n if (!raw) {\n return undefined;\n }\n\n try {\n return JSON.parse(raw) as LinkOptionsInput;\n } catch {\n return undefined;\n }\n}\n\nexport function parseButtonsAttribute(raw: string | null | undefined): string[] {\n if (!raw) {\n return ['bold', 'italic'];\n }\n\n return raw\n .split(',')\n .map((button) => button.trim())\n .filter(Boolean);\n}\n\nexport function parseToolbarAttribute(\n toolbarRaw: string | ToolbarNode[] | null | undefined,\n buttonsRaw: string | string[] | null | undefined,\n): ToolbarNode[] {\n if (Array.isArray(toolbarRaw)) {\n return parseToolbarConfig(toolbarRaw);\n }\n\n if (typeof toolbarRaw === 'string' && toolbarRaw.trim()) {\n return parseToolbarConfig(toolbarRaw);\n }\n\n if (Array.isArray(buttonsRaw)) {\n return parseToolbarConfig(buttonsRaw.join(','));\n }\n\n return parseToolbarConfig(buttonsRaw ?? 'bold,italic');\n}\n","import {\n alignCenter,\n alignJustify,\n alignLeft,\n alignRight,\n arrowRotateLeft,\n arrowRotateRight,\n bold,\n bracketsCurly,\n chevronDown,\n code,\n fileDashedLine,\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n heading,\n highlighter,\n italic,\n link,\n listOl,\n listUl,\n minus,\n paragraph,\n quoteRight,\n strikethrough,\n subscript,\n superscript,\n table,\n textSlash,\n underline,\n renderIconHtml,\n} from '../../icons/index.js';\n\nexport const TOOLBAR_CHEVRON_HTML = renderIconHtml(chevronDown);\n\nexport const TOOLBAR_ICONS: Record<string, string> = {\n bold: renderIconHtml(bold),\n italic: renderIconHtml(italic),\n underline: renderIconHtml(underline),\n strikethrough: renderIconHtml(strikethrough),\n subscript: renderIconHtml(subscript),\n superscript: renderIconHtml(superscript),\n code: renderIconHtml(bracketsCurly),\n 'code-block': renderIconHtml(code),\n highlight: renderIconHtml(highlighter),\n h1: renderIconHtml(h1),\n h2: renderIconHtml(h2),\n h3: renderIconHtml(h3),\n h4: renderIconHtml(h4),\n h5: renderIconHtml(h5),\n h6: renderIconHtml(h6),\n heading: renderIconHtml(heading),\n paragraph: renderIconHtml(paragraph),\n 'unordered-list': renderIconHtml(listUl),\n 'ordered-list': renderIconHtml(listOl),\n blockquote: renderIconHtml(quoteRight),\n 'align-left': renderIconHtml(alignLeft),\n 'align-center': renderIconHtml(alignCenter),\n 'align-right': renderIconHtml(alignRight),\n 'align-justify': renderIconHtml(alignJustify),\n 'clear-format': renderIconHtml(textSlash),\n hr: renderIconHtml(minus),\n 'line-break': renderIconHtml(fileDashedLine),\n link: renderIconHtml(link),\n table: renderIconHtml(table),\n undo: renderIconHtml(arrowRotateLeft),\n redo: renderIconHtml(arrowRotateRight),\n};\n\nexport const TOOLBAR_LABELS: Record<string, string> = {\n bold: 'Bold',\n italic: 'Italic',\n underline: 'Underline',\n strikethrough: 'Strikethrough',\n subscript: 'Subscript',\n superscript: 'Superscript',\n code: 'Inline code',\n 'code-block': 'Code block',\n highlight: 'Highlight',\n h1: 'Heading 1',\n h2: 'Heading 2',\n h3: 'Heading 3',\n h4: 'Heading 4',\n h5: 'Heading 5',\n h6: 'Heading 6',\n paragraph: 'Paragraph',\n 'unordered-list': 'Bullet list',\n 'ordered-list': 'Numbered list',\n blockquote: 'Blockquote',\n 'align-left': 'Align left',\n 'align-center': 'Align center',\n 'align-right': 'Align right',\n 'align-justify': 'Justify',\n 'clear-format': 'Clear format',\n hr: 'Horizontal rule',\n 'line-break': 'Line break',\n link: 'Link',\n table: 'Table',\n undo: 'Undo',\n redo: 'Redo',\n};\n\nexport function getToolbarMenuItemLabel(buttonName: string): string {\n return TOOLBAR_LABELS[buttonName] ?? buttonName;\n}\n\n/** Prefix icon for `pk-dropdown-item` — SVG must carry `slot=\"prefix\"` directly. */\nexport function createToolbarPrefixIcon(buttonName: string): SVGSVGElement | null {\n const iconHtml = TOOLBAR_ICONS[buttonName];\n\n if (!iconHtml) {\n return null;\n }\n\n const template = document.createElement('template');\n template.innerHTML = iconHtml.trim();\n const icon = template.content.firstElementChild;\n\n if (!(icon instanceof SVGSVGElement)) {\n return null;\n }\n\n icon.setAttribute('slot', 'prefix');\n icon.setAttribute('aria-hidden', 'true');\n icon.setAttribute('width', '12');\n icon.setAttribute('height', '12');\n icon.classList.add('pk-dropdown-item__prefix-icon');\n\n return icon;\n}\n","import { css } from 'lit';\n\nexport const pkTiptapEditorStyles = css`\n @layer pk-component {\n :host {\n display: block;\n width: 100%;\n font-family: var(--pk-font-family);\n }\n\n .shell {\n overflow: hidden;\n border: var(--pk-input-border);\n border-radius: var(--pk-radius-md);\n background: #fff;\n }\n\n :host([invalid]) .shell,\n :host(:state(user-invalid)) .shell {\n border-color: var(--pk-color-rose-600);\n }\n\n .toolbar {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n border-bottom: 1px solid rgba(96, 125, 159, 0.4);\n background: #fff;\n box-shadow: 0 2px 3px rgba(49, 49, 93, 0.07);\n }\n\n .toolbar-item {\n display: inline-flex;\n }\n\n .toolbar-item pk-tooltip {\n display: contents;\n }\n\n .toolbar-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: var(--pk-radius-md);\n background: transparent;\n color: #1c2e36;\n cursor: pointer;\n }\n\n .toolbar-btn:hover:not(:disabled) {\n background: rgb(241, 245, 249);\n }\n\n .toolbar-btn[data-state='active'] {\n background: rgb(226, 232, 240);\n }\n\n .toolbar-btn:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .toolbar-btn svg {\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n }\n\n .toolbar-btn--menu {\n width: auto;\n min-width: 2rem;\n gap: 0.125rem;\n padding: 0 0.375rem;\n }\n\n .toolbar-btn__trigger-label {\n font-size: 0.625rem;\n font-weight: 700;\n line-height: 1;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n\n .toolbar-btn__chevron {\n display: inline-flex;\n flex-shrink: 0;\n opacity: 0.7;\n }\n\n .toolbar-btn__chevron svg {\n width: 0.5rem;\n height: 0.5rem;\n }\n\n .toolbar-separator {\n align-self: center;\n flex-shrink: 0;\n width: 1px;\n height: 1.25rem;\n margin: 0 0.125rem;\n background: rgba(96, 125, 159, 0.35);\n }\n\n .toolbar-btn__label {\n font-size: 0.625rem;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n }\n\n /* Full toolbar replace (slot=toolbar on host when hasCustomToolbar). */\n .toolbar ::slotted([slot='toolbar']) {\n display: contents;\n }\n\n /* Append lane inside the stock toolbar — one flex item per slotted root (same gap). */\n .toolbar ::slotted([slot='toolbar-end']) {\n display: inline-flex;\n align-items: center;\n }\n\n .editor-mount {\n position: relative;\n }\n\n .content-error {\n display: flex;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--pk-color-rose-200);\n background: var(--pk-color-rose-50);\n color: var(--pk-color-rose-800);\n font-size: var(--pk-font-size-sm);\n }\n\n .mirror-input {\n display: none;\n }\n\n /* No trigger slot — collapse the host so it does not reserve shell space.\n Toolbar refresh while open is still gated by linkDialogBusy / open. */\n .link-dialog {\n display: contents;\n }\n\n .link-dialog__fields {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n\n .link-bubble {\n position: absolute;\n z-index: 250;\n display: flex;\n align-items: center;\n gap: 0;\n width: max-content;\n max-width: calc(100% - 1rem);\n padding: 0;\n border: 0;\n border-radius: var(--pk-radius-md);\n background: #1c2e36;\n color: #fff;\n font-size: 12px;\n line-height: 1.5;\n overflow: visible;\n pointer-events: auto;\n white-space: nowrap;\n }\n\n .link-bubble__arrow {\n position: absolute;\n left: 50%;\n bottom: -0.25rem;\n width: 0.5rem;\n height: 0.5rem;\n background: #1c2e36;\n transform: translateX(-50%) rotate(45deg);\n pointer-events: none;\n }\n\n .link-bubble__url,\n .link-bubble__action {\n box-sizing: border-box;\n padding: 6px 8px;\n font-size: 12px;\n line-height: 1.5;\n }\n\n .link-bubble__url {\n display: inline-flex;\n align-items: center;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .link-bubble__divider {\n flex-shrink: 0;\n align-self: center;\n width: 1px;\n height: 12px;\n background: #616d73;\n }\n\n .link-bubble__action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: #fff;\n font-family: inherit;\n font-weight: inherit;\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n appearance: none;\n -webkit-appearance: none;\n min-height: 0;\n transition: color 0.15s ease;\n }\n\n .link-bubble__action:hover {\n color: rgb(255 255 255 / 0.7);\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport {\n applyLinkToEditor,\n createTiptapExtensions,\n getCraftLinkOptions,\n getFatalTiptapContentError,\n getLinkEditState,\n getLinkOptionsElementSiteId,\n getLinkOpenInNewTab,\n getSelectedText,\n getToolbarGroupDefaultIcon,\n getToolbarGroupMenuItems,\n getToolbarGroupTriggerState,\n isFormattingToolbarPreset,\n isHeadingsOnlyToolbarPreset,\n isTiptapButtonActive,\n isToolbarButtonActive,\n openCraftElementLinkSelector,\n runToolbarButton,\n toolbarIncludesButton,\n unsetLinkFromEditor,\n type LinkElementConfig,\n type LinkOptionsInput,\n type ToolbarGroup,\n type ToolbarNode,\n} from '@verbb/plugin-kit-tiptap-core';\nimport { getMarkRange, posToDOMRect } from '@tiptap/core';\n\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { MirrorValidator } from '../../validators/index.js';\nimport {\n link,\n triangleExclamation,\n renderIconHtml,\n} from '../../icons/index.js';\n\nimport '../button/pk-button.js';\nimport '../checkbox/pk-checkbox.js';\nimport '../dialog/pk-dialog.js';\nimport '../dropdown-menu/pk-dropdown-item.js';\nimport '../field/pk-field.js';\nimport '../input/pk-input.js';\nimport '../dropdown-menu/pk-dropdown-menu.js';\nimport '../dropdown-menu/pk-dropdown-separator.js';\nimport '../tooltip/pk-tooltip.js';\nimport type { PkButton } from '../button/pk-button.js';\nimport type { PkCheckbox } from '../checkbox/pk-checkbox.js';\nimport type { PkDialog } from '../dialog/pk-dialog.js';\nimport type { PkDropdownMenu } from '../dropdown-menu/pk-dropdown-menu.js';\nimport type { PkInput } from '../input/pk-input.js';\nimport { TiptapEditorHost, parseTiptapDocumentValue, serializeTiptapDocumentContent, serializeTiptapDocumentValue } from './tiptap-editor-host.js';\nimport { createCraftElementSelectorHost, parseLinkOptionsAttribute, parseToolbarAttribute } from './tiptap-utils.js';\nimport {\n TOOLBAR_CHEVRON_HTML,\n TOOLBAR_ICONS,\n TOOLBAR_LABELS,\n createToolbarPrefixIcon,\n getToolbarMenuItemLabel,\n} from './tiptap-toolbar.js';\nimport { createVariableTagDomNodeView } from './variable-tag-node-view.js';\nimport { pkTiptapEditorStyles } from './pk-tiptap-editor.styles.js';\nimport { tiptapProseMirrorStyles } from './tiptap.styles.js';\n\ntype LinkDialogSeed = {\n url?: string;\n text?: string;\n openInNewTab?: boolean;\n from?: number;\n to?: number;\n};\n\n/**\n * TipTap document editor with a Craft-styled toolbar.\n *\n * @slot toolbar - Replace the entire default toolbar (opt-in via light-DOM presence).\n * @slot toolbar-end - Append controls after stock toolbar buttons (same flex gap).\n */\n@customElement('pk-tiptap-editor')\nexport class PkTiptapEditor extends PkFormAssociatedElement {\n static override styles = [formControlStyles, pkTiptapEditorStyles, tiptapProseMirrorStyles];\n\n static override get validators() {\n return [...super.validators, MirrorValidator()];\n }\n\n override assumeInteractionOn = ['blur', 'input'];\n\n @query('.editor-mount')\n private editorMount!: HTMLDivElement;\n\n @query('.mirror-input')\n override input!: HTMLInputElement;\n\n @query('.link-dialog')\n private linkDialog?: PkDialog;\n\n @query('pk-input.link-dialog__url-input')\n private linkUrlInput?: PkInput;\n\n @query('pk-input.link-dialog__text-input')\n private linkTextInput?: PkInput;\n\n @query('pk-checkbox')\n private linkNewTabCheckbox?: PkCheckbox;\n\n @query('pk-button.link-dialog__submit')\n private linkSubmitButton?: PkButton;\n\n private readonly linkUrlInputId = uniqueId('pk-tiptap-link-url');\n\n private readonly linkTextInputId = uniqueId('pk-tiptap-link-text');\n\n private readonly host = new TiptapEditorHost();\n\n private _value: string | null = null;\n\n /**\n * Flat toolbar button list. HTML uses a comma-separated attribute; React may\n * pass a `string[]`. Named `buttons` (not `buttonsAttr`) so React can set the\n * property — a getter-only `buttons` previously threw on assign.\n */\n @property({\n attribute: 'buttons',\n converter: {\n fromAttribute: (value: string | null) => value ?? 'bold,italic',\n toAttribute: (value: string | string[] | null | undefined) => {\n if (value == null) {\n return 'bold,italic';\n }\n\n return Array.isArray(value) ? value.join(',') : value;\n },\n },\n })\n buttons: string | string[] = 'bold,italic';\n\n /** Structured toolbar config — JSON string attribute, or a node array from React. */\n @property({\n attribute: 'toolbar',\n converter: {\n fromAttribute: (value: string | null) => value,\n toAttribute: (value: string | ToolbarNode[] | null | undefined) => {\n if (value == null) {\n return null;\n }\n\n return typeof value === 'string' ? value : JSON.stringify(value);\n },\n },\n })\n toolbar: string | ToolbarNode[] | null = null;\n\n @property({ attribute: 'link-options' })\n linkOptions: string | null = null;\n\n @property({ attribute: 'link-selector-storage-key-prefix' })\n linkSelectorStorageKeyPrefix?: string;\n\n @property({ type: Number })\n rows = 4;\n\n @property()\n placeholder = '';\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n /**\n * Formie / React configure bridge — called when a chip is activated for editing.\n * Prefer this over listening for `pk-variable-tag-configure` from React.\n */\n @property({ attribute: false })\n variableTagConfigure: ((detail: import('./variable-tag-node-view.js').PkVariableTagConfigureDetail) => void) | null = null;\n\n @property({ attribute: 'invalid-content-message' })\n invalidContentMessage = '';\n\n /** Show `pk-tooltip` hints on toolbar buttons (default: on). */\n @property({ type: Boolean, attribute: 'toolbar-tooltips' })\n toolbarTooltips = true;\n\n private linkDialogBusy = false;\n\n private linkDialogSeed: LinkDialogSeed = {};\n\n @state()\n private linkDialogTitle = 'Insert Link';\n\n @state()\n private linkDialogSubmitLabel = 'Insert';\n\n @state()\n private linkDialogMounted = false;\n\n @state()\n private linkBubbleVisible = false;\n\n @state()\n private linkBubbleHref = '';\n\n @state()\n private linkBubbleTop = 0;\n\n @state()\n private linkBubbleLeft = 0;\n\n private hasCustomToolbar = false;\n\n private readonly linkButtonId = uniqueId('pk-tiptap-link-btn');\n\n private readonly toolbarButtonIds = new Map<string, string>();\n\n private readonly toolbarGroupIds = new Map<string, string>();\n\n private selectionListenerAttached = false;\n\n get value(): string {\n if (this.valueHasChanged) {\n return this._value ?? '[]';\n }\n\n return this._value ?? this.defaultValue ?? '[]';\n }\n\n /**\n * Document JSON string. Also accepts a TipTap node array (common from React)\n * and serializes it — arrays previously bypassed JSON.parse and mounted empty.\n */\n @state()\n set value(val: string | unknown[] | null) {\n const next = serializeTiptapDocumentValue(val);\n\n if (this._value === next) {\n return;\n }\n\n this.valueHasChanged = true;\n this._value = next;\n }\n\n @property({ attribute: 'value', reflect: true })\n defaultValue: string | null = '[]';\n\n get editor() {\n return this.host.editor;\n }\n\n get toolbarNodes(): ToolbarNode[] {\n const buttonsRaw = Array.isArray(this.buttons) ? this.buttons.join(',') : this.buttons;\n\n return parseToolbarAttribute(this.toolbar, buttonsRaw)\n .filter((node) => node.type !== 'button' || node.name !== 'variableTag');\n }\n\n /** Resolved flat button names from the active toolbar config. */\n get buttonNames(): string[] {\n return this.toolbarNodes\n .filter((node): node is Extract<ToolbarNode, { type: 'button' }> => node.type === 'button')\n .map((node) => node.name);\n }\n\n private toolbarHasLink(): boolean {\n return toolbarIncludesButton(this.toolbarNodes, 'link');\n }\n\n private resolveLinkOptions(): LinkOptionsInput | undefined {\n return parseLinkOptionsAttribute(this.linkOptions);\n }\n\n private get contentError(): string {\n return this.resolveContentError();\n }\n\n protected override syncFormValue(): void {\n this.setValue(this.value || '[]');\n\n if (this.input) {\n this.input.value = this.value || '[]';\n }\n }\n\n protected override resetToDefaultValue(): void {\n this.valueHasChanged = false;\n this._value = null;\n this.syncEditorContent();\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.syncEditorContent();\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.hasCustomToolbar = Boolean(this.querySelector('[slot=\"toolbar\"]'));\n }\n\n override disconnectedCallback(): void {\n this.linkDialog?.forceOverlayReset();\n this.linkDialogBusy = false;\n this.host.destroy();\n this.selectionListenerAttached = false;\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('value') && !changed.has('defaultValue')) {\n this.syncEditorContent();\n }\n\n if (changed.has('defaultValue') && !this.valueHasChanged) {\n this.syncEditorContent();\n }\n\n if (changed.has('disabled') || changed.has('readonly')) {\n this.host.editor?.setEditable(!this.disabled && !this.readonly);\n }\n\n super.updated(changed);\n }\n\n override firstUpdated(): void {\n queueMicrotask(() => {\n this.mountEditor();\n this.syncFormValue();\n });\n }\n\n private resolveContentError(): string {\n const detected = getFatalTiptapContentError(this.value);\n return detected ? (this.invalidContentMessage || detected) : '';\n }\n\n private mountEditor(): void {\n const content = this.contentError ? null : parseTiptapDocumentValue(this.value);\n const normalizedRows = Math.max(1, Number(this.rows || 0));\n const minHeight = `${(normalizedRows * 24) + 32}px`;\n\n this.host.mount({\n element: this.editorMount,\n extensions: createTiptapExtensions({\n trailingCursorText: '\\u2060',\n variableTagNodeView: createVariableTagDomNodeView(),\n }),\n content,\n editable: !this.disabled && !this.readonly && !this.contentError,\n trailingCursorText: '\\u2060',\n minHeight,\n onUpdate: (nextContent) => {\n const serialized = serializeTiptapDocumentContent(nextContent);\n this.value = serialized;\n\n if (this.input) {\n this.input.value = serialized;\n }\n\n this.syncFormValue();\n // Emit JSON string (matches `value` prop) — arrays caused Formie controlled\n // fields to write mismatched types and re-enter sync forever.\n this.emitValueChange(serialized);\n },\n });\n\n queueMicrotask(() => {\n this.attachSelectionListeners();\n });\n }\n\n private attachSelectionListeners(): void {\n const editor = this.host.editor;\n\n if (!editor || this.selectionListenerAttached) {\n return;\n }\n\n const refreshToolbar = () => {\n if (this.linkDialogBusy || this.linkDialog?.open) {\n this.linkBubbleVisible = false;\n return;\n }\n\n this.updateLinkBubble();\n\n queueMicrotask(() => {\n if (this.isConnected && !this.linkDialogBusy && !this.linkDialog?.open) {\n this.requestUpdate();\n }\n });\n };\n\n editor.on('selectionUpdate', refreshToolbar);\n editor.on('transaction', refreshToolbar);\n editor.on('focus', refreshToolbar);\n editor.on('blur', () => {\n this.linkBubbleVisible = false;\n this.requestUpdate();\n });\n this.selectionListenerAttached = true;\n }\n\n private updateLinkBubble(): void {\n const editor = this.host.editor;\n\n if (\n !editor\n || this.disabled\n || this.readonly\n || this.linkDialogBusy\n || this.linkDialog?.open\n || !editor.isFocused\n || !editor.isActive('link')\n ) {\n this.linkBubbleVisible = false;\n return;\n }\n\n const linkType = editor.state.schema.marks.link;\n const range = getMarkRange(editor.state.selection.$from, linkType);\n\n if (!range) {\n this.linkBubbleVisible = false;\n return;\n }\n\n const linkRect = posToDOMRect(editor.view, range.from, range.to);\n const mountRect = this.editorMount.getBoundingClientRect();\n const bubbleOffset = 8;\n\n this.linkBubbleHref = String(editor.getAttributes('link').href ?? '');\n this.linkBubbleTop = linkRect.top - mountRect.top - bubbleOffset;\n this.linkBubbleLeft = linkRect.left - mountRect.left + (linkRect.width / 2);\n this.linkBubbleVisible = true;\n }\n\n private handleLinkBubbleEdit = (event: Event): void => {\n event.preventDefault();\n\n const editor = this.host.editor;\n\n if (!editor) {\n return;\n }\n\n const state = getLinkEditState(editor);\n this.linkBubbleVisible = false;\n this.openLinkDialog({\n url: state.href,\n text: state.text,\n openInNewTab: state.openInNewTab,\n from: state.from,\n to: state.to,\n });\n };\n\n private handleLinkBubbleUnlink = (event: Event): void => {\n event.preventDefault();\n\n const editor = this.host.editor;\n\n if (!editor) {\n return;\n }\n\n unsetLinkFromEditor(editor);\n this.linkBubbleVisible = false;\n };\n\n private renderLinkBubble() {\n return html`\n <div\n class=\"link-bubble\"\n role=\"toolbar\"\n aria-label=\"Link actions\"\n tabindex=\"0\"\n style=${`top:${this.linkBubbleTop}px;left:${this.linkBubbleLeft}px;transform:translate(-50%, -100%);`}\n >\n <span class=\"link-bubble__arrow\" aria-hidden=\"true\"></span>\n <span class=\"link-bubble__url\">${this.linkBubbleHref}</span>\n <span class=\"link-bubble__divider\" aria-hidden=\"true\"></span>\n <button\n type=\"button\"\n class=\"link-bubble__action\"\n @mousedown=${(event: Event) => event.preventDefault()}\n @click=${this.handleLinkBubbleEdit}\n >Edit</button>\n <span class=\"link-bubble__divider\" aria-hidden=\"true\"></span>\n <button\n type=\"button\"\n class=\"link-bubble__action\"\n @mousedown=${(event: Event) => event.preventDefault()}\n @click=${this.handleLinkBubbleUnlink}\n >Unlink</button>\n </div>\n `;\n }\n\n private syncEditorContent(): void {\n const content = this.contentError ? null : parseTiptapDocumentValue(this.value);\n this.host.setContent(content, { trailingCursorText: '\\u2060' });\n\n if (this.input) {\n this.input.value = this.value || '[]';\n }\n }\n\n private emitValueChange(value: string): void {\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private handleToolbarCommand(buttonName: string): void {\n const editor = this.host.editor;\n\n if (!editor) {\n return;\n }\n\n runToolbarButton(editor, buttonName);\n }\n\n private openLinkMenu(): void {\n const editor = this.host.editor;\n\n if (!editor) {\n return;\n }\n\n const selected = getSelectedText(editor);\n const { from, to } = editor.state.selection;\n\n const menu = this.shadowRoot?.querySelector<PkDropdownMenu>(\n `pk-dropdown-menu[for=\"${this.linkButtonId}\"]`,\n );\n\n void (async () => {\n await menu?.whenClosed();\n this.openLinkDialog(from !== to ? { text: selected, from, to } : undefined);\n })();\n }\n\n private openLinkDialog(initial?: LinkDialogSeed): void {\n const editor = this.host.editor;\n const url = initial?.url ?? '';\n\n this.linkDialogBusy = true;\n this.linkBubbleVisible = false;\n this.linkDialogSeed = {\n url,\n text: initial?.text ?? '',\n openInNewTab: initial?.openInNewTab ?? (editor ? getLinkOpenInNewTab(editor) : false),\n from: initial?.from,\n to: initial?.to,\n };\n this.linkDialogTitle = url.trim() ? 'Update Link' : 'Insert Link';\n this.linkDialogSubmitLabel = url.trim() ? 'Update' : 'Insert';\n\n if (!this.linkDialogMounted) {\n this.linkDialogMounted = true;\n }\n\n // Mount first, then open after the dropdown has fully demoted (caller awaits\n // whenClosed). Busy flag still suppresses toolbar refresh during show animation.\n queueMicrotask(async () => {\n await this.updateComplete;\n await this.linkDialog?.updateComplete;\n this.syncLinkDialogFields();\n // Prefer show() over flipping `open` before firstUpdated — that path only\n // call showModal() and skips PkShowEvent / enter animation.\n await this.linkDialog?.show();\n });\n }\n\n private closeLinkDialog(): void {\n void this.linkDialog?.hide('close-button');\n }\n\n private handleLinkDialogAfterHide = (): void => {\n this.linkDialogBusy = false;\n\n queueMicrotask(() => {\n if (this.isConnected && !this.linkDialog?.open) {\n this.requestUpdate();\n }\n });\n };\n\n private syncLinkDialogFields(): void {\n const seed = this.linkDialogSeed;\n\n if (this.linkUrlInput) {\n this.linkUrlInput.value = seed.url ?? '';\n }\n\n if (this.linkTextInput) {\n this.linkTextInput.value = seed.text ?? '';\n }\n\n if (this.linkNewTabCheckbox) {\n this.linkNewTabCheckbox.checked = Boolean(seed.openInNewTab);\n }\n\n this.updateLinkDialogSubmitState();\n }\n\n private updateLinkDialogSubmitState(): void {\n const canSubmit = Boolean(this.linkUrlInput?.value.trim());\n\n if (this.linkSubmitButton) {\n this.linkSubmitButton.disabled = !canSubmit;\n }\n }\n\n private handleLinkUrlInput = (): void => {\n this.updateLinkDialogSubmitState();\n };\n\n private handleLinkDialogKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Enter') {\n return;\n }\n\n const path = event.composedPath();\n\n if (path.some((node) => node instanceof HTMLElement && node.localName === 'pk-checkbox')) {\n return;\n }\n\n if (path.some((node) => node instanceof HTMLElement && node.localName === 'pk-button')) {\n return;\n }\n\n if (path.some((node) => node instanceof HTMLButtonElement)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n this.submitLinkDialog();\n };\n\n private handleLinkDialogSubmit = (): void => {\n this.submitLinkDialog();\n };\n\n private submitLinkDialog(): void {\n const editor = this.host.editor;\n const url = this.linkUrlInput?.value.trim() ?? '';\n\n if (!editor || !url) {\n return;\n }\n\n applyLinkToEditor(editor, {\n url,\n text: this.linkTextInput?.value ?? '',\n openInNewTab: Boolean(this.linkNewTabCheckbox?.checked),\n from: this.linkDialogSeed.from,\n to: this.linkDialogSeed.to,\n });\n\n this.closeLinkDialog();\n }\n\n private isLinkActive(): boolean {\n const editor = this.host.editor;\n return editor ? isTiptapButtonActive(editor, 'link') : false;\n }\n\n private renderLinkDialog() {\n return html`\n <pk-dialog\n class=\"link-dialog\"\n size=\"wide\"\n label=${this.linkDialogTitle}\n @pk-after-hide=${this.handleLinkDialogAfterHide}\n @keydown=${this.handleLinkDialogKeyDown}\n >\n <div class=\"link-dialog__fields\">\n <pk-field label=\"URL\" required .for=${this.linkUrlInputId}>\n <pk-input\n id=${this.linkUrlInputId}\n class=\"link-dialog__url-input\"\n type=\"url\"\n placeholder=\"https://\"\n autofocus\n @input=${this.handleLinkUrlInput}\n ></pk-input>\n </pk-field>\n <pk-field label=\"Text\" .for=${this.linkTextInputId}>\n <pk-input\n id=${this.linkTextInputId}\n class=\"link-dialog__text-input\"\n type=\"text\"\n ></pk-input>\n </pk-field>\n <pk-checkbox>Open link in new tab</pk-checkbox>\n </div>\n <pk-button slot=\"footer\" data-dialog-close>Cancel</pk-button>\n <pk-button\n slot=\"footer\"\n class=\"link-dialog__submit\"\n variant=\"primary\"\n disabled\n @click=${this.handleLinkDialogSubmit}\n >\n ${this.linkDialogSubmitLabel}\n </pk-button>\n </pk-dialog>\n `;\n }\n\n private getToolbarButtonId(buttonName: string): string {\n let id = this.toolbarButtonIds.get(buttonName);\n\n if (!id) {\n id = uniqueId(`pk-tiptap-toolbar-${buttonName}`);\n this.toolbarButtonIds.set(buttonName, id);\n }\n\n return id;\n }\n\n private getToolbarButtonLabel(buttonName: string): string {\n return TOOLBAR_LABELS[buttonName] ?? buttonName;\n }\n\n private renderToolbarTooltip(buttonId: string, label: string) {\n if (!this.toolbarTooltips) {\n return nothing;\n }\n\n return html`\n <pk-tooltip for=${buttonId} content=${label} placement=\"top\"></pk-tooltip>\n `;\n }\n\n private renderToolbarButton(buttonName: string) {\n const editor = this.host.editor;\n const icon = TOOLBAR_ICONS[buttonName];\n const label = this.getToolbarButtonLabel(buttonName);\n const buttonId = this.getToolbarButtonId(buttonName);\n const active = editor ? isTiptapButtonActive(editor, buttonName) : false;\n\n return html`\n <div class=\"toolbar-item\">\n <button\n id=${buttonId}\n type=\"button\"\n class=\"toolbar-btn\"\n aria-label=${label}\n ?disabled=${this.disabled || this.readonly}\n data-state=${active ? 'active' : nothing}\n @click=${() => this.handleToolbarCommand(buttonName)}\n >\n ${icon ? unsafeSVG(icon) : html`<span class=\"toolbar-btn__label\">${label}</span>`}\n </button>\n ${this.renderToolbarTooltip(buttonId, label)}\n </div>\n `;\n }\n\n private handleCraftLink(config: LinkElementConfig): void {\n const editor = this.host.editor;\n\n if (!editor) {\n return;\n }\n\n openCraftElementLinkSelector({\n config,\n elementSiteId: getLinkOptionsElementSiteId(this.resolveLinkOptions()),\n linkSelectorStorageKeyPrefix: this.linkSelectorStorageKeyPrefix,\n getSelectedText: () => getSelectedText(editor),\n onSelect: ({ url, text }) => { this.openLinkDialog({ url, text }); },\n host: createCraftElementSelectorHost(),\n });\n }\n\n private getToolbarGroupId(groupKey: string): string {\n let id = this.toolbarGroupIds.get(groupKey);\n\n if (!id) {\n id = uniqueId('pk-tiptap-toolbar-group');\n this.toolbarGroupIds.set(groupKey, id);\n }\n\n return id;\n }\n\n private renderToolbarSeparator() {\n return html`<span class=\"toolbar-separator\" aria-hidden=\"true\"></span>`;\n }\n\n private renderGroupTriggerContent(group: ToolbarGroup, triggerLabel: string, iconName: string) {\n const icon = TOOLBAR_ICONS[iconName];\n const showTextLabel = Boolean(group.label);\n\n if (showTextLabel && triggerLabel) {\n return html`\n <span class=\"toolbar-btn__trigger-label\">${triggerLabel}</span>\n <span class=\"toolbar-btn__chevron\">${unsafeSVG(TOOLBAR_CHEVRON_HTML)}</span>\n `;\n }\n\n return html`\n ${icon ? unsafeSVG(icon) : html`<span class=\"toolbar-btn__trigger-label\">${triggerLabel}</span>`}\n <span class=\"toolbar-btn__chevron\">${unsafeSVG(TOOLBAR_CHEVRON_HTML)}</span>\n `;\n }\n\n private renderToolbarGroup(group: ToolbarGroup, groupKey: string) {\n const editor = this.host.editor;\n const groupId = this.getToolbarGroupId(groupKey);\n const trigger = editor ? getToolbarGroupTriggerState(editor, group) : {\n activeName: null,\n label: group.label ?? '',\n isActive: false,\n icon: group.icon ?? getToolbarGroupDefaultIcon(group),\n };\n const menuItems = getToolbarGroupMenuItems(group);\n const tooltipLabel = group.label\n ?? (isHeadingsOnlyToolbarPreset(group.preset) ? 'Headings'\n : isFormattingToolbarPreset(group.preset) ? 'Formatting'\n : group.preset === 'lists' ? 'Lists'\n : group.preset === 'align' ? 'Alignment'\n : 'More');\n\n return html`\n <div class=\"toolbar-item\">\n <button\n id=${groupId}\n type=\"button\"\n class=\"toolbar-btn toolbar-btn--menu\"\n aria-label=${tooltipLabel}\n aria-haspopup=\"menu\"\n ?disabled=${this.disabled || this.readonly}\n data-state=${trigger.isActive ? 'active' : nothing}\n >\n ${this.renderGroupTriggerContent(group, trigger.label, trigger.icon)}\n </button>\n ${this.renderToolbarTooltip(groupId, tooltipLabel)}\n <pk-dropdown-menu for=${groupId} placement=\"bottom-start\">\n ${menuItems.map((entry, itemIndex) => {\n if (entry.type === 'separator') {\n return html`<pk-dropdown-separator key=${`${groupKey}-sep-${itemIndex}`}></pk-dropdown-separator>`;\n }\n\n const itemName = entry.name;\n const active = editor ? isToolbarButtonActive(editor, itemName) : false;\n const prefixIcon = createToolbarPrefixIcon(itemName);\n const itemLabel = getToolbarMenuItemLabel(itemName);\n\n return html`\n <pk-dropdown-item\n key=${`${groupKey}-${itemName}-${itemIndex}`}\n ?data-active=${active || nothing}\n @click=${() => this.handleToolbarCommand(itemName)}\n >\n ${prefixIcon ?? nothing}\n ${itemLabel}\n </pk-dropdown-item>\n `;\n })}\n </pk-dropdown-menu>\n </div>\n `;\n }\n\n private renderToolbarNode(node: ToolbarNode, index: number) {\n if (node.type === 'separator') {\n return this.renderToolbarSeparator();\n }\n\n if (node.type === 'group') {\n return this.renderToolbarGroup(node.group, `group-${index}`);\n }\n\n if (node.name === 'link') {\n return this.renderLinkToolbarButton();\n }\n\n return this.renderToolbarButton(node.name);\n }\n\n private renderDefaultToolbar() {\n // `toolbar-end` — append custom controls (Formie variable picker, etc.) into the\n // stock toolbar flex/gap. Prefer over replacing the whole bar via slot=\"toolbar\".\n return html`\n <div class=\"toolbar\" part=\"toolbar\">\n ${this.toolbarNodes.map((node, index) => this.renderToolbarNode(node, index))}\n <slot name=\"toolbar-end\"></slot>\n </div>\n `;\n }\n\n private renderLinkToolbarButton() {\n const editor = this.host.editor;\n const craftOptions = getCraftLinkOptions(this.resolveLinkOptions());\n const label = this.getToolbarButtonLabel('link');\n const active = this.isLinkActive();\n\n return html`\n <div class=\"toolbar-item\">\n <button\n id=${this.linkButtonId}\n type=\"button\"\n class=\"toolbar-btn\"\n aria-label=${label}\n aria-haspopup=\"menu\"\n ?disabled=${this.disabled || this.readonly}\n data-state=${active ? 'active' : nothing}\n >\n ${unsafeSVG(TOOLBAR_ICONS.link)}\n </button>\n ${this.renderToolbarTooltip(this.linkButtonId, label)}\n <pk-dropdown-menu for=${this.linkButtonId} placement=\"bottom-start\">\n ${craftOptions.map((option) => html`\n <pk-dropdown-item @click=${() => this.handleCraftLink(option)}>\n ${option.optionTitle}\n </pk-dropdown-item>\n `)}\n ${craftOptions.length > 0 ? html`<pk-dropdown-separator></pk-dropdown-separator>` : nothing}\n <pk-dropdown-item @click=${() => this.openLinkMenu()}>Insert Link</pk-dropdown-item>\n <pk-dropdown-item\n ?disabled=${!active}\n @click=${() => editor && unsetLinkFromEditor(editor)}\n >Unlink</pk-dropdown-item>\n </pk-dropdown-menu>\n </div>\n `;\n }\n\n override render() {\n return html`\n <div class=\"shell\" part=\"shell\">\n ${this.hasCustomToolbar\n ? html`<slot name=\"toolbar\"></slot>`\n : this.renderDefaultToolbar()}\n\n <div class=\"editor-mount\" part=\"editor\">\n ${this.contentError ? html`\n <div class=\"content-error\">\n <span>${unsafeSVG(renderIconHtml(triangleExclamation))}</span>\n <span>${this.contentError}</span>\n </div>\n ` : nothing}\n ${this.toolbarHasLink() && this.linkBubbleVisible ? this.renderLinkBubble() : nothing}\n </div>\n\n <input class=\"mirror-input\" type=\"text\" .value=${this.value} readonly tabindex=\"-1\" aria-hidden=\"true\" />\n ${this.toolbarHasLink() && this.linkDialogMounted ? this.renderLinkDialog() : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-tiptap-editor': PkTiptapEditor;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAOA,SAAgB,+BAA+B,SAA0B;AACrE,QAAO,KAAK,UAAU,sBAAsB,QAAQ,CAAC;;;AAIzD,SAAgB,6BAA6B,KAAoD;AAC7F,KAAI,OAAO,KACP,QAAO;AAGX,KAAI,OAAO,QAAQ,SACf,QAAO;AAGX,KAAI,MAAM,QAAQ,IAAI,CAClB,QAAO,KAAK,UAAU,IAAI;AAG9B,QAAO;;AAGX,SAAgB,yBAAyB,KAAuD;AAC5F,KAAI,OAAO,QAAQ,QAAQ,GACvB,QAAO,EAAE;AAIb,KAAI,MAAM,QAAQ,IAAI,CAClB,QAAO;AAGX,KAAI,OAAO,QAAQ,SACf,QAAO,EAAE;AAGb,KAAI;EACA,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,SAAO,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;SACtC;AACJ,SAAO,EAAE;;;AAcjB,IAAa,mBAAb,MAA8B;;gBACF;qBAEa;gCAIJ;;CAEjC,MAAM,EACF,SACA,YACA,SACA,UACA,qBAAqB,KACrB,WACA,YAC8B;EAC9B,MAAM,MAAM,eAAe,SAAS,EAAE,oBAAoB,CAAC;AAE3D,OAAK,SAAS,IAAI,OAAO;GACrB;GACA,YAAY,cAAc,uBAAuB,EAAE,oBAAoB,CAAC;GACxE,SAAS;GACT;GACA,WAAW,EAAE,aAAa;IACtB,MAAM,aAAa,sBAAsB,OAAO,SAAS,CAAC,QAAQ;IAClE,MAAM,aAAa,KAAK,UAAU,WAAW;AAC7C,SAAK,cAAc;AAEnB,QAAI,KAAK,uBACL;AAGJ,eAAW,WAAW;;GAE7B,CAAC;AAEF,MAAI,UACA,MAAK,OAAO,KAAK,IAAI,MAAM,YAAY;;CAI/C,WAAW,SAAkB,UAAmE,EAAE,EAAQ;AACtG,MAAI,CAAC,KAAK,OACN;EAGJ,MAAM,EAAE,qBAAqB,KAAU,eAAe,SAAS;AAE/D,MAAI,gBAAgB,KAAK,OAAO,UAC5B;EAGJ,MAAM,MAAM,eAAe,SAAS,EAAE,oBAAoB,CAAC;EAC3D,MAAM,WAAW,KAAK,UAAU,KAAK,WAAW,EAAE,CAAC;AAGnD,MAAI,aAFY,KAAK,UAAU,KAAK,OAAO,SAAS,CAAC,WAAW,EAAE,CAEjD,IAAW,aAAa,KAAK,YAC1C;AAGJ,OAAK,yBAAyB;AAC9B,MAAI;AACA,QAAK,OAAO,SAAS,WAAW,OAAO;IAAE,MAAM;IAAO,SAAS,EAAE;IAAE,CAAC;YAC9D;AACN,QAAK,yBAAyB;;;CAItC,UAAgB;AACZ,OAAK,QAAQ,SAAS;AACtB,OAAK,SAAS;AACd,OAAK,cAAc;AACnB,OAAK,yBAAyB;;;;;ACvHtC,SAAgB,iCAAsD;AAClE,QAAO,EACH,sBAAsB,aAAa,YAAY;EAC3C,MAAM,OAAO,OAAO,OAAO;AAE3B,MAAI,CAAC,KACD,OAAM,IAAI,MAAM,+DAA+D;AAGnF,OAAK,aAAa,QAAQ;IAEjC;;AAGL,SAAgB,0BAA0B,KAAkD;AACxF,KAAI,CAAC,IACD;AAGJ,KAAI;AACA,SAAO,KAAK,MAAM,IAAI;SAClB;AACJ;;;AAeR,SAAgB,sBACZ,YACA,YACa;AACb,KAAI,MAAM,QAAQ,WAAW,CACzB,QAAO,mBAAmB,WAAW;AAGzC,KAAI,OAAO,eAAe,YAAY,WAAW,MAAM,CACnD,QAAO,mBAAmB,WAAW;AAGzC,KAAI,MAAM,QAAQ,WAAW,CACzB,QAAO,mBAAmB,WAAW,KAAK,IAAI,CAAC;AAGnD,QAAO,mBAAmB,cAAc,cAAc;;;;AChC1D,IAAa,uBAAuB,eAAe,cAAA,YAAY;AAE/D,IAAa,gBAAwC;CACjD,MAAM,eAAe,cAAA,KAAK;CAC1B,QAAQ,eAAe,cAAA,OAAO;CAC9B,WAAW,eAAe,cAAA,UAAU;CACpC,eAAe,eAAe,cAAA,cAAc;CAC5C,WAAW,eAAe,cAAA,UAAU;CACpC,aAAa,eAAe,cAAA,YAAY;CACxC,MAAM,eAAe,cAAA,cAAc;CACnC,cAAc,eAAe,cAAA,KAAK;CAClC,WAAW,eAAe,cAAA,YAAY;CACtC,IAAI,eAAe,cAAA,GAAG;CACtB,IAAI,eAAe,cAAA,GAAG;CACtB,IAAI,eAAe,cAAA,GAAG;CACtB,IAAI,eAAe,cAAA,GAAG;CACtB,IAAI,eAAe,cAAA,GAAG;CACtB,IAAI,eAAe,cAAA,GAAG;CACtB,SAAS,eAAe,cAAA,QAAQ;CAChC,WAAW,eAAe,cAAA,UAAU;CACpC,kBAAkB,eAAe,cAAA,OAAO;CACxC,gBAAgB,eAAe,cAAA,OAAO;CACtC,YAAY,eAAe,cAAA,WAAW;CACtC,cAAc,eAAe,cAAA,UAAU;CACvC,gBAAgB,eAAe,cAAA,YAAY;CAC3C,eAAe,eAAe,cAAA,WAAW;CACzC,iBAAiB,eAAe,cAAA,aAAa;CAC7C,gBAAgB,eAAe,cAAA,UAAU;CACzC,IAAI,eAAe,cAAA,MAAM;CACzB,cAAc,eAAe,cAAA,eAAe;CAC5C,MAAM,eAAe,cAAA,KAAK;CAC1B,OAAO,eAAe,cAAA,MAAM;CAC5B,MAAM,eAAe,cAAA,gBAAgB;CACrC,MAAM,eAAe,cAAA,iBAAiB;CACzC;AAED,IAAa,iBAAyC;CAClD,MAAM;CACN,QAAQ;CACR,WAAW;CACX,eAAe;CACf,WAAW;CACX,aAAa;CACb,MAAM;CACN,cAAc;CACd,WAAW;CACX,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,WAAW;CACX,kBAAkB;CAClB,gBAAgB;CAChB,YAAY;CACZ,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,gBAAgB;CAChB,IAAI;CACJ,cAAc;CACd,MAAM;CACN,OAAO;CACP,MAAM;CACN,MAAM;CACT;AAED,SAAgB,wBAAwB,YAA4B;AAChE,QAAO,eAAe,eAAe;;;AAIzC,SAAgB,wBAAwB,YAA0C;CAC9E,MAAM,WAAW,cAAc;AAE/B,KAAI,CAAC,SACD,QAAO;CAGX,MAAM,WAAW,SAAS,cAAc,WAAW;AACnD,UAAS,YAAY,SAAS,MAAM;CACpC,MAAM,OAAO,SAAS,QAAQ;AAE9B,KAAI,EAAE,gBAAgB,eAClB,QAAO;AAGX,MAAK,aAAa,QAAQ,SAAS;AACnC,MAAK,aAAa,eAAe,OAAO;AACxC,MAAK,aAAa,SAAS,KAAK;AAChC,MAAK,aAAa,UAAU,KAAK;AACjC,MAAK,UAAU,IAAI,gCAAgC;AAEnD,QAAO;;;;ACjIX,IAAa,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACiFhC,IAAA,iBAAA,MAAM,uBAAuB,wBAAwB;;;6BAOzB,CAAC,QAAQ,QAAQ;wBAuBd,SAAS,qBAAqB;yBAE7B,SAAS,sBAAsB;cAE1C,IAAI,kBAAkB;gBAEd;iBAoBH;iBAgBY;qBAGZ;cAMtB;qBAGO;kBAGH;iBAGD;8BAO4G;+BAG9F;yBAIN;wBAEO;wBAEgB,EAAE;yBAGjB;+BAGM;2BAGJ;2BAGA;wBAGH;uBAGD;wBAGC;0BAEE;sBAEK,SAAS,qBAAqB;0CAE1B,IAAI,KAAqB;yCAE1B,IAAI,KAAqB;mCAExB;sBA2BN;+BAmME,UAAuB;AACnD,SAAM,gBAAgB;GAEtB,MAAM,SAAS,KAAK,KAAK;AAEzB,OAAI,CAAC,OACD;GAGJ,MAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAK,oBAAoB;AACzB,QAAK,eAAe;IAChB,KAAK,MAAM;IACX,MAAM,MAAM;IACZ,cAAc,MAAM;IACpB,MAAM,MAAM;IACZ,IAAI,MAAM;IACb,CAAC;;iCAG4B,UAAuB;AACrD,SAAM,gBAAgB;GAEtB,MAAM,SAAS,KAAK,KAAK;AAEzB,OAAI,CAAC,OACD;AAGJ,uBAAoB,OAAO;AAC3B,QAAK,oBAAoB;;yCAqHmB;AAC5C,QAAK,iBAAiB;AAEtB,wBAAqB;AACjB,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,KACtC,MAAK,eAAe;KAE1B;;kCA6BmC;AACrC,QAAK,6BAA6B;;kCAGH,UAA+B;AAC9D,OAAI,MAAM,QAAQ,QACd;GAGJ,MAAM,OAAO,MAAM,cAAc;AAEjC,OAAI,KAAK,MAAM,SAAS,gBAAgB,eAAe,KAAK,cAAc,cAAc,CACpF;AAGJ,OAAI,KAAK,MAAM,SAAS,gBAAgB,eAAe,KAAK,cAAc,YAAY,CAClF;AAGJ,OAAI,KAAK,MAAM,SAAS,gBAAgB,kBAAkB,CACtD;AAGJ,SAAM,gBAAgB;AACtB,SAAM,iBAAiB;AACvB,QAAK,kBAAkB;;sCAGkB;AACzC,QAAK,kBAAkB;;;;gBA5jBF;GAAC;GAAmB;GAAsB;GAAwB;;CAE3F,WAAoB,aAAa;AAC7B,SAAO,CAAC,GAAG,MAAM,YAAY,iBAAiB,CAAC;;CAyInD,IAAI,QAAgB;AAChB,MAAI,KAAK,gBACL,QAAO,KAAK,UAAU;AAG1B,SAAO,KAAK,UAAU,KAAK,gBAAgB;;;;;;CAO/C,IACI,MAAM,KAAgC;EACtC,MAAM,OAAO,6BAA6B,IAAI;AAE9C,MAAI,KAAK,WAAW,KAChB;AAGJ,OAAK,kBAAkB;AACvB,OAAK,SAAS;;CAMlB,IAAI,SAAS;AACT,SAAO,KAAK,KAAK;;CAGrB,IAAI,eAA8B;EAC9B,MAAM,aAAa,MAAM,QAAQ,KAAK,QAAQ,GAAG,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK;AAE/E,SAAO,sBAAsB,KAAK,SAAS,WAAW,CACjD,QAAQ,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,cAAc;;;CAIhF,IAAI,cAAwB;AACxB,SAAO,KAAK,aACP,QAAQ,SAA2D,KAAK,SAAS,SAAS,CAC1F,KAAK,SAAS,KAAK,KAAK;;CAGjC,iBAAkC;AAC9B,SAAO,sBAAsB,KAAK,cAAc,OAAO;;CAG3D,qBAA2D;AACvD,SAAO,0BAA0B,KAAK,YAAY;;CAGtD,IAAY,eAAuB;AAC/B,SAAO,KAAK,qBAAqB;;CAGrC,gBAAyC;AACrC,OAAK,SAAS,KAAK,SAAS,KAAK;AAEjC,MAAI,KAAK,MACL,MAAK,MAAM,QAAQ,KAAK,SAAS;;CAIzC,sBAA+C;AAC3C,OAAK,kBAAkB;AACvB,OAAK,SAAS;AACd,OAAK,mBAAmB;;CAG5B,iBAAoC,OAA8C;AAC9E,MAAI,OAAO,UAAU,UAAU;AAC3B,QAAK,QAAQ;AACb,QAAK,mBAAmB;;;CAIhC,oBAAmC;AAC/B,QAAM,mBAAmB;AACzB,OAAK,mBAAmB,QAAQ,KAAK,cAAc,qBAAmB,CAAC;;CAG3E,uBAAsC;AAClC,OAAK,YAAY,mBAAmB;AACpC,OAAK,iBAAiB;AACtB,OAAK,KAAK,SAAS;AACnB,OAAK,4BAA4B;AACjC,QAAM,sBAAsB;;CAGhC,QAAiB,SAA+B;AAC5C,MAAI,QAAQ,IAAI,QAAQ,IAAI,CAAC,QAAQ,IAAI,eAAe,CACpD,MAAK,mBAAmB;AAG5B,MAAI,QAAQ,IAAI,eAAe,IAAI,CAAC,KAAK,gBACrC,MAAK,mBAAmB;AAG5B,MAAI,QAAQ,IAAI,WAAW,IAAI,QAAQ,IAAI,WAAW,CAClD,MAAK,KAAK,QAAQ,YAAY,CAAC,KAAK,YAAY,CAAC,KAAK,SAAS;AAGnE,QAAM,QAAQ,QAAQ;;CAG1B,eAA8B;AAC1B,uBAAqB;AACjB,QAAK,aAAa;AAClB,QAAK,eAAe;IACtB;;CAGN,sBAAsC;EAClC,MAAM,WAAW,2BAA2B,KAAK,MAAM;AACvD,SAAO,WAAY,KAAK,yBAAyB,WAAY;;CAGjE,cAA4B;EACxB,MAAM,UAAU,KAAK,eAAe,OAAO,yBAAyB,KAAK,MAAM;EAE/E,MAAM,YAAY,GADK,KAAK,IAAI,GAAG,OAAO,KAAK,QAAQ,EAAE,CACnC,GAAiB,KAAM,GAAG;AAEhD,OAAK,KAAK,MAAM;GACZ,SAAS,KAAK;GACd,YAAY,uBAAuB;IAC/B,oBAAoB;IACpB,qBAAqB,8BAA8B;IACtD,CAAC;GACF;GACA,UAAU,CAAC,KAAK,YAAY,CAAC,KAAK,YAAY,CAAC,KAAK;GACpD,oBAAoB;GACpB;GACA,WAAW,gBAAgB;IACvB,MAAM,aAAa,+BAA+B,YAAY;AAC9D,SAAK,QAAQ;AAEb,QAAI,KAAK,MACL,MAAK,MAAM,QAAQ;AAGvB,SAAK,eAAe;AAGpB,SAAK,gBAAgB,WAAW;;GAEvC,CAAC;AAEF,uBAAqB;AACjB,QAAK,0BAA0B;IACjC;;CAGN,2BAAyC;EACrC,MAAM,SAAS,KAAK,KAAK;AAEzB,MAAI,CAAC,UAAU,KAAK,0BAChB;EAGJ,MAAM,uBAAuB;AACzB,OAAI,KAAK,kBAAkB,KAAK,YAAY,MAAM;AAC9C,SAAK,oBAAoB;AACzB;;AAGJ,QAAK,kBAAkB;AAEvB,wBAAqB;AACjB,QAAI,KAAK,eAAe,CAAC,KAAK,kBAAkB,CAAC,KAAK,YAAY,KAC9D,MAAK,eAAe;KAE1B;;AAGN,SAAO,GAAG,mBAAmB,eAAe;AAC5C,SAAO,GAAG,eAAe,eAAe;AACxC,SAAO,GAAG,SAAS,eAAe;AAClC,SAAO,GAAG,cAAc;AACpB,QAAK,oBAAoB;AACzB,QAAK,eAAe;IACtB;AACF,OAAK,4BAA4B;;CAGrC,mBAAiC;EAC7B,MAAM,SAAS,KAAK,KAAK;AAEzB,MACI,CAAC,UACE,KAAK,YACL,KAAK,YACL,KAAK,kBACL,KAAK,YAAY,QACjB,CAAC,OAAO,aACR,CAAC,OAAO,SAAS,OAAO,EAC7B;AACE,QAAK,oBAAoB;AACzB;;EAGJ,MAAM,WAAW,OAAO,MAAM,OAAO,MAAM;EAC3C,MAAM,QAAQ,aAAa,OAAO,MAAM,UAAU,OAAO,SAAS;AAElE,MAAI,CAAC,OAAO;AACR,QAAK,oBAAoB;AACzB;;EAGJ,MAAM,WAAW,aAAa,OAAO,MAAM,MAAM,MAAM,MAAM,GAAG;EAChE,MAAM,YAAY,KAAK,YAAY,uBAAuB;EAC1D,MAAM,eAAe;AAErB,OAAK,iBAAiB,OAAO,OAAO,cAAc,OAAO,CAAC,QAAQ,GAAG;AACrE,OAAK,gBAAgB,SAAS,MAAM,UAAU,MAAM;AACpD,OAAK,iBAAiB,SAAS,OAAO,UAAU,OAAQ,SAAS,QAAQ;AACzE,OAAK,oBAAoB;;CAoC7B,mBAA2B;AACvB,SAAO,IAAI;;;;;;wBAMK,OAAO,KAAK,cAAc,UAAU,KAAK,eAAe,sCAAsC;;;iDAGrE,KAAK,eAAe;;;;;kCAKnC,UAAiB,MAAM,gBAAgB,CAAC;6BAC7C,KAAK,qBAAqB;;;;;;kCAMrB,UAAiB,MAAM,gBAAgB,CAAC;6BAC7C,KAAK,uBAAuB;;;;;CAMrD,oBAAkC;EAC9B,MAAM,UAAU,KAAK,eAAe,OAAO,yBAAyB,KAAK,MAAM;AAC/E,OAAK,KAAK,WAAW,SAAS,EAAE,oBAAoB,KAAU,CAAC;AAE/D,MAAI,KAAK,MACL,MAAK,MAAM,QAAQ,KAAK,SAAS;;CAIzC,gBAAwB,OAAqB;AACzC,OAAK,cAAc,IAAI,YAAY,aAAa;GAC5C,QAAQ,EAAE,OAAO;GACjB,SAAS;GACT,UAAU;GACb,CAAC,CAAC;AACH,OAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;GAAM,CAAC,CAAC;AACzE,OAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;GAAM,CAAC,CAAC;;CAG9E,qBAA6B,YAA0B;EACnD,MAAM,SAAS,KAAK,KAAK;AAEzB,MAAI,CAAC,OACD;AAGJ,mBAAiB,QAAQ,WAAW;;CAGxC,eAA6B;EACzB,MAAM,SAAS,KAAK,KAAK;AAEzB,MAAI,CAAC,OACD;EAGJ,MAAM,WAAW,gBAAgB,OAAO;EACxC,MAAM,EAAE,MAAM,OAAO,OAAO,MAAM;EAElC,MAAM,OAAO,KAAK,YAAY,cAC1B,yBAAyB,KAAK,aAAa,IAC9C;AAED,GAAM,YAAY;AACd,SAAM,MAAM,YAAY;AACxB,QAAK,eAAe,SAAS,KAAK;IAAE,MAAM;IAAU;IAAM;IAAI,GAAG,KAAA,EAAU;MAC3E;;CAGR,eAAuB,SAAgC;EACnD,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,MAAM,SAAS,OAAO;AAE5B,OAAK,iBAAiB;AACtB,OAAK,oBAAoB;AACzB,OAAK,iBAAiB;GAClB;GACA,MAAM,SAAS,QAAQ;GACvB,cAAc,SAAS,iBAAiB,SAAS,oBAAoB,OAAO,GAAG;GAC/E,MAAM,SAAS;GACf,IAAI,SAAS;GAChB;AACD,OAAK,kBAAkB,IAAI,MAAM,GAAG,gBAAgB;AACpD,OAAK,wBAAwB,IAAI,MAAM,GAAG,WAAW;AAErD,MAAI,CAAC,KAAK,kBACN,MAAK,oBAAoB;AAK7B,iBAAe,YAAY;AACvB,SAAM,KAAK;AACX,SAAM,KAAK,YAAY;AACvB,QAAK,sBAAsB;AAG3B,SAAM,KAAK,YAAY,MAAM;IAC/B;;CAGN,kBAAgC;AACvB,OAAK,YAAY,KAAK,eAAe;;CAa9C,uBAAqC;EACjC,MAAM,OAAO,KAAK;AAElB,MAAI,KAAK,aACL,MAAK,aAAa,QAAQ,KAAK,OAAO;AAG1C,MAAI,KAAK,cACL,MAAK,cAAc,QAAQ,KAAK,QAAQ;AAG5C,MAAI,KAAK,mBACL,MAAK,mBAAmB,UAAU,QAAQ,KAAK,aAAa;AAGhE,OAAK,6BAA6B;;CAGtC,8BAA4C;EACxC,MAAM,YAAY,QAAQ,KAAK,cAAc,MAAM,MAAM,CAAC;AAE1D,MAAI,KAAK,iBACL,MAAK,iBAAiB,WAAW,CAAC;;CAoC1C,mBAAiC;EAC7B,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,MAAM,KAAK,cAAc,MAAM,MAAM,IAAI;AAE/C,MAAI,CAAC,UAAU,CAAC,IACZ;AAGJ,oBAAkB,QAAQ;GACtB;GACA,MAAM,KAAK,eAAe,SAAS;GACnC,cAAc,QAAQ,KAAK,oBAAoB,QAAQ;GACvD,MAAM,KAAK,eAAe;GAC1B,IAAI,KAAK,eAAe;GAC3B,CAAC;AAEF,OAAK,iBAAiB;;CAG1B,eAAgC;EAC5B,MAAM,SAAS,KAAK,KAAK;AACzB,SAAO,SAAS,qBAAqB,QAAQ,OAAO,GAAG;;CAG3D,mBAA2B;AACvB,SAAO,IAAI;;;;wBAIK,KAAK,gBAAgB;iCACZ,KAAK,0BAA0B;2BACrC,KAAK,wBAAwB;;;0DAGE,KAAK,eAAe;;iCAE7C,KAAK,eAAe;;;;;qCAKhB,KAAK,mBAAmB;;;kDAGX,KAAK,gBAAgB;;iCAEtC,KAAK,gBAAgB;;;;;;;;;;;;;6BAazB,KAAK,uBAAuB;;sBAEnC,KAAK,sBAAsB;;;;;CAM7C,mBAA2B,YAA4B;EACnD,IAAI,KAAK,KAAK,iBAAiB,IAAI,WAAW;AAE9C,MAAI,CAAC,IAAI;AACL,QAAK,SAAS,qBAAqB,aAAa;AAChD,QAAK,iBAAiB,IAAI,YAAY,GAAG;;AAG7C,SAAO;;CAGX,sBAA8B,YAA4B;AACtD,SAAO,eAAe,eAAe;;CAGzC,qBAA6B,UAAkB,OAAe;AAC1D,MAAI,CAAC,KAAK,gBACN,QAAO;AAGX,SAAO,IAAI;8BACW,SAAS,WAAW,MAAM;;;CAIpD,oBAA4B,YAAoB;EAC5C,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,OAAO,cAAc;EAC3B,MAAM,QAAQ,KAAK,sBAAsB,WAAW;EACpD,MAAM,WAAW,KAAK,mBAAmB,WAAW;EACpD,MAAM,SAAS,SAAS,qBAAqB,QAAQ,WAAW,GAAG;AAEnE,SAAO,IAAI;;;yBAGM,SAAS;;;iCAGD,MAAM;gCACP,KAAK,YAAY,KAAK,SAAS;iCAC9B,SAAS,WAAW,QAAQ;mCAC1B,KAAK,qBAAqB,WAAW,CAAC;;sBAEnD,OAAO,UAAU,KAAK,GAAG,IAAI,oCAAoC,MAAM,SAAS;;kBAEpF,KAAK,qBAAqB,UAAU,MAAM,CAAC;;;;CAKzD,gBAAwB,QAAiC;EACrD,MAAM,SAAS,KAAK,KAAK;AAEzB,MAAI,CAAC,OACD;AAGJ,+BAA6B;GACzB;GACA,eAAe,4BAA4B,KAAK,oBAAoB,CAAC;GACrE,8BAA8B,KAAK;GACnC,uBAAuB,gBAAgB,OAAO;GAC9C,WAAW,EAAE,KAAK,WAAW;AAAE,SAAK,eAAe;KAAE;KAAK;KAAM,CAAC;;GACjE,MAAM,gCAAgC;GACzC,CAAC;;CAGN,kBAA0B,UAA0B;EAChD,IAAI,KAAK,KAAK,gBAAgB,IAAI,SAAS;AAE3C,MAAI,CAAC,IAAI;AACL,QAAK,SAAS,0BAA0B;AACxC,QAAK,gBAAgB,IAAI,UAAU,GAAG;;AAG1C,SAAO;;CAGX,yBAAiC;AAC7B,SAAO,IAAI;;CAGf,0BAAkC,OAAqB,cAAsB,UAAkB;EAC3F,MAAM,OAAO,cAAc;AAG3B,MAFsB,QAAQ,MAAM,MAEhC,IAAiB,aACjB,QAAO,IAAI;2DACoC,aAAa;qDACnB,UAAU,qBAAqB,CAAC;;AAI7E,SAAO,IAAI;cACL,OAAO,UAAU,KAAK,GAAG,IAAI,4CAA4C,aAAa,SAAS;iDAC5D,UAAU,qBAAqB,CAAC;;;CAI7E,mBAA2B,OAAqB,UAAkB;EAC9D,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,UAAU,KAAK,kBAAkB,SAAS;EAChD,MAAM,UAAU,SAAS,4BAA4B,QAAQ,MAAM,GAAG;GAClE,YAAY;GACZ,OAAO,MAAM,SAAS;GACtB,UAAU;GACV,MAAM,MAAM,QAAQ,2BAA2B,MAAM;GACxD;EACD,MAAM,YAAY,yBAAyB,MAAM;EACjD,MAAM,eAAe,MAAM,UACnB,4BAA4B,MAAM,OAAO,GAAG,aAC1C,0BAA0B,MAAM,OAAO,GAAG,eACtC,MAAM,WAAW,UAAU,UACvB,MAAM,WAAW,UAAU,cACvB;AAEtB,SAAO,IAAI;;;yBAGM,QAAQ;;;iCAGA,aAAa;;gCAEd,KAAK,YAAY,KAAK,SAAS;iCAC9B,QAAQ,WAAW,WAAW,QAAQ;;sBAEjD,KAAK,0BAA0B,OAAO,QAAQ,OAAO,QAAQ,KAAK,CAAC;;kBAEvE,KAAK,qBAAqB,SAAS,aAAa,CAAC;wCAC3B,QAAQ;sBAC1B,UAAU,KAAK,OAAO,cAAc;AAClC,OAAI,MAAM,SAAS,YACf,QAAO,IAAI,8BAA8B,GAAG,SAAS,OAAO,YAAY;GAG5E,MAAM,WAAW,MAAM;GACvB,MAAM,SAAS,SAAS,sBAAsB,QAAQ,SAAS,GAAG;GAClE,MAAM,aAAa,wBAAwB,SAAS;GACpD,MAAM,YAAY,wBAAwB,SAAS;AAEnD,UAAO,IAAI;;sCAEG,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY;+CAC9B,UAAU,QAAQ;+CAClB,KAAK,qBAAqB,SAAS,CAAC;;kCAEjD,cAAc,QAAQ;kCACtB,UAAU;;;IAGtB,CAAC;;;;;CAMnB,kBAA0B,MAAmB,OAAe;AACxD,MAAI,KAAK,SAAS,YACd,QAAO,KAAK,wBAAwB;AAGxC,MAAI,KAAK,SAAS,QACd,QAAO,KAAK,mBAAmB,KAAK,OAAO,SAAS,QAAQ;AAGhE,MAAI,KAAK,SAAS,OACd,QAAO,KAAK,yBAAyB;AAGzC,SAAO,KAAK,oBAAoB,KAAK,KAAK;;CAG9C,uBAA+B;AAG3B,SAAO,IAAI;;kBAED,KAAK,aAAa,KAAK,MAAM,UAAU,KAAK,kBAAkB,MAAM,MAAM,CAAC,CAAC;;;;;CAM1F,0BAAkC;EAC9B,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,eAAe,oBAAoB,KAAK,oBAAoB,CAAC;EACnE,MAAM,QAAQ,KAAK,sBAAsB,OAAO;EAChD,MAAM,SAAS,KAAK,cAAc;AAElC,SAAO,IAAI;;;yBAGM,KAAK,aAAa;;;iCAGV,MAAM;;gCAEP,KAAK,YAAY,KAAK,SAAS;iCAC9B,SAAS,WAAW,QAAQ;;sBAEvC,UAAU,cAAc,KAAK,CAAC;;kBAElC,KAAK,qBAAqB,KAAK,cAAc,MAAM,CAAC;wCAC9B,KAAK,aAAa;sBACpC,aAAa,KAAK,WAAW,IAAI;yDACE,KAAK,gBAAgB,OAAO,CAAC;8BACxD,OAAO,YAAY;;sBAE3B,CAAC;sBACD,aAAa,SAAS,IAAI,IAAI,oDAAoD,QAAQ;qDAC3D,KAAK,cAAc,CAAC;;oCAErC,CAAC,OAAO;uCACL,UAAU,oBAAoB,OAAO,CAAC;;;;;;CAOzE,SAAkB;AACd,SAAO,IAAI;;kBAED,KAAK,mBACD,IAAI,iCACJ,KAAK,sBAAsB,CAAC;;;sBAG5B,KAAK,eAAe,IAAI;;oCAEV,UAAU,eAAe,cAAA,oBAAoB,CAAC,CAAC;oCAC/C,KAAK,aAAa;;wBAE9B,QAAQ;sBACV,KAAK,gBAAgB,IAAI,KAAK,oBAAoB,KAAK,kBAAkB,GAAG,QAAQ;;;iEAGzC,KAAK,MAAM;kBAC1D,KAAK,gBAAgB,IAAI,KAAK,oBAAoB,KAAK,kBAAkB,GAAG,QAAQ;;;;;YAz2BjG,MAAM,gBAAgB,CAAA,EAAA,eAAA,WAAA,eAAA,KAAA,EAAA;YAGtB,MAAM,gBAAgB,CAAA,EAAA,eAAA,WAAA,SAAA,KAAA,EAAA;YAGtB,MAAM,eAAe,CAAA,EAAA,eAAA,WAAA,cAAA,KAAA,EAAA;YAGrB,MAAM,kCAAkC,CAAA,EAAA,eAAA,WAAA,gBAAA,KAAA,EAAA;YAGxC,MAAM,mCAAmC,CAAA,EAAA,eAAA,WAAA,iBAAA,KAAA,EAAA;YAGzC,MAAM,cAAc,CAAA,EAAA,eAAA,WAAA,sBAAA,KAAA,EAAA;YAGpB,MAAM,gCAAgC,CAAA,EAAA,eAAA,WAAA,oBAAA,KAAA,EAAA;YAgBtC,SAAS;CACN,WAAW;CACX,WAAW;EACP,gBAAgB,UAAyB,SAAS;EAClD,cAAc,UAAgD;AAC1D,OAAI,SAAS,KACT,QAAO;AAGX,UAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG;;EAEvD;CACJ,CAAC,CAAA,EAAA,eAAA,WAAA,WAAA,KAAA,EAAA;YAID,SAAS;CACN,WAAW;CACX,WAAW;EACP,gBAAgB,UAAyB;EACzC,cAAc,UAAqD;AAC/D,OAAI,SAAS,KACT,QAAO;AAGX,UAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,MAAM;;EAEvE;CACJ,CAAC,CAAA,EAAA,eAAA,WAAA,WAAA,KAAA,EAAA;YAGD,SAAS,EAAE,WAAW,gBAAgB,CAAC,CAAA,EAAA,eAAA,WAAA,eAAA,KAAA,EAAA;YAGvC,SAAS,EAAE,WAAW,oCAAoC,CAAC,CAAA,EAAA,eAAA,WAAA,gCAAA,KAAA,EAAA;YAG3D,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,eAAA,WAAA,QAAA,KAAA,EAAA;YAG1B,UAAU,CAAA,EAAA,eAAA,WAAA,eAAA,KAAA,EAAA;YAGV,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,eAAA,WAAA,YAAA,KAAA,EAAA;YAG1C,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,eAAA,WAAA,WAAA,KAAA,EAAA;YAO1C,SAAS,EAAE,WAAW,OAAO,CAAC,CAAA,EAAA,eAAA,WAAA,wBAAA,KAAA,EAAA;YAG9B,SAAS,EAAE,WAAW,2BAA2B,CAAC,CAAA,EAAA,eAAA,WAAA,yBAAA,KAAA,EAAA;YAIlD,SAAS;CAAE,MAAM;CAAS,WAAW;CAAoB,CAAC,CAAA,EAAA,eAAA,WAAA,mBAAA,KAAA,EAAA;YAO1D,OAAO,CAAA,EAAA,eAAA,WAAA,mBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,yBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,qBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,qBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,kBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,iBAAA,KAAA,EAAA;YAGP,OAAO,CAAA,EAAA,eAAA,WAAA,kBAAA,KAAA,EAAA;YAyBP,OAAO,CAAA,EAAA,eAAA,WAAA,SAAA,KAAA;YAYP,SAAS;CAAE,WAAW;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,eAAA,WAAA,gBAAA,KAAA,EAAA;6BAtKnD,cAAc,mBAAmB,CAAA,EAAA,eAAA"}